diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-11-08 17:18:27 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-11-08 17:18:27 +0700 |
commit | d644e956bb0dd3fe0731c3050c185f27ab6d9e1f (patch) | |
tree | 2e4464b274efeb8ce3205c7a736bd65dea7b8262 /crypto | |
parent | Merge pull request #10 from peterdettman/pcl (diff) | |
parent | Merge branch 'master' of git.bouncycastle.org:bc-csharp (diff) | |
download | BouncyCastle.NET-ed25519-d644e956bb0dd3fe0731c3050c185f27ab6d9e1f.tar.xz |
Merge branch 'master' of git.bouncycastle.org:bc-csharp into pcl
Diffstat (limited to 'crypto')
89 files changed, 1617 insertions, 700 deletions
diff --git a/crypto/bzip2/src/CBZip2InputStream.cs b/crypto/bzip2/src/CBZip2InputStream.cs index 7411f0a21..82ff83e42 100644 --- a/crypto/bzip2/src/CBZip2InputStream.cs +++ b/crypto/bzip2/src/CBZip2InputStream.cs @@ -25,6 +25,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Apache.Bzip2 { /** @@ -286,10 +288,10 @@ namespace Org.BouncyCastle.Apache.Bzip2 Cadvise(); } - private void BsFinishedWithStream() { + private void BsFinishedWithStream() { try { if (this.bsStream != null) { - this.bsStream.Dispose(); + Platform.Dispose(this.bsStream); this.bsStream = null; } } catch { diff --git a/crypto/bzip2/src/CBZip2OutputStream.cs b/crypto/bzip2/src/CBZip2OutputStream.cs index 690c8a058..361592796 100644 --- a/crypto/bzip2/src/CBZip2OutputStream.cs +++ b/crypto/bzip2/src/CBZip2OutputStream.cs @@ -25,6 +25,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Apache.Bzip2 { /** @@ -384,23 +386,32 @@ namespace Org.BouncyCastle.Apache.Bzip2 // Close(); // } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { if (closed) - { return; - } Finish(); - closed = true; - - bsStream.Dispose(); + Platform.Dispose(this.bsStream); } base.Dispose(disposing); } +#else + public override void Close() { + if (closed) + return; + + Finish(); + closed = true; + Platform.Dispose(this.bsStream); + + base.Close(); + } +#endif public void Finish() { if (finished) { diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index b147fa9c7..cdb48bfff 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -11865,6 +11865,11 @@ BuildAction = "Compile" /> <File + RelPath = "test\src\math\test\PrimesTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "test\src\ocsp\test\AllTests.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs index 418b560fd..58e7e26f8 100644 --- a/crypto/src/asn1/Asn1Set.cs +++ b/crypto/src/asn1/Asn1Set.cs @@ -75,8 +75,8 @@ namespace Org.BouncyCastle.Asn1 * be converted. */ public static Asn1Set GetInstance( - Asn1TaggedObject obj, - bool explicitly) + Asn1TaggedObject obj, + bool explicitly) { Asn1Object inner = obj.GetObject(); @@ -85,7 +85,7 @@ namespace Org.BouncyCastle.Asn1 if (!obj.IsExplicit()) throw new ArgumentException("object implicit - explicit expected."); - return (Asn1Set) inner; + return (Asn1Set)inner; } // @@ -100,7 +100,7 @@ namespace Org.BouncyCastle.Asn1 if (inner is Asn1Set) { - return (Asn1Set) inner; + return (Asn1Set)inner; } // @@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Asn1 if (inner is Asn1Sequence) { Asn1EncodableVector v = new Asn1EncodableVector(); - Asn1Sequence s = (Asn1Sequence) inner; + Asn1Sequence s = (Asn1Sequence)inner; foreach (Asn1Encodable ae in s) { @@ -149,14 +149,14 @@ namespace Org.BouncyCastle.Asn1 */ public virtual Asn1Encodable this[int index] { - get { return (Asn1Encodable) _set[index]; } + get { return (Asn1Encodable)_set[index]; } } [Obsolete("Use 'object[index]' syntax instead")] public Asn1Encodable GetObjectAt( int index) { - return this[index]; + return this[index]; } [Obsolete("Use 'Count' property instead")] @@ -207,8 +207,8 @@ namespace Org.BouncyCastle.Asn1 return ((Asn1Set)obj).Parser; // NB: Asn1OctetString implements Asn1OctetStringParser directly -// if (obj is Asn1OctetString) -// return ((Asn1OctetString)obj).Parser; + // if (obj is Asn1OctetString) + // return ((Asn1OctetString)obj).Parser; return obj; } @@ -303,12 +303,18 @@ namespace Org.BouncyCastle.Asn1 Asn1Encodable[] items = new Asn1Encodable[_set.Count]; byte[][] keys = new byte[_set.Count][]; - //List<Asn1Encodable[]> t; + for (int i = 0; i < _set.Count; ++i) + { + Asn1Encodable item = (Asn1Encodable)_set[i]; + items[i] = item; + keys[i] = item.GetEncoded(Asn1Encodable.Der); + } + Array.Sort(keys, items, new DerComparer()); for (int i = 0; i < _set.Count; ++i) { - _set[i] = sorted[i]; + _set[i] = items[i]; } #endif } diff --git a/crypto/src/asn1/BEROctetStringGenerator.cs b/crypto/src/asn1/BEROctetStringGenerator.cs index 6d7d1b66e..f34538f38 100644 --- a/crypto/src/asn1/BEROctetStringGenerator.cs +++ b/crypto/src/asn1/BEROctetStringGenerator.cs @@ -102,19 +102,32 @@ namespace Org.BouncyCastle.Asn1 } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (_off != 0) - { - DerOctetString.Encode(_derOut, _buf, 0, _off); - } - - _gen.WriteBerEnd(); - } - base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_off != 0) + { + DerOctetString.Encode(_derOut, _buf, 0, _off); + } + + _gen.WriteBerEnd(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (_off != 0) + { + DerOctetString.Encode(_derOut, _buf, 0, _off); + } + + _gen.WriteBerEnd(); + base.Close(); + } +#endif } } } diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index 57527f3a0..4de0feaa6 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -262,8 +262,13 @@ namespace Org.BouncyCastle.Asn1 DateTimeStyles style = DateTimeStyles.None; if (format.EndsWith("Z")) { - style = DateTimeStyles.AssumeUniversal; - + try + { + style = (DateTimeStyles)Enums.GetEnumValue(typeof(DateTimeStyles), "AssumeUniversal"); + } + catch (Exception) + { + } style |= DateTimeStyles.AdjustToUniversal; } diff --git a/crypto/src/asn1/DerSequence.cs b/crypto/src/asn1/DerSequence.cs index 1a86dc429..a76cf2882 100644 --- a/crypto/src/asn1/DerSequence.cs +++ b/crypto/src/asn1/DerSequence.cs @@ -1,6 +1,9 @@ +using System; using System.Collections; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1 { public class DerSequence @@ -75,9 +78,9 @@ namespace Org.BouncyCastle.Asn1 dOut.WriteObject(obj); } - dOut.Dispose(); + Platform.Dispose(dOut); - byte[] bytes = bOut.ToArray(); + byte[] bytes = bOut.ToArray(); derOut.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, bytes); } diff --git a/crypto/src/asn1/DerSet.cs b/crypto/src/asn1/DerSet.cs index 6d3f438bd..3df1a6766 100644 --- a/crypto/src/asn1/DerSet.cs +++ b/crypto/src/asn1/DerSet.cs @@ -1,5 +1,8 @@ +using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1 { /** @@ -98,9 +101,9 @@ namespace Org.BouncyCastle.Asn1 dOut.WriteObject(obj); } - dOut.Dispose(); + Platform.Dispose(dOut); - byte[] bytes = bOut.ToArray(); + byte[] bytes = bOut.ToArray(); derOut.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, bytes); } diff --git a/crypto/src/asn1/cmp/CertResponse.cs b/crypto/src/asn1/cmp/CertResponse.cs index 246b8ce70..80813b8b7 100644 --- a/crypto/src/asn1/cmp/CertResponse.cs +++ b/crypto/src/asn1/cmp/CertResponse.cs @@ -107,8 +107,7 @@ namespace Org.BouncyCastle.Asn1.Cmp public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(certReqId, status); - v.AddOptional(certifiedKeyPair); - v.AddOptional(rspInfo); + v.AddOptional(certifiedKeyPair, rspInfo); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/ErrorMsgContent.cs b/crypto/src/asn1/cmp/ErrorMsgContent.cs index f4dc584ea..2d6353b65 100644 --- a/crypto/src/asn1/cmp/ErrorMsgContent.cs +++ b/crypto/src/asn1/cmp/ErrorMsgContent.cs @@ -86,8 +86,7 @@ namespace Org.BouncyCastle.Asn1.Cmp public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo); - v.AddOptional(errorCode); - v.AddOptional(errorDetails); + v.AddOptional(errorCode, errorDetails); return new DerSequence(v); } } diff --git a/crypto/src/asn1/crmf/CertReqMsg.cs b/crypto/src/asn1/crmf/CertReqMsg.cs index 2ca319a57..20fd4179a 100644 --- a/crypto/src/asn1/crmf/CertReqMsg.cs +++ b/crypto/src/asn1/crmf/CertReqMsg.cs @@ -98,8 +98,7 @@ namespace Org.BouncyCastle.Asn1.Crmf public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(certReq); - v.AddOptional(popo); - v.AddOptional(regInfo); + v.AddOptional(popo, regInfo); return new DerSequence(v); } } diff --git a/crypto/src/asn1/util/Dump.cs b/crypto/src/asn1/util/Dump.cs index 99ced5836..e313fe879 100644 --- a/crypto/src/asn1/util/Dump.cs +++ b/crypto/src/asn1/util/Dump.cs @@ -2,6 +2,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1.Utilities { public sealed class Dump @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Asn1.Utilities Console.WriteLine(Asn1Dump.DumpAsString(obj)); } - bIn.Close(); + Platform.Dispose(bIn); } } } diff --git a/crypto/src/asn1/util/FilterStream.cs b/crypto/src/asn1/util/FilterStream.cs index 3d08446cd..0c38c5b6e 100644 --- a/crypto/src/asn1/util/FilterStream.cs +++ b/crypto/src/asn1/util/FilterStream.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1.Utilities { [Obsolete("Use Org.BouncyCastle.Utilities.IO.FilterStream")] @@ -32,16 +34,22 @@ namespace Org.BouncyCastle.Asn1.Utilities get { return s.Position; } set { s.Position = value; } } - +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - s.Dispose(); + Platform.Dispose(s); } base.Dispose(disposing); } - +#else + public override void Close() + { + Platform.Dispose(s); + base.Close(); + } +#endif public override void Flush() { s.Flush(); diff --git a/crypto/src/asn1/x509/AlgorithmIdentifier.cs b/crypto/src/asn1/x509/AlgorithmIdentifier.cs index c6f4af5bf..00e7ad8bc 100644 --- a/crypto/src/asn1/x509/AlgorithmIdentifier.cs +++ b/crypto/src/asn1/x509/AlgorithmIdentifier.cs @@ -5,9 +5,8 @@ namespace Org.BouncyCastle.Asn1.X509 public class AlgorithmIdentifier : Asn1Encodable { - private readonly DerObjectIdentifier objectID; + private readonly DerObjectIdentifier algorithm; private readonly Asn1Encodable parameters; - private readonly bool parametersDefined; public static AlgorithmIdentifier GetInstance( Asn1TaggedObject obj, @@ -19,39 +18,32 @@ namespace Org.BouncyCastle.Asn1.X509 public static AlgorithmIdentifier GetInstance( object obj) { - if (obj == null || obj is AlgorithmIdentifier) - return (AlgorithmIdentifier) obj; - - // TODO: delete - if (obj is DerObjectIdentifier) - return new AlgorithmIdentifier((DerObjectIdentifier) obj); - - // TODO: delete - if (obj is string) - return new AlgorithmIdentifier((string) obj); - + if (obj == null) + return null; + if (obj is AlgorithmIdentifier) + return (AlgorithmIdentifier)obj; return new AlgorithmIdentifier(Asn1Sequence.GetInstance(obj)); } public AlgorithmIdentifier( - DerObjectIdentifier objectID) + DerObjectIdentifier algorithm) { - this.objectID = objectID; + this.algorithm = algorithm; } + [Obsolete("Use version taking a DerObjectIdentifier")] public AlgorithmIdentifier( - string objectID) + string algorithm) { - this.objectID = new DerObjectIdentifier(objectID); + this.algorithm = new DerObjectIdentifier(algorithm); } public AlgorithmIdentifier( - DerObjectIdentifier objectID, + DerObjectIdentifier algorithm, Asn1Encodable parameters) { - this.objectID = objectID; + this.algorithm = algorithm; this.parameters = parameters; - this.parametersDefined = true; } internal AlgorithmIdentifier( @@ -60,13 +52,8 @@ namespace Org.BouncyCastle.Asn1.X509 if (seq.Count < 1 || seq.Count > 2) throw new ArgumentException("Bad sequence size: " + seq.Count); - this.objectID = DerObjectIdentifier.GetInstance(seq[0]); - this.parametersDefined = (seq.Count == 2); - - if (parametersDefined) - { - this.parameters = seq[1]; - } + this.algorithm = DerObjectIdentifier.GetInstance(seq[0]); + this.parameters = seq.Count < 2 ? null : seq[1]; } /// <summary> @@ -74,18 +61,19 @@ namespace Org.BouncyCastle.Asn1.X509 /// </summary> public virtual DerObjectIdentifier Algorithm { - get { return objectID; } + get { return algorithm; } } + [Obsolete("Use 'Algorithm' property instead")] public virtual DerObjectIdentifier ObjectID { - get { return objectID; } + get { return algorithm; } } /// <summary> /// Return the parameters structure in the Parameters entry of this identifier. /// </summary> - public Asn1Encodable Parameters + public virtual Asn1Encodable Parameters { get { return parameters; } } @@ -100,20 +88,8 @@ namespace Org.BouncyCastle.Asn1.X509 */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(objectID); - - if (parametersDefined) - { - if (parameters != null) - { - v.Add(parameters); - } - else - { - v.Add(DerNull.Instance); - } - } - + Asn1EncodableVector v = new Asn1EncodableVector(algorithm); + v.AddOptional(parameters); return new DerSequence(v); } } diff --git a/crypto/src/bcpg/ArmoredInputStream.cs b/crypto/src/bcpg/ArmoredInputStream.cs index c7bb85942..d5d9f7ffb 100644 --- a/crypto/src/bcpg/ArmoredInputStream.cs +++ b/crypto/src/bcpg/ArmoredInputStream.cs @@ -504,13 +504,21 @@ namespace Org.BouncyCastle.Bcpg return pos - offset; } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - input.Dispose(); + Platform.Dispose(input); } base.Dispose(disposing); } +#else + public override void Close() + { + Platform.Dispose(input); + base.Close(); + } +#endif } } diff --git a/crypto/src/bcpg/ArmoredOutputStream.cs b/crypto/src/bcpg/ArmoredOutputStream.cs index 44b2b78e7..1f0e412d8 100644 --- a/crypto/src/bcpg/ArmoredOutputStream.cs +++ b/crypto/src/bcpg/ArmoredOutputStream.cs @@ -283,40 +283,60 @@ namespace Org.BouncyCastle.Bcpg * <b>Note</b>: Close() does not close the underlying stream. So it is possible to write * multiple objects using armoring to a single stream. */ +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) - { - if (type != null) { - if (bufPtr > 0) - { - Encode(outStream, buf, bufPtr); - } + if (type == null) + return; - DoWrite(nl + '='); + DoClose(); - int crcV = crc.Value; - - buf[0] = ((crcV >> 16) & 0xff); - buf[1] = ((crcV >> 8) & 0xff); - buf[2] = (crcV & 0xff); + type = null; + start = true; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (type == null) + return; - Encode(outStream, buf, 3); + DoClose(); - DoWrite(nl); - DoWrite(footerStart); - DoWrite(type); - DoWrite(footerTail); - DoWrite(nl); + type = null; + start = true; - outStream.Flush(); + base.Close(); + } +#endif - type = null; - start = true; - } + private void DoClose() + { + if (bufPtr > 0) + { + Encode(outStream, buf, bufPtr); } - base.Dispose(disposing); + + DoWrite(nl + '='); + + int crcV = crc.Value; + + buf[0] = ((crcV >> 16) & 0xff); + buf[1] = ((crcV >> 8) & 0xff); + buf[2] = (crcV & 0xff); + + Encode(outStream, buf, 3); + + DoWrite(nl); + DoWrite(footerStart); + DoWrite(type); + DoWrite(footerTail); + DoWrite(nl); + + outStream.Flush(); } private void WriteHeaderEntry( diff --git a/crypto/src/bcpg/BcpgInputStream.cs b/crypto/src/bcpg/BcpgInputStream.cs index 9835891b1..f9627fde0 100644 --- a/crypto/src/bcpg/BcpgInputStream.cs +++ b/crypto/src/bcpg/BcpgInputStream.cs @@ -2,6 +2,7 @@ using System; using System.IO; using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Bcpg @@ -246,14 +247,22 @@ namespace Org.BouncyCastle.Bcpg } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - m_in.Dispose(); - } - base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(m_in); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(m_in); + base.Close(); + } +#endif /// <summary> /// A stream that overlays our input stream, allowing the user to only read a segment of it. diff --git a/crypto/src/bcpg/BcpgOutputStream.cs b/crypto/src/bcpg/BcpgOutputStream.cs index f62fadc19..7ab661edb 100644 --- a/crypto/src/bcpg/BcpgOutputStream.cs +++ b/crypto/src/bcpg/BcpgOutputStream.cs @@ -1,6 +1,7 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Bcpg @@ -379,15 +380,25 @@ namespace Org.BouncyCastle.Bcpg } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - this.Finish(); - outStr.Flush(); - outStr.Dispose(); - } - base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.Finish(); + outStr.Flush(); + Platform.Dispose(outStr); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + this.Finish(); + outStr.Flush(); + Platform.Dispose(outStr); + base.Close(); + } +#endif } } diff --git a/crypto/src/bcpg/PublicKeyEncSessionPacket.cs b/crypto/src/bcpg/PublicKeyEncSessionPacket.cs index eefe4495b..831b5a189 100644 --- a/crypto/src/bcpg/PublicKeyEncSessionPacket.cs +++ b/crypto/src/bcpg/PublicKeyEncSessionPacket.cs @@ -107,7 +107,7 @@ namespace Org.BouncyCastle.Bcpg pOut.Write(data[i]); } - pOut.Dispose(); + Platform.Dispose(pOut); bcpgOut.WritePacket(PacketTag.PublicKeyEncryptedSession , bOut.ToArray(), true); } diff --git a/crypto/src/cms/CMSAuthenticatedDataGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataGenerator.cs index 0a37ca4f5..131a4753f 100644 --- a/crypto/src/cms/CMSAuthenticatedDataGenerator.cs +++ b/crypto/src/cms/CMSAuthenticatedDataGenerator.cs @@ -9,6 +9,7 @@ using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Cms @@ -83,10 +84,9 @@ namespace Org.BouncyCastle.Cms content.Write(mOut); - mOut.Dispose(); - bOut.Dispose(); + Platform.Dispose(mOut); - encContent = new BerOctetString(bOut.ToArray()); + encContent = new BerOctetString(bOut.ToArray()); byte[] macOctets = MacUtilities.DoFinal(mac); macResult = new DerOctetString(macOctets); diff --git a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs index 6638ccff7..a135cdd11 100644 --- a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs @@ -9,6 +9,7 @@ using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Cms @@ -251,26 +252,46 @@ namespace Org.BouncyCastle.Cms macStream.Write(bytes, off, len); } - protected override void Dispose(bool disposing) - { - if (disposing) - { - macStream.Dispose(); +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(macStream); // TODO Parent context(s) should really be be closed explicitly - eiGen.Close(); + eiGen.Close(); - // [TODO] auth attributes go here - byte[] macOctets = MacUtilities.DoFinal(mac); - authGen.AddObject(new DerOctetString(macOctets)); - // [TODO] unauth attributes go here + // [TODO] auth attributes go here + byte[] macOctets = MacUtilities.DoFinal(mac); + authGen.AddObject(new DerOctetString(macOctets)); + // [TODO] unauth attributes go here - authGen.Close(); - cGen.Close(); - } - base.Dispose(disposing); - } + authGen.Close(); + cGen.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(macStream); + + // TODO Parent context(s) should really be be closed explicitly + + eiGen.Close(); + + // [TODO] auth attributes go here + byte[] macOctets = MacUtilities.DoFinal(mac); + authGen.AddObject(new DerOctetString(macOctets)); + // [TODO] unauth attributes go here + + authGen.Close(); + cGen.Close(); + base.Close(); + } +#endif } } } diff --git a/crypto/src/cms/CMSCompressedData.cs b/crypto/src/cms/CMSCompressedData.cs index a351d7206..21651f041 100644 --- a/crypto/src/cms/CMSCompressedData.cs +++ b/crypto/src/cms/CMSCompressedData.cs @@ -3,6 +3,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Zlib; namespace Org.BouncyCastle.Cms @@ -56,7 +57,7 @@ namespace Org.BouncyCastle.Cms } finally { - zIn.Dispose(); + Platform.Dispose(zIn); } } diff --git a/crypto/src/cms/CMSCompressedDataGenerator.cs b/crypto/src/cms/CMSCompressedDataGenerator.cs index f147bb7ea..d51de1026 100644 --- a/crypto/src/cms/CMSCompressedDataGenerator.cs +++ b/crypto/src/cms/CMSCompressedDataGenerator.cs @@ -5,6 +5,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Zlib; namespace Org.BouncyCastle.Cms @@ -45,9 +46,9 @@ namespace Org.BouncyCastle.Cms content.Write(zOut); - zOut.Dispose(); + Platform.Dispose(zOut); - comAlgId = new AlgorithmIdentifier(new DerObjectIdentifier(compressionOid)); + comAlgId = new AlgorithmIdentifier(new DerObjectIdentifier(compressionOid)); comOcts = new BerOctetString(bOut.ToArray()); } catch (IOException e) diff --git a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs index c5a4afa1c..0cb1bb641 100644 --- a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs @@ -4,6 +4,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; using Org.BouncyCastle.Utilities.Zlib; @@ -124,20 +125,34 @@ namespace Org.BouncyCastle.Cms _out.Write(bytes, off, len); } - protected override void Dispose(bool disposing) - { - if (disposing) - { - _out.Dispose(); +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(_out); // TODO Parent context(s) should really be be closed explicitly _eiGen.Close(); - _cGen.Close(); - _sGen.Close(); - } - base.Dispose(disposing); - } + _cGen.Close(); + _sGen.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be be closed explicitly + + _eiGen.Close(); + _cGen.Close(); + _sGen.Close(); + base.Close(); + } +#endif } } } diff --git a/crypto/src/cms/CMSContentInfoParser.cs b/crypto/src/cms/CMSContentInfoParser.cs index 5b1606394..a7b43f295 100644 --- a/crypto/src/cms/CMSContentInfoParser.cs +++ b/crypto/src/cms/CMSContentInfoParser.cs @@ -3,6 +3,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Cms { @@ -41,7 +42,7 @@ namespace Org.BouncyCastle.Cms */ public void Close() { - this.data.Dispose(); + Platform.Dispose(this.data); } } } diff --git a/crypto/src/cms/CMSEnvelopedDataGenerator.cs b/crypto/src/cms/CMSEnvelopedDataGenerator.cs index 5071af4ad..d260e998a 100644 --- a/crypto/src/cms/CMSEnvelopedDataGenerator.cs +++ b/crypto/src/cms/CMSEnvelopedDataGenerator.cs @@ -80,9 +80,9 @@ namespace Org.BouncyCastle.Cms content.Write(cOut); - cOut.Dispose(); + Platform.Dispose(cOut); - encContent = new BerOctetString(bOut.ToArray()); + encContent = new BerOctetString(bOut.ToArray()); } catch (SecurityUtilityException e) { diff --git a/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs b/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs index cb5b246eb..0a9e5bece 100644 --- a/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs @@ -255,15 +255,16 @@ namespace Org.BouncyCastle.Cms _out.Write(bytes, off, len); } - protected override void Dispose(bool disposing) - { - if (disposing) - { - _out.Dispose(); +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(_out); - // TODO Parent context(s) should really be be closed explicitly + // TODO Parent context(s) should really be closed explicitly - _eiGen.Close(); + _eiGen.Close(); if (_outer.unprotectedAttributeGenerator != null) { @@ -274,11 +275,34 @@ namespace Org.BouncyCastle.Cms _envGen.AddObject(new DerTaggedObject(false, 1, unprotectedAttrs)); } - _envGen.Close(); - _cGen.Close(); - } - base.Dispose(disposing); - } + _envGen.Close(); + _cGen.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be closed explicitly + + _eiGen.Close(); + + if (_outer.unprotectedAttributeGenerator != null) + { + Asn1.Cms.AttributeTable attrTable = _outer.unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable()); + + Asn1Set unprotectedAttrs = new BerSet(attrTable.ToAsn1EncodableVector()); + + _envGen.AddObject(new DerTaggedObject(false, 1, unprotectedAttrs)); + } + + _envGen.Close(); + _cGen.Close(); + base.Close(); + } +#endif } } } diff --git a/crypto/src/cms/CMSProcessableFile.cs b/crypto/src/cms/CMSProcessableFile.cs index 46f88cd9f..5494b238a 100644 --- a/crypto/src/cms/CMSProcessableFile.cs +++ b/crypto/src/cms/CMSProcessableFile.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Cms @@ -37,7 +38,7 @@ namespace Org.BouncyCastle.Cms { Stream inStr = GetInputStream(); Streams.PipeAll(inStr, zOut); - inStr.Dispose(); + Platform.Dispose(inStr); } /// <returns>The file handle</returns> diff --git a/crypto/src/cms/CMSProcessableInputStream.cs b/crypto/src/cms/CMSProcessableInputStream.cs index 978caf862..b2abd6f71 100644 --- a/crypto/src/cms/CMSProcessableInputStream.cs +++ b/crypto/src/cms/CMSProcessableInputStream.cs @@ -1,6 +1,7 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Cms @@ -29,7 +30,7 @@ namespace Org.BouncyCastle.Cms CheckSingleUsage(); Streams.PipeAll(input, output); - input.Dispose(); + Platform.Dispose(input); } [Obsolete] diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs index 3d4dfeb95..f63ed874e 100644 --- a/crypto/src/cms/CMSSignedDataGenerator.cs +++ b/crypto/src/cms/CMSSignedDataGenerator.cs @@ -173,7 +173,7 @@ namespace Org.BouncyCastle.Cms content.Write(sigStr); } - sigStr.Dispose(); + Platform.Dispose(sigStr); byte[] sigBytes = ((IBlockResult)calculator.GetResult()).Collect(); Asn1Set unsignedAttr = null; diff --git a/crypto/src/cms/CMSSignedDataParser.cs b/crypto/src/cms/CMSSignedDataParser.cs index ec5a84fdf..e5e6edc58 100644 --- a/crypto/src/cms/CMSSignedDataParser.cs +++ b/crypto/src/cms/CMSSignedDataParser.cs @@ -384,7 +384,7 @@ namespace Org.BouncyCastle.Cms // gen.AddSigners(parser.GetSignerInfos()); - contentOut.Dispose(); + Platform.Dispose(contentOut); return outStr; } @@ -434,12 +434,12 @@ namespace Org.BouncyCastle.Cms gen.AddSigners(parser.GetSignerInfos()); - contentOut.Dispose(); + Platform.Dispose(contentOut); - return outStr; + return outStr; } - private static Asn1Set GetAsn1Set( + private static Asn1Set GetAsn1Set( Asn1SetParser asn1SetParser) { return asn1SetParser == null diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs index ceec09715..59837e397 100644 --- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs @@ -636,7 +636,7 @@ namespace Org.BouncyCastle.Cms { content.Write(signedOut); } - signedOut.Dispose(); + Platform.Dispose(signedOut); } // RFC3852, section 5.1: @@ -809,100 +809,113 @@ namespace Org.BouncyCastle.Cms _out.Write(bytes, off, len); } - protected override void Dispose(bool disposing) - { - if (disposing) - { - _out.Dispose(); +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + DoClose(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + DoClose(); + base.Close(); + } +#endif - // TODO Parent context(s) should really be be closed explicitly + private void DoClose() + { + Platform.Dispose(_out); - _eiGen.Close(); + // TODO Parent context(s) should really be be closed explicitly - outer._digests.Clear(); // clear the current preserved digest state + _eiGen.Close(); - if (outer._certs.Count > 0) - { - Asn1Set certs = CmsUtilities.CreateBerSetFromList(outer._certs); + outer._digests.Clear(); // clear the current preserved digest state - WriteToGenerator(_sigGen, new BerTaggedObject(false, 0, certs)); - } + if (outer._certs.Count > 0) + { + Asn1Set certs = CmsUtilities.CreateBerSetFromList(outer._certs); - if (outer._crls.Count > 0) - { - Asn1Set crls = CmsUtilities.CreateBerSetFromList(outer._crls); + WriteToGenerator(_sigGen, new BerTaggedObject(false, 0, certs)); + } - WriteToGenerator(_sigGen, new BerTaggedObject(false, 1, crls)); - } + if (outer._crls.Count > 0) + { + Asn1Set crls = CmsUtilities.CreateBerSetFromList(outer._crls); - // - // Calculate the digest hashes - // - foreach (DictionaryEntry de in outer._messageDigests) - { - outer._messageHashes.Add(de.Key, DigestUtilities.DoFinal((IDigest)de.Value)); - } + WriteToGenerator(_sigGen, new BerTaggedObject(false, 1, crls)); + } + + // + // Calculate the digest hashes + // + foreach (DictionaryEntry de in outer._messageDigests) + { + outer._messageHashes.Add(de.Key, DigestUtilities.DoFinal((IDigest)de.Value)); + } - // TODO If the digest OIDs for precalculated signers weren't mixed in with - // the others, we could fill in outer._digests here, instead of SignerInfoGenerator.Generate + // TODO If the digest OIDs for precalculated signers weren't mixed in with + // the others, we could fill in outer._digests here, instead of SignerInfoGenerator.Generate - // - // collect all the SignerInfo objects - // - Asn1EncodableVector signerInfos = new Asn1EncodableVector(); + // + // collect all the SignerInfo objects + // + Asn1EncodableVector signerInfos = new Asn1EncodableVector(); - // - // add the generated SignerInfo objects - // + // + // add the generated SignerInfo objects + // + { + foreach (DigestAndSignerInfoGeneratorHolder holder in outer._signerInfs) { - foreach (DigestAndSignerInfoGeneratorHolder holder in outer._signerInfs) - { - AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm; + AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm; - byte[] calculatedDigest = (byte[])outer._messageHashes[ - Helper.GetDigestAlgName(holder.digestOID)]; - outer._digests[holder.digestOID] = calculatedDigest.Clone(); + byte[] calculatedDigest = (byte[])outer._messageHashes[ + Helper.GetDigestAlgName(holder.digestOID)]; + outer._digests[holder.digestOID] = calculatedDigest.Clone(); - signerInfos.Add(holder.signerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest)); - } + signerInfos.Add(holder.signerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest)); } + } - // - // add the precalculated SignerInfo objects. - // + // + // add the precalculated SignerInfo objects. + // + { + foreach (SignerInformation signer in outer._signers) { - foreach (SignerInformation signer in outer._signers) - { - // TODO Verify the content type and calculated digest match the precalculated SignerInfo - // if (!signer.ContentType.Equals(_contentOID)) - // { - // // TODO The precalculated content type did not match - error? - // } - // - // byte[] calculatedDigest = (byte[])outer._digests[signer.DigestAlgOid]; - // if (calculatedDigest == null) - // { - // // TODO We can't confirm this digest because we didn't calculate it - error? - // } - // else - // { - // if (!Arrays.AreEqual(signer.GetContentDigest(), calculatedDigest)) - // { - // // TODO The precalculated digest did not match - error? - // } - // } - - signerInfos.Add(signer.ToSignerInfo()); - } + // TODO Verify the content type and calculated digest match the precalculated SignerInfo +// if (!signer.ContentType.Equals(_contentOID)) +// { +// // TODO The precalculated content type did not match - error? +// } +// +// byte[] calculatedDigest = (byte[])outer._digests[signer.DigestAlgOid]; +// if (calculatedDigest == null) +// { +// // TODO We can't confirm this digest because we didn't calculate it - error? +// } +// else +// { +// if (!Arrays.AreEqual(signer.GetContentDigest(), calculatedDigest)) +// { +// // TODO The precalculated digest did not match - error? +// } +// } + + signerInfos.Add(signer.ToSignerInfo()); } + } - WriteToGenerator(_sigGen, new DerSet(signerInfos)); + WriteToGenerator(_sigGen, new DerSet(signerInfos)); - _sigGen.Close(); - _sGen.Close(); - } - base.Dispose(disposing); - } + _sigGen.Close(); + _sGen.Close(); + } private static void WriteToGenerator( Asn1Generator ag, diff --git a/crypto/src/cms/CMSTypedStream.cs b/crypto/src/cms/CMSTypedStream.cs index 73b439cce..681583765 100644 --- a/crypto/src/cms/CMSTypedStream.cs +++ b/crypto/src/cms/CMSTypedStream.cs @@ -2,6 +2,7 @@ using System; using System.IO; using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Cms @@ -52,7 +53,7 @@ namespace Org.BouncyCastle.Cms public void Drain() { Streams.Drain(_in); - _in.Dispose(); + Platform.Dispose(_in); } private class FullReaderStream : FilterStream diff --git a/crypto/src/crypto/digests/GeneralDigest.cs b/crypto/src/crypto/digests/GeneralDigest.cs index 54a09ae05..d40ad28bb 100644 --- a/crypto/src/crypto/digests/GeneralDigest.cs +++ b/crypto/src/crypto/digests/GeneralDigest.cs @@ -55,38 +55,44 @@ namespace Org.BouncyCastle.Crypto.Digests int inOff, int length) { + length = System.Math.Max(0, length); + // // fill the current word // - while ((xBufOff != 0) && (length > 0)) + int i = 0; + if (xBufOff != 0) { - Update(input[inOff]); - inOff++; - length--; + while (i < length) + { + xBuf[xBufOff++] = input[inOff + i++]; + if (xBufOff == 4) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + break; + } + } } // // process whole words. // - while (length > xBuf.Length) + int limit = ((length - i) & ~3) + i; + for (; i < limit; i += 4) { - ProcessWord(input, inOff); - - inOff += xBuf.Length; - length -= xBuf.Length; - byteCount += xBuf.Length; + ProcessWord(input, inOff + i); } // // load in the remainder. // - while (length > 0) + while (i < length) { - Update(input[inOff]); - - inOff++; - length--; + xBuf[xBufOff++] = input[inOff + i++]; } + + byteCount += length; } public void Finish() diff --git a/crypto/src/crypto/engines/AesEngine.cs b/crypto/src/crypto/engines/AesEngine.cs index 164c43ee9..c84f4a964 100644 --- a/crypto/src/crypto/engines/AesEngine.cs +++ b/crypto/src/crypto/engines/AesEngine.cs @@ -288,17 +288,14 @@ namespace Org.BouncyCastle.Crypto.Engines * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits * This code is written assuming those are the only possible values */ - private uint[][] GenerateWorkingKey( - byte[] key, - bool forEncryption) + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) { - int KC = key.Length / 4; // key length in words - int t; - - if ((KC != 4) && (KC != 6) && (KC != 8)) + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) throw new ArgumentException("Key length not 128/192/256 bits."); - ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block for (int i = 0; i <= ROUNDS; ++i) @@ -306,35 +303,109 @@ namespace Org.BouncyCastle.Crypto.Engines W[i] = new uint[4]; } - // - // copy the key into the round key array - // - - t = 0; - for (int i = 0; i < key.Length; t++) - { - W[t >> 2][t & 3] = Pack.LE_To_UInt32(key, i); - i+=4; - } - - // - // while not enough round key material calculated - // calculate new values - // - int k = (ROUNDS + 1) << 2; - for (int i = KC; (i < k); i++) + switch (KC) { - uint temp = W[(i-1)>>2][(i-1)&3]; - if ((i % KC) == 0) + case 4: { - temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1]; - } - else if ((KC > 6) && ((i % KC) == 4)) + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; + } + case 6: { - temp = SubWord(temp); + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; + + break; } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; - W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } } if (!forEncryption) diff --git a/crypto/src/crypto/engines/AesFastEngine.cs b/crypto/src/crypto/engines/AesFastEngine.cs index 38ce1a946..18367a324 100644 --- a/crypto/src/crypto/engines/AesFastEngine.cs +++ b/crypto/src/crypto/engines/AesFastEngine.cs @@ -624,16 +624,14 @@ namespace Org.BouncyCastle.Crypto.Engines * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits * This code is written assuming those are the only possible values */ - private uint[][] GenerateWorkingKey( - byte[] key, - bool forEncryption) + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) { - int KC = key.Length / 4; // key length in words - - if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.Length)) + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) throw new ArgumentException("Key length not 128/192/256 bits."); - ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block for (int i = 0; i <= ROUNDS; ++i) @@ -641,32 +639,109 @@ namespace Org.BouncyCastle.Crypto.Engines W[i] = new uint[4]; } - // - // copy the key into the round key array - // - - int t = 0; - for (int i = 0; i < key.Length; t++) + switch (KC) + { + case 4: { - W[t >> 2][t & 3] = Pack.LE_To_UInt32(key, i); - i+=4; + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; } + case 6: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; - // - // while not enough round key material calculated - // calculate new values - // - int k = (ROUNDS + 1) << 2; - for (int i = KC; (i < k); i++) + break; + } + case 8: { - uint temp = W[(i-1)>>2][(i-1)&3]; - if ((i % KC) == 0) { - temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1]; - } else if ((KC > 6) && ((i % KC) == 4)) { - temp = SubWord(temp); + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; } - W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; + + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } } if (!forEncryption) diff --git a/crypto/src/crypto/engines/AesLightEngine.cs b/crypto/src/crypto/engines/AesLightEngine.cs index a42b34971..a48fa5857 100644 --- a/crypto/src/crypto/engines/AesLightEngine.cs +++ b/crypto/src/crypto/engines/AesLightEngine.cs @@ -185,17 +185,14 @@ namespace Org.BouncyCastle.Crypto.Engines * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits * This code is written assuming those are the only possible values */ - private uint[][] GenerateWorkingKey( - byte[] key, - bool forEncryption) + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) { - int KC = key.Length / 4; // key length in words - int t; - - if ((KC != 4) && (KC != 6) && (KC != 8)) + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) throw new ArgumentException("Key length not 128/192/256 bits."); - ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block for (int i = 0; i <= ROUNDS; ++i) @@ -203,40 +200,114 @@ namespace Org.BouncyCastle.Crypto.Engines W[i] = new uint[4]; } - // - // copy the key into the round key array - // - - t = 0; - for (int i = 0; i < key.Length; t++) - { - W[t >> 2][t & 3] = Pack.LE_To_UInt32(key, i); - i+=4; - } - - // - // while not enough round key material calculated - // calculate new values - // - int k = (ROUNDS + 1) << 2; - for (int i = KC; (i < k); i++) + switch (KC) { - uint temp = W[(i-1)>>2][(i-1)&3]; - if ((i % KC) == 0) + case 4: { - temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC)-1]; - } - else if ((KC > 6) && ((i % KC) == 4)) + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; + } + case 6: { - temp = SubWord(temp); + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; + + break; } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; - W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } } - if (!forEncryption) + if (!forEncryption) { - for (int j = 1; j < ROUNDS; j++) + for (int j = 1; j < ROUNDS; j++) { uint[] w = W[j]; for (int i = 0; i < 4; i++) diff --git a/crypto/src/crypto/generators/DHParametersHelper.cs b/crypto/src/crypto/generators/DHParametersHelper.cs index bf2de2add..385690430 100644 --- a/crypto/src/crypto/generators/DHParametersHelper.cs +++ b/crypto/src/crypto/generators/DHParametersHelper.cs @@ -44,10 +44,10 @@ namespace Org.BouncyCastle.Crypto.Generators p = q.ShiftLeft(1).Add(BigInteger.One); - if (!p.IsProbablePrime(certainty)) + if (!p.IsProbablePrime(certainty, true)) continue; - if (certainty > 2 && !q.IsProbablePrime(certainty - 2)) + if (certainty > 2 && !q.IsProbablePrime(certainty, true)) continue; break; @@ -92,15 +92,15 @@ namespace Org.BouncyCastle.Crypto.Generators if (q.BitLength != qLength) continue; - if (!q.RabinMillerTest(2, random)) + if (!q.RabinMillerTest(2, random, true)) continue; p = q.ShiftLeft(1).Add(BigInteger.One); - if (!p.RabinMillerTest(certainty, random)) + if (!p.RabinMillerTest(certainty, random, true)) continue; - if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random)) + if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random, true)) continue; /* diff --git a/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs b/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs index cff12ac44..d68106844 100644 --- a/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs +++ b/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs @@ -98,7 +98,7 @@ namespace Org.BouncyCastle.Crypto.Generators p = _p.Multiply(_2au).Add(BigInteger.One); - if (!p.IsProbablePrime(certainty)) + if (!p.IsProbablePrime(certainty, true)) continue; for (;;) @@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Generators q = _q.Multiply(_2bv).Add(BigInteger.One); - if (q.IsProbablePrime(certainty)) + if (q.IsProbablePrime(certainty, true)) break; } diff --git a/crypto/src/crypto/generators/RsaKeyPairGenerator.cs b/crypto/src/crypto/generators/RsaKeyPairGenerator.cs index 2613b902b..449976550 100644 --- a/crypto/src/crypto/generators/RsaKeyPairGenerator.cs +++ b/crypto/src/crypto/generators/RsaKeyPairGenerator.cs @@ -150,7 +150,7 @@ namespace Org.BouncyCastle.Crypto.Generators if (p.Mod(e).Equals(One)) continue; - if (!p.IsProbablePrime(parameters.Certainty)) + if (!p.IsProbablePrime(parameters.Certainty, true)) continue; if (!eIsKnownOddPrime && !e.Gcd(p.Subtract(One)).Equals(One)) diff --git a/crypto/src/crypto/io/CipherStream.cs b/crypto/src/crypto/io/CipherStream.cs index f2083e878..bfce386a7 100644 --- a/crypto/src/crypto/io/CipherStream.cs +++ b/crypto/src/crypto/io/CipherStream.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.IO { @@ -201,22 +202,36 @@ namespace Org.BouncyCastle.Crypto.IO set { throw new NotSupportedException(); } } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - if (outCipher != null) - { - byte[] data = outCipher.DoFinal(); - stream.Write(data, 0, data.Length); - stream.Flush(); - } - stream.Dispose(); + if (outCipher != null) + { + byte[] data = outCipher.DoFinal(); + stream.Write(data, 0, data.Length); + stream.Flush(); + } + Platform.Dispose(stream); } base.Dispose(disposing); } +#else + public override void Close() + { + if (outCipher != null) + { + byte[] data = outCipher.DoFinal(); + stream.Write(data, 0, data.Length); + stream.Flush(); + } + Platform.Dispose(stream); + base.Close(); + } +#endif - public override void Flush() + public override void Flush() { // Note: outCipher.DoFinal is only called during Close() stream.Flush(); diff --git a/crypto/src/crypto/io/DigestStream.cs b/crypto/src/crypto/io/DigestStream.cs index b0a69f03e..dce875792 100644 --- a/crypto/src/crypto/io/DigestStream.cs +++ b/crypto/src/crypto/io/DigestStream.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.IO { public class DigestStream @@ -110,16 +112,24 @@ namespace Org.BouncyCastle.Crypto.IO set { stream.Position = value; } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - stream.Dispose(); - } - base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(stream); + base.Close(); + } +#endif - public override void Flush() + public override void Flush() { stream.Flush(); } diff --git a/crypto/src/crypto/io/MacStream.cs b/crypto/src/crypto/io/MacStream.cs index c7feabcae..d9b8323b5 100644 --- a/crypto/src/crypto/io/MacStream.cs +++ b/crypto/src/crypto/io/MacStream.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.IO { public class MacStream @@ -109,16 +111,24 @@ namespace Org.BouncyCastle.Crypto.IO set { stream.Position = value; } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - stream.Dispose(); - } - base.Dispose(disposing); - } - - public override void Flush() +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(stream); + base.Close(); + } +#endif + + public override void Flush() { stream.Flush(); } diff --git a/crypto/src/crypto/io/SignerStream.cs b/crypto/src/crypto/io/SignerStream.cs index 2a609f6ee..1e37c8d34 100644 --- a/crypto/src/crypto/io/SignerStream.cs +++ b/crypto/src/crypto/io/SignerStream.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.IO { public class SignerStream @@ -110,16 +112,24 @@ namespace Org.BouncyCastle.Crypto.IO set { stream.Position = value; } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - stream.Dispose(); - } - base.Dispose(disposing); - } - - public override void Flush() +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(stream); + base.Close(); + } +#endif + + public override void Flush() { stream.Flush(); } diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index 8e6120eef..ecebc3de9 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -513,10 +513,11 @@ namespace Org.BouncyCastle.Crypto.Modes private byte[] GetNextCounterBlock() { - for (int i = 15; i >= 12; --i) - { - if (++counter[i] != 0) break; - } + uint c = 1; + c += counter[15]; counter[15] = (byte)c; c >>= 8; + c += counter[14]; counter[14] = (byte)c; c >>= 8; + c += counter[13]; counter[13] = (byte)c; c >>= 8; + c += counter[12]; counter[12] = (byte)c; byte[] tmp = new byte[BlockSize]; // TODO Sure would be nice if ciphers could operate on int[] diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs index ec59c11aa..3a20e4bff 100644 --- a/crypto/src/crypto/operators/Asn1Signature.cs +++ b/crypto/src/crypto/operators/Asn1Signature.cs @@ -303,12 +303,7 @@ namespace Org.BouncyCastle.Crypto.Operators set { throw new NotImplementedException (); } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - } - - public override void Flush() + public override void Flush() { } diff --git a/crypto/src/crypto/parameters/SkeinParameters.cs b/crypto/src/crypto/parameters/SkeinParameters.cs index 82a78968f..cc57ef5ff 100644 --- a/crypto/src/crypto/parameters/SkeinParameters.cs +++ b/crypto/src/crypto/parameters/SkeinParameters.cs @@ -240,7 +240,7 @@ namespace Org.BouncyCastle.Crypto.Parameters outBytes.Write(emailAddress); outBytes.Write(" "); outBytes.Write(distinguisher); - outBytes.Dispose(); + Platform.Dispose(outBytes); return Set(PARAM_TYPE_PERSONALISATION, bout.ToArray()); } catch (IOException e) diff --git a/crypto/src/crypto/prng/ThreadedSeedGenerator.cs b/crypto/src/crypto/prng/ThreadedSeedGenerator.cs index 6b732161d..499aab267 100644 --- a/crypto/src/crypto/prng/ThreadedSeedGenerator.cs +++ b/crypto/src/crypto/prng/ThreadedSeedGenerator.cs @@ -73,8 +73,6 @@ namespace Org.BouncyCastle.Crypto.Prng for (int i = 0; i < end; i++) { - using (var mre = new ManualResetEvent(false)) - { while (this.counter == last) { try @@ -90,7 +88,6 @@ namespace Org.BouncyCastle.Crypto.Prng // ignore } } - } last = this.counter; diff --git a/crypto/src/crypto/tls/ByteQueueStream.cs b/crypto/src/crypto/tls/ByteQueueStream.cs index 3b8ffb02f..249e6099b 100644 --- a/crypto/src/crypto/tls/ByteQueueStream.cs +++ b/crypto/src/crypto/tls/ByteQueueStream.cs @@ -33,11 +33,6 @@ namespace Org.BouncyCastle.Crypto.Tls get { return true; } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - } - public override void Flush() { } diff --git a/crypto/src/crypto/tls/CertificateUrl.cs b/crypto/src/crypto/tls/CertificateUrl.cs index b51121121..d285fa0f6 100644 --- a/crypto/src/crypto/tls/CertificateUrl.cs +++ b/crypto/src/crypto/tls/CertificateUrl.cs @@ -117,7 +117,7 @@ namespace Org.BouncyCastle.Crypto.Tls this.Position = 0; TlsUtilities.WriteUint16((int)length, this); this.WriteTo(output); - this.Dispose(); + Platform.Dispose(this); } } } diff --git a/crypto/src/crypto/tls/DtlsReliableHandshake.cs b/crypto/src/crypto/tls/DtlsReliableHandshake.cs index 527a02a22..c45e15f66 100644 --- a/crypto/src/crypto/tls/DtlsReliableHandshake.cs +++ b/crypto/src/crypto/tls/DtlsReliableHandshake.cs @@ -419,9 +419,9 @@ namespace Org.BouncyCastle.Crypto.Tls internal void SendToRecordLayer(DtlsRecordLayer recordLayer) { - var buffer = ToArray(); + byte[] buffer = ToArray(); recordLayer.Send(buffer, 0, buffer.Length); - this.Dispose(); + Platform.Dispose(this); } } diff --git a/crypto/src/crypto/tls/RecordStream.cs b/crypto/src/crypto/tls/RecordStream.cs index 4c57da502..d510ed94e 100644 --- a/crypto/src/crypto/tls/RecordStream.cs +++ b/crypto/src/crypto/tls/RecordStream.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Tls { /// <summary>An implementation of the TLS 1.0/1.1/1.2 record layer, allowing downgrade to SSLv3.</summary> @@ -287,7 +289,7 @@ namespace Org.BouncyCastle.Crypto.Tls { try { - mInput.Dispose(); + Platform.Dispose(mInput); } catch (IOException) { @@ -295,7 +297,7 @@ namespace Org.BouncyCastle.Crypto.Tls try { - mOutput.Dispose(); + Platform.Dispose(mOutput); } catch (IOException) { diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs index fb25029f7..c3a7572c6 100644 --- a/crypto/src/crypto/tls/TlsProtocol.cs +++ b/crypto/src/crypto/tls/TlsProtocol.cs @@ -1311,7 +1311,7 @@ namespace Org.BouncyCastle.Crypto.Tls this.Position = 1; TlsUtilities.WriteUint24((int)length, this); protocol.WriteHandshakeMessage(ToArray(), 0, (int)Length); - this.Dispose(); + Platform.Dispose(this); } } } diff --git a/crypto/src/crypto/tls/TlsStream.cs b/crypto/src/crypto/tls/TlsStream.cs index f78ba0344..bfd80edf2 100644 --- a/crypto/src/crypto/tls/TlsStream.cs +++ b/crypto/src/crypto/tls/TlsStream.cs @@ -28,6 +28,7 @@ namespace Org.BouncyCastle.Crypto.Tls get { return !handler.IsClosed; } } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) @@ -36,6 +37,13 @@ namespace Org.BouncyCastle.Crypto.Tls } base.Dispose(disposing); } +#else + public override void Close() + { + handler.Close(); + base.Close(); + } +#endif public override void Flush() { diff --git a/crypto/src/math/BigInteger.cs b/crypto/src/math/BigInteger.cs index ebeb78788..3d0509fe0 100644 --- a/crypto/src/math/BigInteger.cs +++ b/crypto/src/math/BigInteger.cs @@ -702,7 +702,7 @@ namespace Org.BouncyCastle.Math if (certainty < 1) break; - if (CheckProbablePrime(certainty, random)) + if (CheckProbablePrime(certainty, random, true)) break; if (bitLength > 32) @@ -714,7 +714,7 @@ namespace Org.BouncyCastle.Math this.magnitude[this.magnitude.Length - 1] ^= ((random.Next() + 1) << 1); this.mQuote = 0; - if (CheckProbablePrime(certainty, random)) + if (CheckProbablePrime(certainty, random, true)) return; } } @@ -1340,8 +1340,12 @@ namespace Org.BouncyCastle.Math * probability of 1 - (1/2)**certainty. * <p>From Knuth Vol 2, pg 395.</p> */ - public bool IsProbablePrime( - int certainty) + public bool IsProbablePrime(int certainty) + { + return IsProbablePrime(certainty, false); + } + + internal bool IsProbablePrime(int certainty, bool randomlySelected) { if (certainty <= 0) return true; @@ -1354,12 +1358,10 @@ namespace Org.BouncyCastle.Math if (n.Equals(One)) return false; - return n.CheckProbablePrime(certainty, RandomSource); + return n.CheckProbablePrime(certainty, RandomSource, randomlySelected); } - private bool CheckProbablePrime( - int certainty, - Random random) + private bool CheckProbablePrime(int certainty, Random random, bool randomlySelected) { Debug.Assert(certainty > 0); Debug.Assert(CompareTo(Two) > 0); @@ -1395,7 +1397,7 @@ namespace Org.BouncyCastle.Math // TODO Is it worth trying to create a hybrid of these two? - return RabinMillerTest(certainty, random); + return RabinMillerTest(certainty, random, randomlySelected); // return SolovayStrassenTest(certainty, random); // bool rbTest = RabinMillerTest(certainty, random); @@ -1408,10 +1410,36 @@ namespace Org.BouncyCastle.Math public bool RabinMillerTest(int certainty, Random random) { + return RabinMillerTest(certainty, random, false); + } + + internal bool RabinMillerTest(int certainty, Random random, bool randomlySelected) + { + int bits = BitLength; + Debug.Assert(certainty > 0); - Debug.Assert(BitLength > 2); + Debug.Assert(bits > 2); Debug.Assert(TestBit(0)); + int iterations = ((certainty - 1) / 2) + 1; + if (randomlySelected) + { + int itersFor100Cert = bits >= 1024 ? 4 + : bits >= 512 ? 8 + : bits >= 256 ? 16 + : 50; + + if (certainty < 100) + { + iterations = System.Math.Min(itersFor100Cert, iterations); + } + else + { + iterations -= 50; + iterations += itersFor100Cert; + } + } + // let n = 1 + d . 2^s BigInteger n = this; int s = n.GetLowestSetBitMaskFirst(-1 << 1); @@ -1449,10 +1477,8 @@ namespace Org.BouncyCastle.Math return false; } } - - certainty -= 2; // composites pass for only 1/4 possible 'a' } - while (certainty > 0); + while (--iterations > 0); return true; } @@ -2494,7 +2520,7 @@ namespace Org.BouncyCastle.Math BigInteger n = Inc().SetBit(0); - while (!n.CheckProbablePrime(100, RandomSource)) + while (!n.CheckProbablePrime(100, RandomSource, false)) { n = n.Add(Two); } diff --git a/crypto/src/math/Primes.cs b/crypto/src/math/Primes.cs index 420c3cc5a..fb279f103 100644 --- a/crypto/src/math/Primes.cs +++ b/crypto/src/math/Primes.cs @@ -11,6 +11,8 @@ namespace Org.BouncyCastle.Math */ public abstract class Primes { + public static readonly int SmallFactorLimit = 211; + private static readonly BigInteger One = BigInteger.One; private static readonly BigInteger Two = BigInteger.Two; private static readonly BigInteger Three = BigInteger.Three; @@ -326,37 +328,80 @@ namespace Org.BouncyCastle.Math */ int m = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23; int r = x.Mod(BigInteger.ValueOf(m)).IntValue; - if ((r & 1) != 0 && (r % 3) != 0 && (r % 5) != 0 && (r % 7) != 0 && (r % 11) != 0 - && (r % 13) != 0 && (r % 17) != 0 && (r % 19) != 0 && (r % 23) != 0) + if ((r % 2) == 0 || (r % 3) == 0 || (r % 5) == 0 || (r % 7) == 0 || (r % 11) == 0 || (r % 13) == 0 + || (r % 17) == 0 || (r % 19) == 0 || (r % 23) == 0) { - m = 29 * 31 * 37 * 41 * 43; - r = x.Mod(BigInteger.ValueOf(m)).IntValue; - if ((r % 29) != 0 && (r % 31) != 0 && (r % 37) != 0 && (r % 41) != 0 && (r % 43) != 0) - { - m = 47 * 53 * 59 * 61 * 67; - r = x.Mod(BigInteger.ValueOf(m)).IntValue; - if ((r % 47) != 0 && (r % 53) != 0 && (r % 59) != 0 && (r % 61) != 0 && (r % 67) != 0) - { - m = 71 * 73 * 79 * 83; - r = x.Mod(BigInteger.ValueOf(m)).IntValue; - if ((r % 71) != 0 && (r % 73) != 0 && (r % 79) != 0 && (r % 83) != 0) - { - m = 89 * 97 * 101 * 103; - r = x.Mod(BigInteger.ValueOf(m)).IntValue; - if ((r % 89) != 0 && (r % 97) != 0 && (r % 101) != 0 && (r % 103) != 0) - { - m = 107 * 109 * 113 * 127; - r = x.Mod(BigInteger.ValueOf(m)).IntValue; - if ((r % 107) != 0 && (r % 109) != 0 && (r % 113) != 0 && (r % 127) != 0) - { - return false; - } - } - } - } - } + return true; } - return true; + + m = 29 * 31 * 37 * 41 * 43; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 29) == 0 || (r % 31) == 0 || (r % 37) == 0 || (r % 41) == 0 || (r % 43) == 0) + { + return true; + } + + m = 47 * 53 * 59 * 61 * 67; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 47) == 0 || (r % 53) == 0 || (r % 59) == 0 || (r % 61) == 0 || (r % 67) == 0) + { + return true; + } + + m = 71 * 73 * 79 * 83; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 71) == 0 || (r % 73) == 0 || (r % 79) == 0 || (r % 83) == 0) + { + return true; + } + + m = 89 * 97 * 101 * 103; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 89) == 0 || (r % 97) == 0 || (r % 101) == 0 || (r % 103) == 0) + { + return true; + } + + m = 107 * 109 * 113 * 127; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 107) == 0 || (r % 109) == 0 || (r % 113) == 0 || (r % 127) == 0) + { + return true; + } + + m = 131 * 137 * 139 * 149; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 131) == 0 || (r % 137) == 0 || (r % 139) == 0 || (r % 149) == 0) + { + return true; + } + + m = 151 * 157 * 163 * 167; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 151) == 0 || (r % 157) == 0 || (r % 163) == 0 || (r % 167) == 0) + { + return true; + } + + m = 173 * 179 * 181 * 191; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 173) == 0 || (r % 179) == 0 || (r % 181) == 0 || (r % 191) == 0) + { + return true; + } + + m = 193 * 197 * 199 * 211; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 193) == 0 || (r % 197) == 0 || (r % 199) == 0 || (r % 211) == 0) + { + return true; + } + + /* + * NOTE: Unit tests depend on SMALL_FACTOR_LIMIT matching the + * highest small factor tested here. + */ + return false; } private static bool ImplMRProbablePrimeToBase(BigInteger w, BigInteger wSubOne, BigInteger m, int a, BigInteger b) diff --git a/crypto/src/ocsp/BasicOCSPRespGenerator.cs b/crypto/src/ocsp/BasicOCSPRespGenerator.cs index 4ef73e09c..0dd4e0a09 100644 --- a/crypto/src/ocsp/BasicOCSPRespGenerator.cs +++ b/crypto/src/ocsp/BasicOCSPRespGenerator.cs @@ -217,7 +217,7 @@ namespace Org.BouncyCastle.Ocsp streamCalculator.Stream.Write(encoded, 0, encoded.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); bitSig = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect()); } diff --git a/crypto/src/openpgp/PgpCompressedDataGenerator.cs b/crypto/src/openpgp/PgpCompressedDataGenerator.cs index e3a889316..51b645279 100644 --- a/crypto/src/openpgp/PgpCompressedDataGenerator.cs +++ b/crypto/src/openpgp/PgpCompressedDataGenerator.cs @@ -2,6 +2,7 @@ using System; using System.IO; using Org.BouncyCastle.Apache.Bzip2; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Zlib; namespace Org.BouncyCastle.Bcpg.OpenPgp @@ -155,10 +156,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { if (dOut != pkOut) { - dOut.Dispose(); - dOut.Flush(); + Platform.Dispose(dOut); } - dOut = null; pkOut.Finish(); @@ -174,14 +173,22 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { } - protected override void Dispose(bool disposing) - { - if (disposing) - { - Finish(); - } - base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Finish(); + return; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Finish(); + } +#endif } private class SafeZOutputStream : ZOutputStream @@ -191,14 +198,24 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { } - protected override void Dispose(bool disposing) - { - if (disposing) - { - Finish(); - End(); - } - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Finish(); + End(); + return; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Finish(); + End(); + } +#endif } } } diff --git a/crypto/src/openpgp/PgpUtilities.cs b/crypto/src/openpgp/PgpUtilities.cs index fc85dac52..055f99636 100644 --- a/crypto/src/openpgp/PgpUtilities.cs +++ b/crypto/src/openpgp/PgpUtilities.cs @@ -382,8 +382,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp pOut.Write(buf, 0, len); } - pOut.Dispose(); - inputStream.Dispose(); + Platform.Dispose(pOut); + Platform.Dispose(inputStream); } #endif diff --git a/crypto/src/openpgp/WrappedGeneratorStream.cs b/crypto/src/openpgp/WrappedGeneratorStream.cs index 60a1fbb0b..5f4a4b045 100644 --- a/crypto/src/openpgp/WrappedGeneratorStream.cs +++ b/crypto/src/openpgp/WrappedGeneratorStream.cs @@ -17,13 +17,21 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp this.gen = gen; } - protected override void Dispose(bool disposing) - { - if (disposing) - { - gen.Close(); - } - // base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + gen.Close(); + return; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + gen.Close(); + } +#endif } } diff --git a/crypto/src/pkcs/Pkcs10CertificationRequest.cs b/crypto/src/pkcs/Pkcs10CertificationRequest.cs index 7fccf32eb..1789f2a70 100644 --- a/crypto/src/pkcs/Pkcs10CertificationRequest.cs +++ b/crypto/src/pkcs/Pkcs10CertificationRequest.cs @@ -279,7 +279,7 @@ namespace Org.BouncyCastle.Pkcs streamCalculator.Stream.Write(reqInfoData, 0, reqInfoData.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); // Generate Signature. sigBits = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect()); @@ -342,7 +342,7 @@ namespace Org.BouncyCastle.Pkcs streamCalculator.Stream.Write(b, 0, b.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); return ((IVerifier)streamCalculator.GetResult()).IsVerified(sigBits.GetBytes()); } diff --git a/crypto/src/pkix/PkixCertPath.cs b/crypto/src/pkix/PkixCertPath.cs index c8ed91bee..d03709167 100644 --- a/crypto/src/pkix/PkixCertPath.cs +++ b/crypto/src/pkix/PkixCertPath.cs @@ -401,7 +401,7 @@ namespace Org.BouncyCastle.Pkix pWrt.WriteObject(certificates[i]); } - pWrt.Writer.Dispose(); + Platform.Dispose(pWrt.Writer); } catch (Exception) { diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs index 1b5ba462e..d4b18f182 100644 --- a/crypto/src/util/Platform.cs +++ b/crypto/src/util/Platform.cs @@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Utilities MemoryStream buf = new MemoryStream(); StreamWriter w = new StreamWriter(buf, Encoding.UTF8); w.WriteLine(); - w.Close(); + Dispose(w); byte[] bs = buf.ToArray(); return Encoding.UTF8.GetString(bs, 0, bs.Length); } @@ -186,5 +186,21 @@ namespace Org.BouncyCastle.Utilities } internal static readonly string NewLine = GetNewLine(); + +#if PORTABLE + internal static void Dispose(IDisposable d) + { + d.Dispose(); + } +#else + internal static void Dispose(Stream s) + { + s.Close(); + } + internal static void Dispose(TextWriter t) + { + t.Close(); + } +#endif } } diff --git a/crypto/src/util/io/BaseInputStream.cs b/crypto/src/util/io/BaseInputStream.cs index 2407bbabe..a5613d801 100644 --- a/crypto/src/util/io/BaseInputStream.cs +++ b/crypto/src/util/io/BaseInputStream.cs @@ -11,15 +11,23 @@ namespace Org.BouncyCastle.Utilities.IO public sealed override bool CanRead { get { return !closed; } } public sealed override bool CanSeek { get { return false; } } public sealed override bool CanWrite { get { return false; } } - protected override void Dispose(bool disposing) + +#if PORTABLE + protected override void Dispose(bool disposing) { if (disposing) { closed = true; } - base.Dispose(disposing); } +#else + public override void Close() + { + closed = true; + base.Close(); + } +#endif public sealed override void Flush() {} public sealed override long Length { get { throw new NotSupportedException(); } } diff --git a/crypto/src/util/io/BaseOutputStream.cs b/crypto/src/util/io/BaseOutputStream.cs index 56ce847e0..a0608d111 100644 --- a/crypto/src/util/io/BaseOutputStream.cs +++ b/crypto/src/util/io/BaseOutputStream.cs @@ -11,6 +11,8 @@ namespace Org.BouncyCastle.Utilities.IO public sealed override bool CanRead { get { return false; } } public sealed override bool CanSeek { get { return false; } } public sealed override bool CanWrite { get { return !closed; } } + +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) @@ -19,7 +21,15 @@ namespace Org.BouncyCastle.Utilities.IO } base.Dispose(disposing); } - public override void Flush() {} +#else + public override void Close() + { + closed = true; + base.Close(); + } +#endif + + public override void Flush() { } public sealed override long Length { get { throw new NotSupportedException(); } } public sealed override long Position { diff --git a/crypto/src/util/io/FilterStream.cs b/crypto/src/util/io/FilterStream.cs index 1aa1f9889..a92dee3e5 100644 --- a/crypto/src/util/io/FilterStream.cs +++ b/crypto/src/util/io/FilterStream.cs @@ -29,14 +29,22 @@ namespace Org.BouncyCastle.Utilities.IO get { return s.Position; } set { s.Position = value; } } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - s.Dispose(); + Platform.Dispose(s); } base.Dispose(disposing); } +#else + public override void Close() + { + Platform.Dispose(s); + base.Close(); + } +#endif public override void Flush() { s.Flush(); diff --git a/crypto/src/util/io/TeeInputStream.cs b/crypto/src/util/io/TeeInputStream.cs index aeed3bae6..6996f3fbb 100644 --- a/crypto/src/util/io/TeeInputStream.cs +++ b/crypto/src/util/io/TeeInputStream.cs @@ -18,17 +18,26 @@ namespace Org.BouncyCastle.Utilities.IO this.tee = tee; } - protected override void Dispose(bool disposing) - { - if (disposing) - { - input.Dispose(); - tee.Dispose(); - } - base.Dispose(disposing); - } - - public override int Read(byte[] buf, int off, int len) +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(input); + Platform.Dispose(tee); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(input); + Platform.Dispose(tee); + base.Close(); + } +#endif + + public override int Read(byte[] buf, int off, int len) { int i = input.Read(buf, off, len); diff --git a/crypto/src/util/io/TeeOutputStream.cs b/crypto/src/util/io/TeeOutputStream.cs index cebca89fe..a6c7fd5b5 100644 --- a/crypto/src/util/io/TeeOutputStream.cs +++ b/crypto/src/util/io/TeeOutputStream.cs @@ -18,17 +18,26 @@ namespace Org.BouncyCastle.Utilities.IO this.tee = tee; } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - output.Dispose(); - tee.Dispose(); + Platform.Dispose(output); + Platform.Dispose(tee); } base.Dispose(disposing); } - - public override void Write(byte[] buffer, int offset, int count) +#else + public override void Close() + { + Platform.Dispose(output); + Platform.Dispose(tee); + base.Close(); + } +#endif + + public override void Write(byte[] buffer, int offset, int count) { output.Write(buffer, offset, count); tee.Write(buffer, offset, count); diff --git a/crypto/src/util/zlib/ZDeflaterOutputStream.cs b/crypto/src/util/zlib/ZDeflaterOutputStream.cs index 544ba8601..d0978942a 100644 --- a/crypto/src/util/zlib/ZDeflaterOutputStream.cs +++ b/crypto/src/util/zlib/ZDeflaterOutputStream.cs @@ -136,23 +136,36 @@ namespace Org.BouncyCastle.Utilities.Zlib { z=null; } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - try - { - try { Finish(); } - catch (IOException) { } + try{ + try{Finish();} + catch (IOException) {} } - finally - { + finally{ End(); - outp.Dispose(); - outp = null; + Platform.Dispose(outp); + outp=null; } } base.Dispose(disposing); } +#else + public override void Close() { + try{ + try{Finish();} + catch (IOException) {} + } + finally{ + End(); + Platform.Dispose(outp); + outp=null; + } + base.Close(); + } +#endif } } diff --git a/crypto/src/util/zlib/ZInflaterInputStream.cs b/crypto/src/util/zlib/ZInflaterInputStream.cs index 9e82954b9..ef742bb00 100644 --- a/crypto/src/util/zlib/ZInflaterInputStream.cs +++ b/crypto/src/util/zlib/ZInflaterInputStream.cs @@ -114,15 +114,23 @@ namespace Org.BouncyCastle.Utilities.Zlib { public override void WriteByte(byte b) { } +#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - inp.Dispose(); + Platform.Dispose(inp); } base.Dispose(disposing); } - +#else + public override void Close() + { + Platform.Dispose(inp); + base.Close(); + } +#endif + public override int ReadByte() { if(Read(buf1, 0, 1)<=0) return -1; diff --git a/crypto/src/util/zlib/ZInputStream.cs b/crypto/src/util/zlib/ZInputStream.cs index 671cf68b0..4b7351555 100644 --- a/crypto/src/util/zlib/ZInputStream.cs +++ b/crypto/src/util/zlib/ZInputStream.cs @@ -93,18 +93,30 @@ namespace Org.BouncyCastle.Utilities.Zlib public sealed override bool CanSeek { get { return false; } } public sealed override bool CanWrite { get { return false; } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (!closed) - { - closed = true; - input.Dispose(); - } - } - base.Dispose(disposing); - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (closed) + return; + + closed = true; + Platform.Dispose(input); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (closed) + return; + + closed = true; + Platform.Dispose(input); + base.Close(); + } +#endif public sealed override void Flush() {} diff --git a/crypto/src/util/zlib/ZOutputStream.cs b/crypto/src/util/zlib/ZOutputStream.cs index 2cef06397..d9f005f69 100644 --- a/crypto/src/util/zlib/ZOutputStream.cs +++ b/crypto/src/util/zlib/ZOutputStream.cs @@ -95,36 +95,52 @@ namespace Org.BouncyCastle.Utilities.Zlib public sealed override bool CanSeek { get { return false; } } public sealed override bool CanWrite { get { return !closed; } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (this.closed) - return; +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (closed) + return; + + DoClose(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (closed) + return; + + DoClose(); + base.Close(); + } +#endif + private void DoClose() + { + try + { try { - try - { - Finish(); - } - catch (IOException) - { - // Ignore - } + Finish(); } - finally + catch (IOException) { - this.closed = true; - End(); - output.Dispose(); - output = null; + // Ignore } - } - base.Dispose(disposing); - } - - public virtual void End() + } + finally + { + this.closed = true; + End(); + Platform.Dispose(output); + output = null; + } + } + + public virtual void End() { if (z == null) return; diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs index 93e3ee940..fc7f96aa9 100644 --- a/crypto/src/x509/X509Certificate.cs +++ b/crypto/src/x509/X509Certificate.cs @@ -576,7 +576,7 @@ namespace Org.BouncyCastle.X509 streamCalculator.Stream.Write(b, 0, b.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) { diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs index 8d5cec8ef..53de3e91f 100644 --- a/crypto/src/x509/X509Crl.cs +++ b/crypto/src/x509/X509Crl.cs @@ -115,7 +115,7 @@ namespace Org.BouncyCastle.X509 streamCalculator.Stream.Write(b, 0, b.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) { diff --git a/crypto/src/x509/X509V1CertificateGenerator.cs b/crypto/src/x509/X509V1CertificateGenerator.cs index 1c59acba4..9adebcb16 100644 --- a/crypto/src/x509/X509V1CertificateGenerator.cs +++ b/crypto/src/x509/X509V1CertificateGenerator.cs @@ -10,6 +10,7 @@ using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.X509 { @@ -184,7 +185,7 @@ namespace Org.BouncyCastle.X509 streamCalculator.Stream.Write(encoded, 0, encoded.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); } diff --git a/crypto/src/x509/X509V2AttributeCertificate.cs b/crypto/src/x509/X509V2AttributeCertificate.cs index bc9b39873..9376538a1 100644 --- a/crypto/src/x509/X509V2AttributeCertificate.cs +++ b/crypto/src/x509/X509V2AttributeCertificate.cs @@ -5,11 +5,11 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; -using Org.BouncyCastle.Crypto.Operators; namespace Org.BouncyCastle.X509 { @@ -186,7 +186,7 @@ namespace Org.BouncyCastle.X509 streamCalculator.Stream.Write(b, 0, b.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); } catch (IOException e) { diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs index fc7d91050..bf046cd1e 100644 --- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs +++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs @@ -1,15 +1,15 @@ using System; using System.Collections; +using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; -using Org.BouncyCastle.Crypto.Operators; -using System.IO; namespace Org.BouncyCastle.X509 { @@ -172,7 +172,7 @@ namespace Org.BouncyCastle.X509 streamCalculator.Stream.Write(encoded, 0, encoded.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); Asn1EncodableVector v = new Asn1EncodableVector(); diff --git a/crypto/src/x509/X509V2CRLGenerator.cs b/crypto/src/x509/X509V2CRLGenerator.cs index 93accee71..566d50234 100644 --- a/crypto/src/x509/X509V2CRLGenerator.cs +++ b/crypto/src/x509/X509V2CRLGenerator.cs @@ -5,12 +5,13 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; -using Org.BouncyCastle.Crypto.Operators; namespace Org.BouncyCastle.X509 { @@ -241,7 +242,7 @@ namespace Org.BouncyCastle.X509 streamCalculator.Stream.Write(encoded, 0, encoded.Length); - streamCalculator.Stream.Dispose(); + Platform.Dispose(streamCalculator.Stream); return GenerateJcaObject(tbsCertList, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); } diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs index 2830a19dc..bc619c37b 100644 --- a/crypto/src/x509/X509V3CertificateGenerator.cs +++ b/crypto/src/x509/X509V3CertificateGenerator.cs @@ -1,15 +1,14 @@ using System; using System.Collections; -using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Operators; -using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.X509.Extension; namespace Org.BouncyCastle.X509 @@ -318,11 +317,11 @@ namespace Org.BouncyCastle.X509 byte[] encoded = tbsCert.GetDerEncoded(); - streamCalculator.Stream.Write (encoded, 0, encoded.Length); + streamCalculator.Stream.Write(encoded, 0, encoded.Length); - streamCalculator.Stream.Dispose (); + Platform.Dispose(streamCalculator.Stream); - return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); + return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); } private X509Certificate GenerateJcaObject( diff --git a/crypto/test/src/asn1/test/GenerationTest.cs b/crypto/test/src/asn1/test/GenerationTest.cs index 534f76bfd..862e66d22 100644 --- a/crypto/test/src/asn1/test/GenerationTest.cs +++ b/crypto/test/src/asn1/test/GenerationTest.cs @@ -53,8 +53,8 @@ namespace Org.BouncyCastle.Asn1.Tests private void TbsV1CertGenerate() { V1TbsCertificateGenerator gen = new V1TbsCertificateGenerator(); - DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc); - DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 12, DateTimeKind.Utc); + DateTime startDate = MakeUtcDateTime(1970, 1, 1, 0, 0, 1); + DateTime endDate = MakeUtcDateTime(1970, 1, 1, 0, 0, 12); gen.SetSerialNumber(new DerInteger(1)); @@ -106,8 +106,8 @@ namespace Org.BouncyCastle.Asn1.Tests private void TbsV3CertGenerate() { V3TbsCertificateGenerator gen = new V3TbsCertificateGenerator(); - DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc); - DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 2, DateTimeKind.Utc); + DateTime startDate = MakeUtcDateTime(1970, 1, 1, 0, 0, 1); + DateTime endDate = MakeUtcDateTime(1970, 1, 1, 0, 0, 2); gen.SetSerialNumber(new DerInteger(2)); @@ -166,8 +166,8 @@ namespace Org.BouncyCastle.Asn1.Tests private void TbsV3CertGenWithNullSubject() { V3TbsCertificateGenerator gen = new V3TbsCertificateGenerator(); - DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc); - DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 2, DateTimeKind.Utc); + DateTime startDate = MakeUtcDateTime(1970, 1, 1, 0, 0, 1); + DateTime endDate = MakeUtcDateTime(1970, 1, 1, 0, 0, 2); gen.SetSerialNumber(new DerInteger(2)); @@ -243,11 +243,11 @@ namespace Org.BouncyCastle.Asn1.Tests gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle")); - gen.AddCrlEntry(new DerInteger(1), new Time(new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc)), ReasonFlags.AACompromise); + gen.AddCrlEntry(new DerInteger(1), new Time(MakeUtcDateTime(1970, 1, 1, 0, 0, 1)), ReasonFlags.AACompromise); - gen.SetNextUpdate(new Time(new DateTime(1970, 1, 1, 0, 0, 2, DateTimeKind.Utc))); + gen.SetNextUpdate(new Time(MakeUtcDateTime(1970, 1, 1, 0, 0, 2))); - gen.SetThisUpdate(new Time(new DateTime(1970, 1, 1, 0, 0, 0, 500, DateTimeKind.Utc))); + gen.SetThisUpdate(new Time(MakeUtcDateTime(1970, 1, 1, 0, 0, 0, 500))); gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.Sha1WithRsaEncryption, DerNull.Instance)); diff --git a/crypto/test/src/asn1/test/TimeTest.cs b/crypto/test/src/asn1/test/TimeTest.cs index 101a87935..04dac3c9e 100644 --- a/crypto/test/src/asn1/test/TimeTest.cs +++ b/crypto/test/src/asn1/test/TimeTest.cs @@ -15,9 +15,9 @@ namespace Org.BouncyCastle.Asn1.Tests DateTime now = DateTime.UtcNow; // Time classes only have a resolution of seconds - now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, DateTimeKind.Utc); + now = SimpleTest.MakeUtcDateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); - Org.BouncyCastle.Asn1.Cms.Time cmsTime = new Org.BouncyCastle.Asn1.Cms.Time(now); + Org.BouncyCastle.Asn1.Cms.Time cmsTime = new Org.BouncyCastle.Asn1.Cms.Time(now); Org.BouncyCastle.Asn1.X509.Time x509Time = new Org.BouncyCastle.Asn1.X509.Time(now); // Assert.AreEqual(cmsTime.Date, x509Time.ToDateTime()); diff --git a/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs b/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs index 23b3d9e07..0b3a203dd 100644 --- a/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs +++ b/crypto/test/src/math/ec/test/ECAlgorithmsTest.cs @@ -20,61 +20,85 @@ namespace Org.BouncyCastle.Math.EC.Tests private static readonly SecureRandom RND = new SecureRandom(); [Test] - [Ignore("SLOW! 44 sec")] public void TestSumOfMultiplies() { + X9ECParameters x9 = CustomNamedCurves.GetByName("secp256r1"); + Assert.NotNull(x9); + DoTestSumOfMultiplies(x9); + } + + [Test, Explicit] + public void TestSumOfMultipliesComplete() + { foreach (X9ECParameters x9 in GetTestCurves()) { - ECPoint[] points = new ECPoint[SCALE]; - BigInteger[] scalars = new BigInteger[SCALE]; - for (int i = 0; i < SCALE; ++i) - { - points[i] = GetRandomPoint(x9); - scalars[i] = GetRandomScalar(x9); - } - - ECPoint u = x9.Curve.Infinity; - for (int i = 0; i < SCALE; ++i) - { - u = u.Add(points[i].Multiply(scalars[i])); - - ECPoint v = ECAlgorithms.SumOfMultiplies(CopyPoints(points, i + 1), CopyScalars(scalars, i + 1)); - - ECPoint[] results = new ECPoint[] { u, v }; - x9.Curve.NormalizeAll(results); - - AssertPointsEqual("ECAlgorithms.SumOfMultiplies is incorrect", results[0], results[1]); - } + DoTestSumOfMultiplies(x9); } } [Test] - [Ignore("SLOW")] public void TestSumOfTwoMultiplies() { + X9ECParameters x9 = CustomNamedCurves.GetByName("secp256r1"); + Assert.NotNull(x9); + DoTestSumOfTwoMultiplies(x9); + } + + [Test, Explicit] + public void TestSumOfTwoMultipliesComplete() + { foreach (X9ECParameters x9 in GetTestCurves()) { - ECPoint p = GetRandomPoint(x9); - BigInteger a = GetRandomScalar(x9); + DoTestSumOfTwoMultiplies(x9); + } + } - for (int i = 0; i < SCALE; ++i) - { - ECPoint q = GetRandomPoint(x9); - BigInteger b = GetRandomScalar(x9); + private void DoTestSumOfMultiplies(X9ECParameters x9) + { + ECPoint[] points = new ECPoint[SCALE]; + BigInteger[] scalars = new BigInteger[SCALE]; + for (int i = 0; i < SCALE; ++i) + { + points[i] = GetRandomPoint(x9); + scalars[i] = GetRandomScalar(x9); + } + + ECPoint u = x9.Curve.Infinity; + for (int i = 0; i < SCALE; ++i) + { + u = u.Add(points[i].Multiply(scalars[i])); - ECPoint u = p.Multiply(a).Add(q.Multiply(b)); - ECPoint v = ECAlgorithms.ShamirsTrick(p, a, q, b); - ECPoint w = ECAlgorithms.SumOfTwoMultiplies(p, a, q, b); + ECPoint v = ECAlgorithms.SumOfMultiplies(CopyPoints(points, i + 1), CopyScalars(scalars, i + 1)); - ECPoint[] results = new ECPoint[] { u, v, w }; - x9.Curve.NormalizeAll(results); + ECPoint[] results = new ECPoint[] { u, v }; + x9.Curve.NormalizeAll(results); - AssertPointsEqual("ECAlgorithms.ShamirsTrick is incorrect", results[0], results[1]); - AssertPointsEqual("ECAlgorithms.SumOfTwoMultiplies is incorrect", results[0], results[2]); + AssertPointsEqual("ECAlgorithms.SumOfMultiplies is incorrect", results[0], results[1]); + } + } - p = q; - a = b; - } + private void DoTestSumOfTwoMultiplies(X9ECParameters x9) + { + ECPoint p = GetRandomPoint(x9); + BigInteger a = GetRandomScalar(x9); + + for (int i = 0; i < SCALE; ++i) + { + ECPoint q = GetRandomPoint(x9); + BigInteger b = GetRandomScalar(x9); + + ECPoint u = p.Multiply(a).Add(q.Multiply(b)); + ECPoint v = ECAlgorithms.ShamirsTrick(p, a, q, b); + ECPoint w = ECAlgorithms.SumOfTwoMultiplies(p, a, q, b); + + ECPoint[] results = new ECPoint[] { u, v, w }; + x9.Curve.NormalizeAll(results); + + AssertPointsEqual("ECAlgorithms.ShamirsTrick is incorrect", results[0], results[1]); + AssertPointsEqual("ECAlgorithms.SumOfTwoMultiplies is incorrect", results[0], results[2]); + + p = q; + a = b; } } @@ -110,9 +134,9 @@ namespace Org.BouncyCastle.Math.EC.Tests private IList GetTestCurves() { ArrayList x9s = new ArrayList(); - ArrayList names = new ArrayList(); - CollectionUtilities.AddRange(names, ECNamedCurveTable.Names); - CollectionUtilities.AddRange(names, CustomNamedCurves.Names); + ISet names = new HashSet(ECNamedCurveTable.Names); + names.AddAll(CustomNamedCurves.Names); + foreach (string name in names) { X9ECParameters x9 = ECNamedCurveTable.GetByName(name); diff --git a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs index fdfc491c8..2bcd5b502 100644 --- a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs +++ b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs @@ -173,7 +173,6 @@ namespace Org.BouncyCastle.Math.EC.Tests } [Test] - [Ignore("SLOW")] public void TestMultiply() { ArrayList nameList = new ArrayList(); diff --git a/crypto/test/src/math/test/AllTests.cs b/crypto/test/src/math/test/AllTests.cs index f0eac21ad..53feff954 100644 --- a/crypto/test/src/math/test/AllTests.cs +++ b/crypto/test/src/math/test/AllTests.cs @@ -20,6 +20,7 @@ namespace Org.BouncyCastle.Math.Tests { TestSuite suite = new TestSuite("Math tests"); suite.Add(new BigIntegerTest()); + suite.Add(new PrimesTest()); return suite; } } diff --git a/crypto/test/src/math/test/PrimesTest.cs b/crypto/test/src/math/test/PrimesTest.cs new file mode 100644 index 000000000..4456ef2c1 --- /dev/null +++ b/crypto/test/src/math/test/PrimesTest.cs @@ -0,0 +1,179 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Tests +{ + [TestFixture] + public class PrimesTest + { + private const int ITERATIONS = 10; + private const int PRIME_BITS = 256; + private const int PRIME_CERTAINTY = 100; + + private static readonly BigInteger Two = BigInteger.Two; + + private static readonly SecureRandom R = new SecureRandom(); + + [Test] + public void TestHasAnySmallFactors() + { + for (int iterations = 0; iterations < ITERATIONS; ++iterations) + { + BigInteger prime = RandomPrime(); + Assert.False(Primes.HasAnySmallFactors(prime)); + + // NOTE: Loop through ALL small values to be sure no small primes are missing + for (int smallFactor = 2; smallFactor <= Primes.SmallFactorLimit; ++smallFactor) + { + BigInteger nonPrimeWithSmallFactor = BigInteger.ValueOf(smallFactor).Multiply(prime); + Assert.True(Primes.HasAnySmallFactors(nonPrimeWithSmallFactor)); + } + } + } + + [Test] + public void TestEnhancedMRProbablePrime() + { + int mrIterations = (PRIME_CERTAINTY + 1) / 2; + for (int iterations = 0; iterations < ITERATIONS; ++iterations) + { + BigInteger prime = RandomPrime(); + Primes.MROutput mr = Primes.EnhancedMRProbablePrimeTest(prime, R, mrIterations); + Assert.False(mr.IsProvablyComposite); + Assert.False(mr.IsNotPrimePower); + Assert.Null(mr.Factor); + + BigInteger primePower = prime; + for (int i = 0; i <= (iterations % 8); ++i) + { + primePower = primePower.Multiply(prime); + } + + Primes.MROutput mr2 = Primes.EnhancedMRProbablePrimeTest(primePower, R, mrIterations); + Assert.True(mr2.IsProvablyComposite); + Assert.False(mr2.IsNotPrimePower); + Assert.AreEqual(mr2.Factor, prime); + + BigInteger nonPrimePower = RandomPrime().Multiply(prime); + Primes.MROutput mr3 = Primes.EnhancedMRProbablePrimeTest(nonPrimePower, R, mrIterations); + Assert.True(mr3.IsProvablyComposite); + Assert.True(mr3.IsNotPrimePower); + Assert.Null(mr.Factor); + } + } + + [Test] + public void TestMRProbablePrime() + { + int mrIterations = (PRIME_CERTAINTY + 1) / 2; + for (int iterations = 0; iterations < ITERATIONS; ++iterations) + { + BigInteger prime = RandomPrime(); + Assert.True(Primes.IsMRProbablePrime(prime, R, mrIterations)); + + BigInteger nonPrime = RandomPrime().Multiply(prime); + Assert.False(Primes.IsMRProbablePrime(nonPrime, R, mrIterations)); + } + } + + [Test] + public void TestMRProbablePrimeToBase() + { + int mrIterations = (PRIME_CERTAINTY + 1) / 2; + for (int iterations = 0; iterations < ITERATIONS; ++iterations) + { + BigInteger prime = RandomPrime(); + Assert.True(ReferenceIsMRProbablePrime(prime, mrIterations)); + + BigInteger nonPrime = RandomPrime().Multiply(prime); + Assert.False(ReferenceIsMRProbablePrime(nonPrime, mrIterations)); + } + } + + [Test] + public void TestSTRandomPrime() + { + IDigest[] digests = new IDigest[] { new Sha1Digest(), new Sha256Digest() }; + for (int digestIndex = 0; digestIndex < digests.Length; ++digestIndex) + { + int coincidenceCount = 0; + + IDigest digest = digests[digestIndex]; + for (int iterations = 0; iterations < ITERATIONS; ++iterations) + { + try + { + byte[] inputSeed = new byte[16]; + R.NextBytes(inputSeed); + + Primes.STOutput st = Primes.GenerateSTRandomPrime(digest, PRIME_BITS, inputSeed); + Assert.True(IsPrime(st.Prime)); + + Primes.STOutput st2 = Primes.GenerateSTRandomPrime(digest, PRIME_BITS, inputSeed); + Assert.AreEqual(st.Prime, st2.Prime); + Assert.AreEqual(st.PrimeGenCounter, st2.PrimeGenCounter); + Assert.True(Arrays.AreEqual(st.PrimeSeed, st2.PrimeSeed)); + + for (int i = 0; i < inputSeed.Length; ++i) + { + inputSeed[i] ^= 0xFF; + } + + Primes.STOutput st3 = Primes.GenerateSTRandomPrime(digest, PRIME_BITS, inputSeed); + Assert.True(!st.Prime.Equals(st3.Prime)); + Assert.False(Arrays.AreEqual(st.PrimeSeed, st3.PrimeSeed)); + + if (st.PrimeGenCounter == st3.PrimeGenCounter) + { + ++coincidenceCount; + } + } + catch (InvalidOperationException e) + { + if (e.Message.StartsWith("Too many iterations")) + { + --iterations; + continue; + } + + throw e; + } + } + + Assert.True(coincidenceCount * coincidenceCount < ITERATIONS); + } + } + + private static bool ReferenceIsMRProbablePrime(BigInteger x, int numBases) + { + BigInteger xSubTwo = x.Subtract(Two); + + for (int i = 0; i < numBases; ++i) + { + BigInteger b = BigIntegers.CreateRandomInRange(Two, xSubTwo, R); + if (!Primes.IsMRProbablePrimeToBase(x, b)) + { + return false; + } + } + + return true; + } + + private static bool IsPrime(BigInteger x) + { + return x.IsProbablePrime(PRIME_CERTAINTY); + } + + private static BigInteger RandomPrime() + { + return new BigInteger(PRIME_BITS, PRIME_CERTAINTY, R); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPRSATest.cs b/crypto/test/src/openpgp/test/PGPRSATest.cs index b56cdf67e..82b569bbb 100644 --- a/crypto/test/src/openpgp/test/PGPRSATest.cs +++ b/crypto/test/src/openpgp/test/PGPRSATest.cs @@ -985,7 +985,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests sGen.Generate().Encode(bcOut); - bcOut.Dispose(); + bcOut.Close(); // // verify generated signature diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs index 6c52ca8ba..5f38609cf 100644 --- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs +++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs @@ -647,39 +647,60 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests + "EQIABgUCOCpiHgAKCRDj8lhUEo8OeQ+QAKCbOTscyUnWHSrDo4fIy0MThEjhOgCe" + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); -// private static readonly byte[] pub6check = Base64.Decode("62O9"); + private static readonly byte[] pub6check = Base64.Decode("62O9"); // - // revoked sub key + // revoked master key // private static readonly byte[] pub7 = Base64.Decode( - "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" - + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" - + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" - + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" - + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" - + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" - + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" - + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" - + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" - + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" - + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" - + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" - + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" - + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" - + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" - + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" - + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" - + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" - + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" - + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" - + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" - + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" - + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" - + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" - + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); - -// private static readonly byte[] pub7check = Base64.Decode("f/YQ"); + "mQGiBFKQDEMRBACtcEzu15gGDrZKLuO2zgDJ9qFkweOxKyeO45LKIfUGBful" + + "lheoFHbsJIeNGjWbSOfWWtphTaSu9//BJt4xxg2pqVLYqzR+hEPpDy9kXxnZ" + + "LwwxjAP2TcOvuZKWe+JzoYQxDunOH4Zu9CPJhZhF3RNPw+tbv0jHfTV/chtb" + + "23Dj5wCg7eoM8bL9NYXacsAfkS//m+AB1MkD/jEZJqJSQHW8WVP7wKRrAZse" + + "N4l9b8+yY4RwLIodhD8wGsMYjkCF4yb/SQ5QlmLlvrHDLBofRzG+8oxldX4o" + + "GLZWvqPmW+BlS4QNSr+ZBu+OwnpClXG2pR+ExumXNoeArREyylrmOgD+0cUa" + + "8K2UbOxbJ8EioyOKxa7wjUVxmHmhBACAGQGLT/lpHA5zcU0g8AlSk8fsd+bB" + + "nwa/+9xdLqVsCTZdOWULtPOw9hbAdjjAy0L4M/MDAJYYtCEl9rB7aOc9PVdT" + + "h7CT9Ma6ltiSMKDlqWbDmogNEGx9Gz3GjiSGxAy/SN6JR1On4c60TAiTv6eE" + + "uEHszE6CH4qceK5W8HLLB4hJBCARAgAJBQJSkA0OAh0CAAoJEBCIvJhXZzdI" + + "X8wAn0qUP/jqAuPEX9g2XCr5jN3RKvKjAKDpx4NP7P1/yLN2ycFIgxKZ1plK" + + "CLACAAO0J3Jldm9rZSAoUmV2b2tlIFRlc3QpIDxyZXZva2VAdGVzdC50ZXN0" + + "PohiBBMRAgAiBQJSkAxDAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK" + + "CRAQiLyYV2c3SKw0AJ9kufxvnorVOv6a+WM+I/bNP+mjLQCgtPKuwTyeZU2k" + + "Sec1fJZUssDL1hGwAgADuQENBFKQDEMQBACruJ54GuhUaXgqGzu/HsCrgGQA" + + "n86PZW1qPCX28E9sayEmVOgzSDA/OT5c05P0PVLhMNEguSnUGC249MpZfPK/" + + "9LVKMXATZLzEB6lFX1YJdfrrb9KrQ5kdDhOcFXm1GIGBwLzjUmXYRVPH+TsT" + + "4QFvDpfIANQZfKK4UV5BJzJV5wADBQP/ew75dy1x58KWpPqfeH1OVln/Ui6e" + + "EDyyISic147+FIfVDuLtWoxMFE0ZPg47+rEQrhWC96izaSKPW97y5bkWz5PG" + + "CMChnLcg+3M91x/QCGzNhzVMiVpY5VhBDFP+7iiOaKYRiN/x7oasf2482Ny8" + + "1oiykOZUm8FCUQnRmJzIlbiISQQYEQIACQUCUpAMQwIbDAAKCRAQiLyYV2c3" + + "SL04AJ9VceD1DtcEDaWPDzFPgpe3ZfiXiQCfe5azYl26JpHSJvNKZRLi0I8H" + + "shCwAgAD"); + + private static readonly byte[] pub7sub = Base64.Decode( + "mQGiBFKQFFURBAD7CTE4RYPD7O+ki7pl/vXSZsSR0kQhCD9BR4lwE/Iffzmr" + + "vK8tmr2yLKWoXyoc3VF0Gdg/VATDcawBnKSjuCIsFZ58Edacb7uVRl4+ACiu" + + "OsvCKl9JuZ54SQ/tbD+NFS+HWNyVlWn7vDv8l+37DWNxuQRIYtQR+drAnIwQ" + + "g0O4owCg5a9cGAaN0zNVssUo6GFEoAI8nE0EAJMxQMcHTlLQQN1c549Ub0+E" + + "LV4dRIxjO7O6yi6Bg5udwS9Un1XeHF4GM7fj95WHi7o9sgErr2evhuGWl337" + + "ySytE1npk2F/jqevhAJazQTuilEuyjMbCShV39qJlEKtU9uHQYxN8oqGT9Ot" + + "lOoXXtrgfHbsrouCVwm4Jk14kzCaA/4okwrQwGkPlXRpVFyLn4GwrGivG7eh" + + "enRbAd2SQBiNVKmMsKLxHT1avZ11qcx6OU3ixdw5wYmq7TNR+5FXiz/e2MIq" + + "m7VhKONN21F7WC7siHxXfqqI/uz2tTPrFoLbnr/j/RZZRUMh6qUQrWpv58ci" + + "Bh+xkWCRantLCL9khuvRSrQncmV2b2tlIChSZXZva2UgVGVzdCkgPHJldm9r" + + "ZUB0ZXN0LnRlc3Q+iGIEExECACIFAlKQFFUCGwMGCwkIBwMCBhUIAgkKCwQW" + + "AgMBAh4BAheAAAoJEDKzvtpHqpp2DN4AoNS9M634KdvZT25DclGpb2bCFjv0" + + "AKDYXl5fIRGi583vFJ9C/q8hNGyNc7ACAAO5AQ0EUpAUVRAEALusV5UIL4gB" + + "6qQk++h+czV9KS0yxwgZyR+dJza+duEG88aNv28Wmjpfr3ZkvIiUaOcxFoct" + + "LgVGtPJM1HhWJtoA94CRBFTGzLfUIfXHcyXSdAw8Qh96svRl2w2KM+/pJl1r" + + "A3CWIy48jQei0mLwElRELLG7HJKYJxjCbg4+ihYTAAMGA/42PgHTV5VpF7YC" + + "XodlLOyGDVOoRjsvu0Gu/P88QnVP2jN57MJcla224aN3pGprtcbTwyjt+dtf" + + "5IJlB+3RZLczyqvT5hw7j9h81mr3RDbg3cn57xdYwQNP+6b6Wf9QRmaE813s" + + "g3kF0IJ0oFvwZdHnjndQ0JCrKaPflGSO6msjIYhTBCgRAgATBQJSkBXdDB0B" + + "U3VwZXJzZWRlZAAKCRAys77aR6qadmZPAJ0eJzmgBLTWK9RIbVtRUFzm736I" + + "hACgsPGHdZmLUFhV80fvYnUtB7TYGeKwAgADiEkEGBECAAkFAlKQFFUCGwwA" + + "CgkQMrO+2keqmnZGIACfRTkdqi6b7fjqkWxx7DysKBedgS8An1TJrhhkeJVd" + + "smkOCYLILgjrBHq4sAIAAw=="); private static readonly byte[] pub8 = Base64.Decode( "mQGiBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" @@ -1646,8 +1667,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests byte[] encRing = pubRings.GetEncoded(); } - [Test, Explicit] - public void PerformTest7() + [Test] + public void TestRevocation() { PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(pub7); PgpPublicKey masterKey = null; @@ -1657,28 +1678,64 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests if (k.IsMasterKey) { masterKey = k; + } + } + + int count = 0; + PgpSignature sig = null; + foreach (PgpSignature pgpSig in masterKey.GetSignaturesOfType(PgpSignature.KeyRevocation)) + { + sig = pgpSig; + ++count; + } + + if (count != 1) + { + Fail("wrong number of revocations in test7."); + } + + sig.InitVerify(masterKey); + + if (!sig.VerifyCertification(masterKey)) + { + Fail("failed to verify revocation certification"); + } + + pgpPub = new PgpPublicKeyRing(pub7sub); + masterKey = null; + + foreach (PgpPublicKey k in pgpPub.GetPublicKeys()) + { + if (k.IsMasterKey) + { + masterKey = k; continue; } - int count = 0; - PgpSignature sig = null; + count = 0; + sig = null; - foreach (PgpSignature sigTemp in k.GetSignaturesOfType(PgpSignature.SubkeyRevocation)) + foreach (PgpSignature pgpSig in k.GetSignaturesOfType(PgpSignature.SubkeyRevocation)) { - sig = sigTemp; - count++; + sig = pgpSig; + ++count; } if (count != 1) { - Fail("wrong number of revocations in test7."); + Fail("wrong number of revocations in test7 subkey."); + } + + if (sig.SignatureType != PgpSignature.SubkeyRevocation) + { + Fail("wrong signature found"); } sig.InitVerify(masterKey); - if (!sig.VerifyCertification(k)) + if (!sig.VerifyCertification(masterKey, k)) { - Fail("failed to verify revocation certification"); + Fail("failed to verify revocation certification of subkey"); } } } @@ -2264,10 +2321,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests PerformTest4(); PerformTest5(); PerformTest6(); - - // NB: This was commented out in the original Java source - //PerformTest7(); - + TestRevocation(); PerformTest8(); PerformTest9(); PerformTest10(); diff --git a/crypto/test/src/util/test/SimpleTest.cs b/crypto/test/src/util/test/SimpleTest.cs index 10c83374d..d759674ea 100644 --- a/crypto/test/src/util/test/SimpleTest.cs +++ b/crypto/test/src/util/test/SimpleTest.cs @@ -160,5 +160,23 @@ namespace Org.BouncyCastle.Utilities.Test internal static readonly string NewLine = GetNewLine(); public abstract void PerformTest(); + + public static DateTime MakeUtcDateTime(int year, int month, int day, int hour, int minute, int second) + { +#if PORTABLE + return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc); +#else + return new DateTime(year, month, day, hour, minute, second); +#endif + } + + public static DateTime MakeUtcDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) + { +#if PORTABLE + return new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Utc); +#else + return new DateTime(year, month, day, hour, minute, second, millisecond); +#endif + } } } diff --git a/crypto/test/src/util/test/UncloseableStream.cs b/crypto/test/src/util/test/UncloseableStream.cs index 160d61795..2a3b4229b 100644 --- a/crypto/test/src/util/test/UncloseableStream.cs +++ b/crypto/test/src/util/test/UncloseableStream.cs @@ -14,9 +14,21 @@ namespace Org.BouncyCastle.Utilities.Test { } - //public override void Close() - //{ - // throw new Exception("Close() called on UncloseableStream"); - //} - } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + throw new Exception("UncloseableStream was disposed"); + } + + base.Dispose(disposing); + } +#else + public override void Close() + { + throw new Exception("Close() called on UncloseableStream"); + } +#endif + } } |