diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs
index 36beb99c4..cfddb17b9 100644
--- a/crypto/src/AssemblyInfo.cs
+++ b/crypto/src/AssemblyInfo.cs
@@ -1,9 +1,13 @@
using System;
using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
//using System.Security.Permissions;
+#if PORTABLE
+using System.Linq;
+#else
+using System.Runtime.InteropServices;
+#endif
+
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -76,3 +80,35 @@ using System.Runtime.InteropServices;
// see Org.BouncyCastle.Crypto.Encodings.Pkcs1Encoding.StrictLengthEnabledProperty
//[assembly: EnvironmentPermission(SecurityAction.RequestOptional, Read="Org.BouncyCastle.Pkcs1.Strict")]
+internal class AssemblyInfo
+{
+ private static string version;
+ public static string Version
+ {
+ get
+ {
+ if (version == null)
+ {
+#if PORTABLE
+#if NEW_REFLECTION
+ var ver = (AssemblyVersionAttribute)typeof(AssemblyInfo).GetTypeInfo().Assembly.GetCustomAttributes(typeof(AssemblyVersionAttribute)).FirstOrDefault();
+#else
+ var ver = (AssemblyVersionAttribute)typeof(AssemblyInfo).Assembly.GetCustomAttributes(typeof(AssemblyVersionAttribute), false).FirstOrDefault();
+#endif
+ if (ver != null)
+ {
+ version = ver.Version;
+ }
+#else
+ version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+#endif
+
+ // if we're still here, then don't try again
+ if (version == null)
+ version = string.Empty;
+ }
+
+ return version;
+ }
+ }
+}
diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs
index cf039d7fe..18f8020f2 100644
--- a/crypto/src/asn1/Asn1Set.cs
+++ b/crypto/src/asn1/Asn1Set.cs
@@ -2,6 +2,11 @@ using System;
using System.Collections;
using System.IO;
+#if PORTABLE
+using System.Collections.Generic;
+using System.Linq;
+#endif
+
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
@@ -283,6 +288,18 @@ namespace Org.BouncyCastle.Asn1
if (_set.Count < 2)
return;
+#if PORTABLE
+ var sorted = _set.Cast<Asn1Encodable>()
+ .Select(a => new { Item = a, Key = a.GetEncoded(Asn1Encodable.Der) })
+ .OrderBy(t => t.Key, new DerComparer())
+ .Select(t => t.Item)
+ .ToList();
+
+ for (int i = 0; i < _set.Count; ++i)
+ {
+ _set[i] = sorted[i];
+ }
+#else
Asn1Encodable[] items = new Asn1Encodable[_set.Count];
byte[][] keys = new byte[_set.Count][];
@@ -299,6 +316,7 @@ namespace Org.BouncyCastle.Asn1
{
_set[i] = items[i];
}
+#endif
}
protected internal void AddObject(Asn1Encodable obj)
@@ -311,12 +329,21 @@ namespace Org.BouncyCastle.Asn1
return CollectionUtilities.ToString(_set);
}
+#if PORTABLE
+ private class DerComparer
+ : IComparer<byte[]>
+ {
+ public int Compare(byte[] x, byte[] y)
+ {
+ byte[] a = x, b = y;
+#else
private class DerComparer
- : IComparer
+ : IComparer
{
public int Compare(object x, object y)
{
byte[] a = (byte[])x, b = (byte[])y;
+#endif
int len = System.Math.Min(a.Length, b.Length);
for (int i = 0; i != len; ++i)
{
diff --git a/crypto/src/bcpg/ArmoredOutputStream.cs b/crypto/src/bcpg/ArmoredOutputStream.cs
index fb1f6eb29..253c5d1fe 100644
--- a/crypto/src/bcpg/ArmoredOutputStream.cs
+++ b/crypto/src/bcpg/ArmoredOutputStream.cs
@@ -101,16 +101,7 @@ namespace Org.BouncyCastle.Bcpg
private static readonly string footerStart = "-----END PGP ";
private static readonly string footerTail = "-----";
- private static readonly string version = "BCPG C# v"
-#if PORTABLE
- + Assembly.GetExecutingAssembly()
- .GetCustomAttributes(typeof(AssemblyVersionAttribute), true)
- .Cast<AssemblyVersionAttribute>()
- .First()
- .Version;
-#else
- + Assembly.GetExecutingAssembly().GetName().Version;
-#endif
+ private static readonly string version = "BCPG C# v" + AssemblyInfo.Version;
private readonly IDictionary headers;
diff --git a/crypto/src/crypto/prng/ThreadedSeedGenerator.cs b/crypto/src/crypto/prng/ThreadedSeedGenerator.cs
index f6a6b3c54..0a38e5f5a 100644
--- a/crypto/src/crypto/prng/ThreadedSeedGenerator.cs
+++ b/crypto/src/crypto/prng/ThreadedSeedGenerator.cs
@@ -1,39 +1,43 @@
using System;
using System.Threading;
+#if NO_THREADS
+using System.Threading.Tasks;
+#endif
+
namespace Org.BouncyCastle.Crypto.Prng
{
- /**
- * A thread based seed generator - one source of randomness.
- * <p>
- * Based on an idea from Marcus Lippert.
- * </p>
- */
- public class ThreadedSeedGenerator
- {
- private class SeedGenerator
- {
+ /**
+ * A thread based seed generator - one source of randomness.
+ * <p>
+ * Based on an idea from Marcus Lippert.
+ * </p>
+ */
+ public class ThreadedSeedGenerator
+ {
+ private class SeedGenerator
+ {
#if NETCF_1_0
// No volatile keyword, but all fields implicitly volatile anyway
private int counter = 0;
private bool stop = false;
#else
- private volatile int counter = 0;
- private volatile bool stop = false;
+ private volatile int counter = 0;
+ private volatile bool stop = false;
#endif
- private void Run(object ignored)
- {
- while (!this.stop)
- {
- this.counter++;
- }
- }
+ private void Run(object ignored)
+ {
+ while (!this.stop)
+ {
+ this.counter++;
+ }
+ }
- public byte[] GenerateSeed(
- int numBytes,
- bool fast)
- {
+ public byte[] GenerateSeed(
+ int numBytes,
+ bool fast)
+ {
#if SILVERLIGHT || PORTABLE
return DoGenerateSeed(numBytes, fast);
#else
@@ -51,71 +55,75 @@ namespace Org.BouncyCastle.Crypto.Prng
}
private byte[] DoGenerateSeed(
- int numBytes,
- bool fast)
+ int numBytes,
+ bool fast)
{
this.counter = 0;
- this.stop = false;
+ this.stop = false;
- byte[] result = new byte[numBytes];
- int last = 0;
- int end = fast ? numBytes : numBytes * 8;
+ byte[] result = new byte[numBytes];
+ int last = 0;
+ int end = fast ? numBytes : numBytes * 8;
- ThreadPool.QueueUserWorkItem(new WaitCallback(Run));
+#if NO_THREADS
+ Task.Factory.StartNew(() => Run(null), TaskCreationOptions.None);
+#else
+ ThreadPool.QueueUserWorkItem(new WaitCallback(Run));
+#endif
- for (int i = 0; i < end; i++)
- {
- while (this.counter == last)
- {
- try
- {
+ for (int i = 0; i < end; i++)
+ {
+ while (this.counter == last)
+ {
+ try
+ {
#if PORTABLE
new AutoResetEvent(false).WaitOne(1);
#else
- Thread.Sleep(1);
+ Thread.Sleep(1);
#endif
- }
- catch (Exception)
- {
- // ignore
- }
- }
+ }
+ catch (Exception)
+ {
+ // ignore
+ }
+ }
- last = this.counter;
+ last = this.counter;
- if (fast)
- {
- result[i] = (byte) last;
- }
- else
- {
- int bytepos = i / 8;
- result[bytepos] = (byte) ((result[bytepos] << 1) | (last & 1));
- }
- }
+ if (fast)
+ {
+ result[i] = (byte)last;
+ }
+ else
+ {
+ int bytepos = i / 8;
+ result[bytepos] = (byte)((result[bytepos] << 1) | (last & 1));
+ }
+ }
- this.stop = true;
+ this.stop = true;
- return result;
- }
- }
+ return result;
+ }
+ }
- /**
- * Generate seed bytes. Set fast to false for best quality.
- * <p>
- * If fast is set to true, the code should be round about 8 times faster when
- * generating a long sequence of random bytes. 20 bytes of random values using
- * the fast mode take less than half a second on a Nokia e70. If fast is set to false,
- * it takes round about 2500 ms.
- * </p>
- * @param numBytes the number of bytes to generate
- * @param fast true if fast mode should be used
- */
- public byte[] GenerateSeed(
- int numBytes,
- bool fast)
- {
- return new SeedGenerator().GenerateSeed(numBytes, fast);
- }
- }
+ /**
+ * Generate seed bytes. Set fast to false for best quality.
+ * <p>
+ * If fast is set to true, the code should be round about 8 times faster when
+ * generating a long sequence of random bytes. 20 bytes of random values using
+ * the fast mode take less than half a second on a Nokia e70. If fast is set to false,
+ * it takes round about 2500 ms.
+ * </p>
+ * @param numBytes the number of bytes to generate
+ * @param fast true if fast mode should be used
+ */
+ public byte[] GenerateSeed(
+ int numBytes,
+ bool fast)
+ {
+ return new SeedGenerator().GenerateSeed(numBytes, fast);
+ }
+ }
}
|