From b6f454e34926a30f7e52b14aef4e923ace28489e Mon Sep 17 00:00:00 2001 From: Sebastien Pouliot Date: Fri, 17 May 2013 11:28:30 -0400 Subject: [PATCH] Remove duplicate files (cvs-time artefact) --- .../corlib/Mono.Math.Prime.Generator/ChangeLog | 35 - .../Mono.Math.Prime.Generator/NextPrimeFinder.cs | 55 - .../PrimeGeneratorBase.cs | 75 - .../SequentialSearchPrimeGeneratorBase.cs | 120 - mcs/class/corlib/Mono.Math.Prime/ChangeLog | 24 - .../corlib/Mono.Math.Prime/ConfidenceFactor.cs | 68 - mcs/class/corlib/Mono.Math.Prime/PrimalityTests.cs | 218 -- mcs/class/corlib/Mono.Math/BigInteger.cs | 2372 -------------------- mcs/class/corlib/Mono.Math/ChangeLog | 78 - .../Mono.Security.Authenticode/AuthenticodeBase.cs | 281 --- .../AuthenticodeDeformatter.cs | 456 ---- .../corlib/Mono.Security.Authenticode/ChangeLog | 72 - .../Mono.Security.Cryptography/CryptoConvert.cs | 754 ------- .../Mono.Security.Cryptography/CryptoTools.cs | 143 -- .../KeyPairPersistence.cs | 454 ---- .../corlib/Mono.Security.Cryptography/PKCS1.cs | 416 ---- .../corlib/Mono.Security.Cryptography/PKCS8.cs | 500 ----- .../Mono.Security.Cryptography/RSAManaged.cs | 506 ----- .../SymmetricTransform.cs | 491 ---- .../BasicConstraintsExtension.cs | 139 -- .../corlib/Mono.Security.X509.Extensions/ChangeLog | 13 - .../KeyUsageExtension.cs | 197 -- .../SubjectKeyIdentifierExtension.cs | 108 - mcs/class/corlib/Mono.Security.X509/ChangeLog | 174 -- .../corlib/Mono.Security.X509/ITrustAnchors.cs | 46 - mcs/class/corlib/Mono.Security.X509/PKCS12.cs | 1972 ---------------- mcs/class/corlib/Mono.Security.X509/TestAnchors.cs | 137 -- .../corlib/Mono.Security.X509/TrustAnchors.cs | 381 ---- mcs/class/corlib/Mono.Security.X509/X501Name.cs | 400 ---- mcs/class/corlib/Mono.Security.X509/X509CRL.cs | 424 ---- .../corlib/Mono.Security.X509/X509Certificate.cs | 583 ----- .../X509CertificateCollection.cs | 207 -- mcs/class/corlib/Mono.Security.X509/X509Chain.cs | 285 --- .../Mono.Security.X509/X509ChainStatusFlags.cs | 72 - .../corlib/Mono.Security.X509/X509Extension.cs | 214 -- .../corlib/Mono.Security.X509/X509Extensions.cs | 203 -- mcs/class/corlib/Mono.Security.X509/X509Store.cs | 355 --- .../corlib/Mono.Security.X509/X509StoreManager.cs | 146 -- mcs/class/corlib/Mono.Security.X509/X509Stores.cs | 158 -- .../corlib/Mono.Security.X509/X520Attributes.cs | 353 --- mcs/class/corlib/Mono.Security/ASN1.cs | 343 --- mcs/class/corlib/Mono.Security/ASN1Convert.cs | 212 -- mcs/class/corlib/Mono.Security/BitConverterLE.cs | 241 -- mcs/class/corlib/Mono.Security/ChangeLog | 194 -- mcs/class/corlib/Mono.Security/PKCS7.cs | 976 -------- mcs/class/corlib/Mono.Security/StrongName.cs | 546 ----- 46 files changed, 16197 deletions(-) delete mode 100644 mcs/class/corlib/Mono.Math.Prime.Generator/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Math.Prime.Generator/NextPrimeFinder.cs delete mode 100644 mcs/class/corlib/Mono.Math.Prime.Generator/PrimeGeneratorBase.cs delete mode 100644 mcs/class/corlib/Mono.Math.Prime.Generator/SequentialSearchPrimeGeneratorBase.cs delete mode 100644 mcs/class/corlib/Mono.Math.Prime/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Math.Prime/ConfidenceFactor.cs delete mode 100644 mcs/class/corlib/Mono.Math.Prime/PrimalityTests.cs delete mode 100644 mcs/class/corlib/Mono.Math/BigInteger.cs delete mode 100644 mcs/class/corlib/Mono.Math/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeBase.cs delete mode 100644 mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeDeformatter.cs delete mode 100644 mcs/class/corlib/Mono.Security.Authenticode/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/CryptoConvert.cs delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/CryptoTools.cs delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/KeyPairPersistence.cs delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/PKCS8.cs delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/RSAManaged.cs delete mode 100644 mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509.Extensions/BasicConstraintsExtension.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509.Extensions/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Security.X509.Extensions/KeyUsageExtension.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509.Extensions/SubjectKeyIdentifierExtension.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Security.X509/ITrustAnchors.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/PKCS12.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/TestAnchors.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/TrustAnchors.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X501Name.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509CRL.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509Certificate.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509CertificateCollection.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509Chain.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509ChainStatusFlags.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509Extension.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509Extensions.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509Store.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509StoreManager.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X509Stores.cs delete mode 100644 mcs/class/corlib/Mono.Security.X509/X520Attributes.cs delete mode 100644 mcs/class/corlib/Mono.Security/ASN1.cs delete mode 100644 mcs/class/corlib/Mono.Security/ASN1Convert.cs delete mode 100644 mcs/class/corlib/Mono.Security/BitConverterLE.cs delete mode 100644 mcs/class/corlib/Mono.Security/ChangeLog delete mode 100644 mcs/class/corlib/Mono.Security/PKCS7.cs delete mode 100644 mcs/class/corlib/Mono.Security/StrongName.cs diff --git a/mcs/class/corlib/Mono.Math.Prime.Generator/ChangeLog b/mcs/class/corlib/Mono.Math.Prime.Generator/ChangeLog deleted file mode 100644 index 885c6e72c3e..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime.Generator/ChangeLog +++ /dev/null @@ -1,35 +0,0 @@ -2007-09-12 Sebastien Pouliot - - * NextPrimeFinder.cs, PrimeGeneratorBase.cs: Updated to match - Mono.Security sources. - -2004-09-16 Sebastien Pouliot - - * SequentialSearchPrimeGeneratorBase.cs: Fixed warning (l4) for unused - variables. - -2004-05-07 Sebastien Pouliot - - * SequentialSearchPrimeGeneratorBase.cs: In sync with - Mono.Security.dll version. - -2004-04-28 Sebastien Pouliot - - * NextPrimeFinder.cs: In sync with Mono.Security.dll version. - * PrimeGeneratorBase.cs: In sync with Mono.Security.dll version. - * SequentialSearchPrimeGeneratorBase.cs: In sync with - Mono.Security.dll version. - -2004-02-13 Sebastien Pouliot - - * PrimeGeneratorBase.cs: Changed primality test to Rabin Miller to - fix issues #51229 (bug), #54262 (very long in same cases). - -2003-04-22 Sebastien Pouliot - - * NextPrimeFinder.cs: New. Prime Generator. - Support class for BigInteger (commited for Ben Maurer). - * PrimeGeneratorBase.cs: New. Abstract Prime Generator. - Support class for BigInteger (commited for Ben Maurer). - * SequentialSearchPrimeGeneratorBase.cs: New. Prime Generator. - Support class for BigInteger (commited for Ben Maurer). diff --git a/mcs/class/corlib/Mono.Math.Prime.Generator/NextPrimeFinder.cs b/mcs/class/corlib/Mono.Math.Prime.Generator/NextPrimeFinder.cs deleted file mode 100644 index 5c31bac4a8b..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime.Generator/NextPrimeFinder.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Mono.Math.Prime.Generator.NextPrimeFinder.cs - Prime Generator -// -// Authors: -// Ben Maurer -// -// Copyright (c) 2003 Ben Maurer. All rights reserved -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Math.Prime.Generator { - - /// - /// Finds the next prime after a given number. - /// -#if INSIDE_CORLIB - internal -#else - public -#endif - class NextPrimeFinder : SequentialSearchPrimeGeneratorBase { - - protected override BigInteger GenerateSearchBase (int bits, object Context) - { - if (Context == null) - throw new ArgumentNullException ("Context"); - - BigInteger ret = new BigInteger ((BigInteger)Context); - ret.SetBit (0); - return ret; - } - } -} diff --git a/mcs/class/corlib/Mono.Math.Prime.Generator/PrimeGeneratorBase.cs b/mcs/class/corlib/Mono.Math.Prime.Generator/PrimeGeneratorBase.cs deleted file mode 100644 index 51f7a122622..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime.Generator/PrimeGeneratorBase.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// Mono.Math.Prime.Generator.PrimeGeneratorBase.cs - Abstract Prime Generator -// -// Authors: -// Ben Maurer -// -// Copyright (c) 2003 Ben Maurer. All rights reserved -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Math.Prime.Generator { - -#if INSIDE_CORLIB - internal -#else - public -#endif - abstract class PrimeGeneratorBase { - - public virtual ConfidenceFactor Confidence { - get { -#if DEBUG - return ConfidenceFactor.ExtraLow; -#else - return ConfidenceFactor.Medium; -#endif - } - } - - public virtual Prime.PrimalityTest PrimalityTest { - get { - return new Prime.PrimalityTest (PrimalityTests.RabinMillerTest); - } - } - - public virtual int TrialDivisionBounds { - get { return 4000; } - } - - /// - /// Performs primality tests on bi, assumes trial division has been done. - /// - /// A BigInteger that has been subjected to and passed trial division - /// False if bi is composite, true if it may be prime. - /// The speed of this method is dependent on Confidence - protected bool PostTrialDivisionTests (BigInteger bi) - { - return PrimalityTest (bi, this.Confidence); - } - - public abstract BigInteger GenerateNewPrime (int bits); - } -} diff --git a/mcs/class/corlib/Mono.Math.Prime.Generator/SequentialSearchPrimeGeneratorBase.cs b/mcs/class/corlib/Mono.Math.Prime.Generator/SequentialSearchPrimeGeneratorBase.cs deleted file mode 100644 index 87388d0011c..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime.Generator/SequentialSearchPrimeGeneratorBase.cs +++ /dev/null @@ -1,120 +0,0 @@ -// -// Mono.Math.Prime.Generator.SequentialSearchPrimeGeneratorBase.cs - Prime Generator -// -// Authors: -// Ben Maurer -// -// Copyright (c) 2003 Ben Maurer. All rights reserved -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Math.Prime.Generator { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class SequentialSearchPrimeGeneratorBase : PrimeGeneratorBase { - - protected virtual BigInteger GenerateSearchBase (int bits, object context) - { - BigInteger ret = BigInteger.GenerateRandom (bits); - ret.SetBit (0); - return ret; - } - - - public override BigInteger GenerateNewPrime (int bits) - { - return GenerateNewPrime (bits, null); - } - - - public virtual BigInteger GenerateNewPrime (int bits, object context) - { - // - // STEP 1. Find a place to do a sequential search - // - BigInteger curVal = GenerateSearchBase (bits, context); - - const uint primeProd1 = 3u* 5u * 7u * 11u * 13u * 17u * 19u * 23u * 29u; - - uint pMod1 = curVal % primeProd1; - - int DivisionBound = TrialDivisionBounds; - uint[] SmallPrimes = BigInteger.smallPrimes; - // - // STEP 2. Search for primes - // - while (true) { - - // - // STEP 2.1 Sieve out numbers divisible by the first 9 primes - // - if (pMod1 % 3 == 0) goto biNotPrime; - if (pMod1 % 5 == 0) goto biNotPrime; - if (pMod1 % 7 == 0) goto biNotPrime; - if (pMod1 % 11 == 0) goto biNotPrime; - if (pMod1 % 13 == 0) goto biNotPrime; - if (pMod1 % 17 == 0) goto biNotPrime; - if (pMod1 % 19 == 0) goto biNotPrime; - if (pMod1 % 23 == 0) goto biNotPrime; - if (pMod1 % 29 == 0) goto biNotPrime; - - // - // STEP 2.2 Sieve out all numbers divisible by the primes <= DivisionBound - // - for (int p = 10; p < SmallPrimes.Length && SmallPrimes [p] <= DivisionBound; p++) { - if (curVal % SmallPrimes [p] == 0) - goto biNotPrime; - } - - // - // STEP 2.3 Is the potential prime acceptable? - // - if (!IsPrimeAcceptable (curVal, context)) - goto biNotPrime; - - // - // STEP 2.4 Filter out all primes that pass this step with a primality test - // - if (PrimalityTest (curVal, Confidence)) - return curVal; - - // - // STEP 2.4 - // - biNotPrime: - pMod1 += 2; - if (pMod1 >= primeProd1) - pMod1 -= primeProd1; - curVal.Incr2 (); - } - } - - protected virtual bool IsPrimeAcceptable (BigInteger bi, object context) - { - return true; - } - } -} diff --git a/mcs/class/corlib/Mono.Math.Prime/ChangeLog b/mcs/class/corlib/Mono.Math.Prime/ChangeLog deleted file mode 100644 index dce33843a7e..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime/ChangeLog +++ /dev/null @@ -1,24 +0,0 @@ -2007-09-12 Sebastien Pouliot - - * ConfidenceFactor.cs, PrimalityTests.cs: Updated to match - Mono.Security sources. - -2004-05-07 Sebastien Pouliot - - * PrimalityTests.cs: In sync with Mono.Security.dll version. - -2004-04-28 Sebastien Pouliot - - * PrimalityTests.cs: In sync with Mono.Security.dll version. - -2003-04-23 Alp Toker - - * PrimalityTests.cs: Mark PrimalityTest as non-CLS-compliant (build fix) - -2003-04-22 Sebastien Pouliot - - * ConfidenceFactor.cs: New. Enum for prime quality. - Support for BigInteger (commited for Ben Maurer). - * PrimalityTests.cs: New. Tests for primality. - Support for BigInteger (commited for Ben Maurer). - diff --git a/mcs/class/corlib/Mono.Math.Prime/ConfidenceFactor.cs b/mcs/class/corlib/Mono.Math.Prime/ConfidenceFactor.cs deleted file mode 100644 index 00cbac5cc67..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime/ConfidenceFactor.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Mono.Math.Prime.ConfidenceFactor.cs - Confidence factor for prime generation -// -// Authors: -// Ben Maurer -// -// Copyright (c) 2003 Ben Maurer. All rights reserved -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Math.Prime { - /// - /// A factor of confidence. - /// -#if INSIDE_CORLIB - internal -#else - public -#endif - enum ConfidenceFactor { - /// - /// Only suitable for development use, probability of failure may be greater than 1/2^20. - /// - ExtraLow, - /// - /// Suitable only for transactions which do not require forward secrecy. Probability of failure about 1/2^40 - /// - Low, - /// - /// Designed for production use. Probability of failure about 1/2^80. - /// - Medium, - /// - /// Suitable for sensitive data. Probability of failure about 1/2^160. - /// - High, - /// - /// Use only if you have lots of time! Probability of failure about 1/2^320. - /// - ExtraHigh, - /// - /// Only use methods which generate provable primes. Not yet implemented. - /// - Provable - } -} diff --git a/mcs/class/corlib/Mono.Math.Prime/PrimalityTests.cs b/mcs/class/corlib/Mono.Math.Prime/PrimalityTests.cs deleted file mode 100644 index cd3953e9955..00000000000 --- a/mcs/class/corlib/Mono.Math.Prime/PrimalityTests.cs +++ /dev/null @@ -1,218 +0,0 @@ -// -// Mono.Math.Prime.PrimalityTests.cs - Test for primality -// -// Authors: -// Ben Maurer -// -// Copyright (c) 2003 Ben Maurer. All rights reserved -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Math.Prime { - -#if INSIDE_CORLIB - internal -#else - public -#endif - delegate bool PrimalityTest (BigInteger bi, ConfidenceFactor confidence); - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class PrimalityTests { - - private PrimalityTests () - { - } - - #region SPP Test - - private static int GetSPPRounds (BigInteger bi, ConfidenceFactor confidence) - { - int bc = bi.BitCount(); - - int Rounds; - - // Data from HAC, 4.49 - if (bc <= 100 ) Rounds = 27; - else if (bc <= 150 ) Rounds = 18; - else if (bc <= 200 ) Rounds = 15; - else if (bc <= 250 ) Rounds = 12; - else if (bc <= 300 ) Rounds = 9; - else if (bc <= 350 ) Rounds = 8; - else if (bc <= 400 ) Rounds = 7; - else if (bc <= 500 ) Rounds = 6; - else if (bc <= 600 ) Rounds = 5; - else if (bc <= 800 ) Rounds = 4; - else if (bc <= 1250) Rounds = 3; - else Rounds = 2; - - switch (confidence) { - case ConfidenceFactor.ExtraLow: - Rounds >>= 2; - return Rounds != 0 ? Rounds : 1; - case ConfidenceFactor.Low: - Rounds >>= 1; - return Rounds != 0 ? Rounds : 1; - case ConfidenceFactor.Medium: - return Rounds; - case ConfidenceFactor.High: - return Rounds << 1; - case ConfidenceFactor.ExtraHigh: - return Rounds << 2; - case ConfidenceFactor.Provable: - throw new Exception ("The Rabin-Miller test can not be executed in a way such that its results are provable"); - default: - throw new ArgumentOutOfRangeException ("confidence"); - } - } - - public static bool Test (BigInteger n, ConfidenceFactor confidence) - { - // Rabin-Miller fails with smaller primes (at least with our BigInteger code) - if (n.BitCount () < 33) - return SmallPrimeSppTest (n, confidence); - else - return RabinMillerTest (n, confidence); - } - - /// - /// Probabilistic prime test based on Rabin-Miller's test - /// - /// - /// - /// The number to test. - /// - /// - /// - /// - /// The number of chosen bases. The test has at least a - /// 1/4^confidence chance of falsely returning True. - /// - /// - /// - /// - /// True if "this" is a strong pseudoprime to randomly chosen bases. - /// - /// - /// False if "this" is definitely NOT prime. - /// - /// - public static bool RabinMillerTest (BigInteger n, ConfidenceFactor confidence) - { - int bits = n.BitCount (); - int t = GetSPPRounds (bits, confidence); - - // n - 1 == 2^s * r, r is odd - BigInteger n_minus_1 = n - 1; - int s = n_minus_1.LowestSetBit (); - BigInteger r = n_minus_1 >> s; - - BigInteger.ModulusRing mr = new BigInteger.ModulusRing (n); - - // Applying optimization from HAC section 4.50 (base == 2) - // not a really random base but an interesting (and speedy) one - BigInteger y = null; - // FIXME - optimization disable for small primes due to bug #81857 - if (n.BitCount () > 100) - y = mr.Pow (2, r); - - // still here ? start at round 1 (round 0 was a == 2) - for (int round = 0; round < t; round++) { - - if ((round > 0) || (y == null)) { - BigInteger a = null; - - // check for 2 <= a <= n - 2 - // ...but we already did a == 2 previously as an optimization - do { - a = BigInteger.GenerateRandom (bits); - } while ((a <= 2) && (a >= n_minus_1)); - - y = mr.Pow (a, r); - } - - if (y == 1) - continue; - - for (int j = 0; ((j < s) && (y != n_minus_1)); j++) { - - y = mr.Pow (y, 2); - if (y == 1) - return false; - } - - if (y != n_minus_1) - return false; - } - return true; - } - - public static bool SmallPrimeSppTest (BigInteger bi, ConfidenceFactor confidence) - { - int Rounds = GetSPPRounds (bi, confidence); - - // calculate values of s and t - BigInteger p_sub1 = bi - 1; - int s = p_sub1.LowestSetBit (); - - BigInteger t = p_sub1 >> s; - - - BigInteger.ModulusRing mr = new BigInteger.ModulusRing (bi); - - for (int round = 0; round < Rounds; round++) { - - BigInteger b = mr.Pow (BigInteger.smallPrimes [round], t); - - if (b == 1) continue; // a^t mod p = 1 - - bool result = false; - for (int j = 0; j < s; j++) { - - if (b == p_sub1) { // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 - result = true; - break; - } - - b = (b * b) % bi; - } - - if (result == false) - return false; - } - return true; - } - - #endregion - - // TODO: Implement the Lucus test - // TODO: Implement other new primality tests - // TODO: Implement primality proving - } -} diff --git a/mcs/class/corlib/Mono.Math/BigInteger.cs b/mcs/class/corlib/Mono.Math/BigInteger.cs deleted file mode 100644 index 0356d0a1664..00000000000 --- a/mcs/class/corlib/Mono.Math/BigInteger.cs +++ /dev/null @@ -1,2372 +0,0 @@ -// -// BigInteger.cs - Big Integer implementation -// -// Authors: -// Ben Maurer -// Chew Keong TAN -// Sebastien Pouliot -// Pieter Philippaerts -// -// Copyright (c) 2003 Ben Maurer -// All rights reserved -// -// Copyright (c) 2002 Chew Keong TAN -// All rights reserved. -// -// Copyright (C) 2004, 2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Security.Cryptography; -using Mono.Math.Prime.Generator; -using Mono.Math.Prime; - -namespace Mono.Math { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class BigInteger { - - #region Data Storage - - /// - /// The Length of this BigInteger - /// - uint length = 1; - - /// - /// The data for this BigInteger - /// - uint [] data; - - #endregion - - #region Constants - - /// - /// Default length of a BigInteger in bytes - /// - const uint DEFAULT_LEN = 20; - - /// - /// Table of primes below 2000. - /// - /// - /// - /// This table was generated using Mathematica 4.1 using the following function: - /// - /// - /// - /// PrimeTable [x_] := Prime [Range [1, PrimePi [x]]] - /// PrimeTable [6000] - /// - /// - /// - internal static readonly uint [] smallPrimes = { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, - 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, - 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, - 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, - 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, - 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, - 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, - 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, - 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, - - 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, - 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, - 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, - 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, - 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, - 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, - 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, - 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, - 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, - 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, - 1979, 1987, 1993, 1997, 1999, - - 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, - 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, - 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, - 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, - 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, - 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, - 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, - 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, - 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, - 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, - - 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, - 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, - 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, - 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, - 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, - 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, - 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, - 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, - 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, - 3947, 3967, 3989, - - 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, - 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, - 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, - 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, - 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, - 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, - 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, - 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, - 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, - 4993, 4999, - - 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, - 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, - 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, - 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, - 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, - 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, - 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, - 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, - 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987 - }; - - public enum Sign : int { - Negative = -1, - Zero = 0, - Positive = 1 - }; - - #region Exception Messages - const string WouldReturnNegVal = "Operation would return a negative value"; - #endregion - - #endregion - - #region Constructors - - public BigInteger () - { - data = new uint [DEFAULT_LEN]; - this.length = DEFAULT_LEN; - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public BigInteger (Sign sign, uint len) - { - this.data = new uint [len]; - this.length = len; - } - - public BigInteger (BigInteger bi) - { - this.data = (uint [])bi.data.Clone (); - this.length = bi.length; - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public BigInteger (BigInteger bi, uint len) - { - - this.data = new uint [len]; - - for (uint i = 0; i < bi.length; i++) - this.data [i] = bi.data [i]; - - this.length = bi.length; - } - - #endregion - - #region Conversions - - public BigInteger (byte [] inData) - { - if (inData.Length == 0) - inData = new byte [1]; - length = (uint)inData.Length >> 2; - int leftOver = inData.Length & 0x3; - - // length not multiples of 4 - if (leftOver != 0) length++; - - data = new uint [length]; - - for (int i = inData.Length - 1, j = 0; i >= 3; i -= 4, j++) { - data [j] = (uint)( - (inData [i-3] << (3*8)) | - (inData [i-2] << (2*8)) | - (inData [i-1] << (1*8)) | - (inData [i]) - ); - } - - switch (leftOver) { - case 1: data [length-1] = (uint)inData [0]; break; - case 2: data [length-1] = (uint)((inData [0] << 8) | inData [1]); break; - case 3: data [length-1] = (uint)((inData [0] << 16) | (inData [1] << 8) | inData [2]); break; - } - - this.Normalize (); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public BigInteger (uint [] inData) - { - if (inData.Length == 0) - inData = new uint [1]; - length = (uint)inData.Length; - - data = new uint [length]; - - for (int i = (int)length - 1, j = 0; i >= 0; i--, j++) - data [j] = inData [i]; - - this.Normalize (); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public BigInteger (uint ui) - { - data = new uint [] {ui}; - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public BigInteger (ulong ul) - { - data = new uint [2] { (uint)ul, (uint)(ul >> 32)}; - length = 2; - - this.Normalize (); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public static implicit operator BigInteger (uint value) - { - return (new BigInteger (value)); - } - - public static implicit operator BigInteger (int value) - { - if (value < 0) throw new ArgumentOutOfRangeException ("value"); - return (new BigInteger ((uint)value)); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public static implicit operator BigInteger (ulong value) - { - return (new BigInteger (value)); - } - - /* This is the BigInteger.Parse method I use. This method works - because BigInteger.ToString returns the input I gave to Parse. */ - public static BigInteger Parse (string number) - { - if (number == null) - throw new ArgumentNullException ("number"); - - int i = 0, len = number.Length; - char c; - bool digits_seen = false; - BigInteger val = new BigInteger (0); - if (number [i] == '+') { - i++; - } - else if (number [i] == '-') { - throw new FormatException (WouldReturnNegVal); - } - - for (; i < len; i++) { - c = number [i]; - if (c == '\0') { - i = len; - continue; - } - if (c >= '0' && c <= '9') { - val = val * 10 + (c - '0'); - digits_seen = true; - } - else { - if (Char.IsWhiteSpace (c)) { - for (i++; i < len; i++) { - if (!Char.IsWhiteSpace (number [i])) - throw new FormatException (); - } - break; - } - else - throw new FormatException (); - } - } - if (!digits_seen) - throw new FormatException (); - return val; - } - - #endregion - - #region Operators - - public static BigInteger operator + (BigInteger bi1, BigInteger bi2) - { - if (bi1 == 0) - return new BigInteger (bi2); - else if (bi2 == 0) - return new BigInteger (bi1); - else - return Kernel.AddSameSign (bi1, bi2); - } - - public static BigInteger operator - (BigInteger bi1, BigInteger bi2) - { - if (bi2 == 0) - return new BigInteger (bi1); - - if (bi1 == 0) - throw new ArithmeticException (WouldReturnNegVal); - - switch (Kernel.Compare (bi1, bi2)) { - - case Sign.Zero: - return 0; - - case Sign.Positive: - return Kernel.Subtract (bi1, bi2); - - case Sign.Negative: - throw new ArithmeticException (WouldReturnNegVal); - default: - throw new Exception (); - } - } - - public static int operator % (BigInteger bi, int i) - { - if (i > 0) - return (int)Kernel.DwordMod (bi, (uint)i); - else - return -(int)Kernel.DwordMod (bi, (uint)-i); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public static uint operator % (BigInteger bi, uint ui) - { - return Kernel.DwordMod (bi, (uint)ui); - } - - public static BigInteger operator % (BigInteger bi1, BigInteger bi2) - { - return Kernel.multiByteDivide (bi1, bi2)[1]; - } - - public static BigInteger operator / (BigInteger bi, int i) - { - if (i > 0) - return Kernel.DwordDiv (bi, (uint)i); - - throw new ArithmeticException (WouldReturnNegVal); - } - - public static BigInteger operator / (BigInteger bi1, BigInteger bi2) - { - return Kernel.multiByteDivide (bi1, bi2)[0]; - } - - public static BigInteger operator * (BigInteger bi1, BigInteger bi2) - { - if (bi1 == 0 || bi2 == 0) return 0; - - // - // Validate pointers - // - if (bi1.data.Length < bi1.length) throw new IndexOutOfRangeException ("bi1 out of range"); - if (bi2.data.Length < bi2.length) throw new IndexOutOfRangeException ("bi2 out of range"); - - BigInteger ret = new BigInteger (Sign.Positive, bi1.length + bi2.length); - - Kernel.Multiply (bi1.data, 0, bi1.length, bi2.data, 0, bi2.length, ret.data, 0); - - ret.Normalize (); - return ret; - } - - public static BigInteger operator * (BigInteger bi, int i) - { - if (i < 0) throw new ArithmeticException (WouldReturnNegVal); - if (i == 0) return 0; - if (i == 1) return new BigInteger (bi); - - return Kernel.MultiplyByDword (bi, (uint)i); - } - - public static BigInteger operator << (BigInteger bi1, int shiftVal) - { - return Kernel.LeftShift (bi1, shiftVal); - } - - public static BigInteger operator >> (BigInteger bi1, int shiftVal) - { - return Kernel.RightShift (bi1, shiftVal); - } - - #endregion - - #region Friendly names for operators - - // with names suggested by FxCop 1.30 - - public static BigInteger Add (BigInteger bi1, BigInteger bi2) - { - return (bi1 + bi2); - } - - public static BigInteger Subtract (BigInteger bi1, BigInteger bi2) - { - return (bi1 - bi2); - } - - public static int Modulus (BigInteger bi, int i) - { - return (bi % i); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public static uint Modulus (BigInteger bi, uint ui) - { - return (bi % ui); - } - - public static BigInteger Modulus (BigInteger bi1, BigInteger bi2) - { - return (bi1 % bi2); - } - - public static BigInteger Divid (BigInteger bi, int i) - { - return (bi / i); - } - - public static BigInteger Divid (BigInteger bi1, BigInteger bi2) - { - return (bi1 / bi2); - } - - public static BigInteger Multiply (BigInteger bi1, BigInteger bi2) - { - return (bi1 * bi2); - } - - public static BigInteger Multiply (BigInteger bi, int i) - { - return (bi * i); - } - - #endregion - - #region Random - private static RandomNumberGenerator rng; - private static RandomNumberGenerator Rng { - get { - if (rng == null) - rng = RandomNumberGenerator.Create (); - return rng; - } - } - - /// - /// Generates a new, random BigInteger of the specified length. - /// - /// The number of bits for the new number. - /// A random number generator to use to obtain the bits. - /// A random number of the specified length. - public static BigInteger GenerateRandom (int bits, RandomNumberGenerator rng) - { - int dwords = bits >> 5; - int remBits = bits & 0x1F; - - if (remBits != 0) - dwords++; - - BigInteger ret = new BigInteger (Sign.Positive, (uint)dwords + 1); - byte [] random = new byte [dwords << 2]; - - rng.GetBytes (random); - Buffer.BlockCopy (random, 0, ret.data, 0, (int)dwords << 2); - - if (remBits != 0) { - uint mask = (uint)(0x01 << (remBits-1)); - ret.data [dwords-1] |= mask; - - mask = (uint)(0xFFFFFFFF >> (32 - remBits)); - ret.data [dwords-1] &= mask; - } - else - ret.data [dwords-1] |= 0x80000000; - - ret.Normalize (); - return ret; - } - - /// - /// Generates a new, random BigInteger of the specified length using the default RNG crypto service provider. - /// - /// The number of bits for the new number. - /// A random number of the specified length. - public static BigInteger GenerateRandom (int bits) - { - return GenerateRandom (bits, Rng); - } - - /// - /// Randomizes the bits in "this" from the specified RNG. - /// - /// A RNG. - public void Randomize (RandomNumberGenerator rng) - { - if (this == 0) - return; - - int bits = this.BitCount (); - int dwords = bits >> 5; - int remBits = bits & 0x1F; - - if (remBits != 0) - dwords++; - - byte [] random = new byte [dwords << 2]; - - rng.GetBytes (random); - Buffer.BlockCopy (random, 0, data, 0, (int)dwords << 2); - - if (remBits != 0) { - uint mask = (uint)(0x01 << (remBits-1)); - data [dwords-1] |= mask; - - mask = (uint)(0xFFFFFFFF >> (32 - remBits)); - data [dwords-1] &= mask; - } - - else - data [dwords-1] |= 0x80000000; - - Normalize (); - } - - /// - /// Randomizes the bits in "this" from the default RNG. - /// - public void Randomize () - { - Randomize (Rng); - } - - #endregion - - #region Bitwise - - public int BitCount () - { - this.Normalize (); - - uint value = data [length - 1]; - uint mask = 0x80000000; - uint bits = 32; - - while (bits > 0 && (value & mask) == 0) { - bits--; - mask >>= 1; - } - bits += ((length - 1) << 5); - - return (int)bits; - } - - /// - /// Tests if the specified bit is 1. - /// - /// The bit to test. The least significant bit is 0. - /// True if bitNum is set to 1, else false. -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public bool TestBit (uint bitNum) - { - uint bytePos = bitNum >> 5; // divide by 32 - byte bitPos = (byte)(bitNum & 0x1F); // get the lowest 5 bits - - uint mask = (uint)1 << bitPos; - return ((this.data [bytePos] & mask) != 0); - } - - public bool TestBit (int bitNum) - { - if (bitNum < 0) throw new IndexOutOfRangeException ("bitNum out of range"); - - uint bytePos = (uint)bitNum >> 5; // divide by 32 - byte bitPos = (byte)(bitNum & 0x1F); // get the lowest 5 bits - - uint mask = (uint)1 << bitPos; - return ((this.data [bytePos] | mask) == this.data [bytePos]); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public void SetBit (uint bitNum) - { - SetBit (bitNum, true); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public void ClearBit (uint bitNum) - { - SetBit (bitNum, false); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public void SetBit (uint bitNum, bool value) - { - uint bytePos = bitNum >> 5; // divide by 32 - - if (bytePos < this.length) { - uint mask = (uint)1 << (int)(bitNum & 0x1F); - if (value) - this.data [bytePos] |= mask; - else - this.data [bytePos] &= ~mask; - } - } - - public int LowestSetBit () - { - if (this == 0) return -1; - int i = 0; - while (!TestBit (i)) i++; - return i; - } - - public byte[] GetBytes () - { - if (this == 0) return new byte [1]; - - int numBits = BitCount (); - int numBytes = numBits >> 3; - if ((numBits & 0x7) != 0) - numBytes++; - - byte [] result = new byte [numBytes]; - - int numBytesInWord = numBytes & 0x3; - if (numBytesInWord == 0) numBytesInWord = 4; - - int pos = 0; - for (int i = (int)length - 1; i >= 0; i--) { - uint val = data [i]; - for (int j = numBytesInWord - 1; j >= 0; j--) { - result [pos+j] = (byte)(val & 0xFF); - val >>= 8; - } - pos += numBytesInWord; - numBytesInWord = 4; - } - return result; - } - - #endregion - - #region Compare - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public static bool operator == (BigInteger bi1, uint ui) - { - if (bi1.length != 1) bi1.Normalize (); - return bi1.length == 1 && bi1.data [0] == ui; - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public static bool operator != (BigInteger bi1, uint ui) - { - if (bi1.length != 1) bi1.Normalize (); - return !(bi1.length == 1 && bi1.data [0] == ui); - } - - public static bool operator == (BigInteger bi1, BigInteger bi2) - { - // we need to compare with null - if ((bi1 as object) == (bi2 as object)) - return true; - if (null == bi1 || null == bi2) - return false; - return Kernel.Compare (bi1, bi2) == 0; - } - - public static bool operator != (BigInteger bi1, BigInteger bi2) - { - // we need to compare with null - if ((bi1 as object) == (bi2 as object)) - return false; - if (null == bi1 || null == bi2) - return true; - return Kernel.Compare (bi1, bi2) != 0; - } - - public static bool operator > (BigInteger bi1, BigInteger bi2) - { - return Kernel.Compare (bi1, bi2) > 0; - } - - public static bool operator < (BigInteger bi1, BigInteger bi2) - { - return Kernel.Compare (bi1, bi2) < 0; - } - - public static bool operator >= (BigInteger bi1, BigInteger bi2) - { - return Kernel.Compare (bi1, bi2) >= 0; - } - - public static bool operator <= (BigInteger bi1, BigInteger bi2) - { - return Kernel.Compare (bi1, bi2) <= 0; - } - - public Sign Compare (BigInteger bi) - { - return Kernel.Compare (this, bi); - } - - #endregion - - #region Formatting - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public string ToString (uint radix) - { - return ToString (radix, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - } - -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif - public string ToString (uint radix, string characterSet) - { - if (characterSet.Length < radix) - throw new ArgumentException ("charSet length less than radix", "characterSet"); - if (radix == 1) - throw new ArgumentException ("There is no such thing as radix one notation", "radix"); - - if (this == 0) return "0"; - if (this == 1) return "1"; - - string result = ""; - - BigInteger a = new BigInteger (this); - - while (a != 0) { - uint rem = Kernel.SingleByteDivideInPlace (a, radix); - result = characterSet [(int) rem] + result; - } - - return result; - } - - #endregion - - #region Misc - - /// - /// Normalizes this by setting the length to the actual number of - /// uints used in data and by setting the sign to Sign.Zero if the - /// value of this is 0. - /// - private void Normalize () - { - // Normalize length - while (length > 0 && data [length-1] == 0) length--; - - // Check for zero - if (length == 0) - length++; - } - - public void Clear () - { - for (int i=0; i < length; i++) - data [i] = 0x00; - } - - #endregion - - #region Object Impl - - public override int GetHashCode () - { - uint val = 0; - - for (uint i = 0; i < this.length; i++) - val ^= this.data [i]; - - return (int)val; - } - - public override string ToString () - { - return ToString (10); - } - - public override bool Equals (object o) - { - if (o == null) - return false; - if (o is int) - return (int)o >= 0 && this == (uint)o; - - BigInteger bi = o as BigInteger; - if (bi == null) - return false; - - return Kernel.Compare (this, bi) == 0; - } - - #endregion - - #region Number Theory - - public BigInteger GCD (BigInteger bi) - { - return Kernel.gcd (this, bi); - } - - public BigInteger ModInverse (BigInteger modulus) - { - return Kernel.modInverse (this, modulus); - } - - public BigInteger ModPow (BigInteger exp, BigInteger n) - { - ModulusRing mr = new ModulusRing (n); - return mr.Pow (this, exp); - } - - #endregion - - #region Prime Testing - - public bool IsProbablePrime () - { - // can we use our small-prime table ? - if (this <= smallPrimes[smallPrimes.Length - 1]) { - for (int p = 0; p < smallPrimes.Length; p++) { - if (this == smallPrimes[p]) - return true; - } - // the list is complete, so it's not a prime - return false; - } - - // otherwise check if we can divide by one of the small primes - for (int p = 0; p < smallPrimes.Length; p++) { - if (this % smallPrimes[p] == 0) - return false; - } - // the last step is to confirm the "large" prime with the SPP or Miller-Rabin test - return PrimalityTests.Test (this, Prime.ConfidenceFactor.Medium); - } - - #endregion - - #region Prime Number Generation - - /// - /// Generates the smallest prime >= bi - /// - /// A BigInteger - /// The smallest prime >= bi. More mathematically, if bi is prime: bi, else Prime [PrimePi [bi] + 1]. - public static BigInteger NextHighestPrime (BigInteger bi) - { - NextPrimeFinder npf = new NextPrimeFinder (); - return npf.GenerateNewPrime (0, bi); - } - - public static BigInteger GeneratePseudoPrime (int bits) - { - SequentialSearchPrimeGeneratorBase sspg = new SequentialSearchPrimeGeneratorBase (); - return sspg.GenerateNewPrime (bits); - } - - /// - /// Increments this by two - /// - public void Incr2 () - { - int i = 0; - - data [0] += 2; - - // If there was no carry, nothing to do - if (data [0] < 2) { - - // Account for the first carry - data [++i]++; - - // Keep adding until no carry - while (data [i++] == 0x0) - data [i]++; - - // See if we increased the data length - if (length == (uint)i) - length++; - } - } - - #endregion - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class ModulusRing { - - BigInteger mod, constant; - - public ModulusRing (BigInteger modulus) - { - this.mod = modulus; - - // calculate constant = b^ (2k) / m - uint i = mod.length << 1; - - constant = new BigInteger (Sign.Positive, i + 1); - constant.data [i] = 0x00000001; - - constant = constant / mod; - } - - public void BarrettReduction (BigInteger x) - { - BigInteger n = mod; - uint k = n.length, - kPlusOne = k+1, - kMinusOne = k-1; - - // x < mod, so nothing to do. - if (x.length < k) return; - - BigInteger q3; - - // - // Validate pointers - // - if (x.data.Length < x.length) throw new IndexOutOfRangeException ("x out of range"); - - // q1 = x / b^ (k-1) - // q2 = q1 * constant - // q3 = q2 / b^ (k+1), Needs to be accessed with an offset of kPlusOne - - // TODO: We should the method in HAC p 604 to do this (14.45) - q3 = new BigInteger (Sign.Positive, x.length - kMinusOne + constant.length); - Kernel.Multiply (x.data, kMinusOne, x.length - kMinusOne, constant.data, 0, constant.length, q3.data, 0); - - // r1 = x mod b^ (k+1) - // i.e. keep the lowest (k+1) words - - uint lengthToCopy = (x.length > kPlusOne) ? kPlusOne : x.length; - - x.length = lengthToCopy; - x.Normalize (); - - // r2 = (q3 * n) mod b^ (k+1) - // partial multiplication of q3 and n - - BigInteger r2 = new BigInteger (Sign.Positive, kPlusOne); - Kernel.MultiplyMod2p32pmod (q3.data, (int)kPlusOne, (int)q3.length - (int)kPlusOne, n.data, 0, (int)n.length, r2.data, 0, (int)kPlusOne); - - r2.Normalize (); - - if (r2 <= x) { - Kernel.MinusEq (x, r2); - } else { - BigInteger val = new BigInteger (Sign.Positive, kPlusOne + 1); - val.data [kPlusOne] = 0x00000001; - - Kernel.MinusEq (val, r2); - Kernel.PlusEq (x, val); - } - - while (x >= n) - Kernel.MinusEq (x, n); - } - - public BigInteger Multiply (BigInteger a, BigInteger b) - { - if (a == 0 || b == 0) return 0; - - if (a > mod) - a %= mod; - - if (b > mod) - b %= mod; - - BigInteger ret = a * b; - BarrettReduction (ret); - - return ret; - } - - public BigInteger Difference (BigInteger a, BigInteger b) - { - Sign cmp = Kernel.Compare (a, b); - BigInteger diff; - - switch (cmp) { - case Sign.Zero: - return 0; - case Sign.Positive: - diff = a - b; break; - case Sign.Negative: - diff = b - a; break; - default: - throw new Exception (); - } - - if (diff >= mod) { - if (diff.length >= mod.length << 1) - diff %= mod; - else - BarrettReduction (diff); - } - if (cmp == Sign.Negative) - diff = mod - diff; - return diff; - } -#if true - public BigInteger Pow (BigInteger a, BigInteger k) - { - BigInteger b = new BigInteger (1); - if (k == 0) - return b; - - BigInteger A = a; - if (k.TestBit (0)) - b = a; - - for (int i = 1; i < k.BitCount (); i++) { - A = Multiply (A, A); - if (k.TestBit (i)) - b = Multiply (A, b); - } - return b; - } -#else - public BigInteger Pow (BigInteger b, BigInteger exp) - { - if ((mod.data [0] & 1) == 1) return OddPow (b, exp); - else return EvenPow (b, exp); - } - - public BigInteger EvenPow (BigInteger b, BigInteger exp) - { - BigInteger resultNum = new BigInteger ((BigInteger)1, mod.length << 1); - BigInteger tempNum = new BigInteger (b % mod, mod.length << 1); // ensures (tempNum * tempNum) < b^ (2k) - - uint totalBits = (uint)exp.BitCount (); - - uint [] wkspace = new uint [mod.length << 1]; - - // perform squaring and multiply exponentiation - for (uint pos = 0; pos < totalBits; pos++) { - if (exp.TestBit (pos)) { - - Array.Clear (wkspace, 0, wkspace.Length); - Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0); - resultNum.length += tempNum.length; - uint [] t = wkspace; - wkspace = resultNum.data; - resultNum.data = t; - - BarrettReduction (resultNum); - } - - Kernel.SquarePositive (tempNum, ref wkspace); - BarrettReduction (tempNum); - - if (tempNum == 1) { - return resultNum; - } - } - - return resultNum; - } - - private BigInteger OddPow (BigInteger b, BigInteger exp) - { - BigInteger resultNum = new BigInteger (Montgomery.ToMont (1, mod), mod.length << 1); - BigInteger tempNum = new BigInteger (Montgomery.ToMont (b, mod), mod.length << 1); // ensures (tempNum * tempNum) < b^ (2k) - uint mPrime = Montgomery.Inverse (mod.data [0]); - uint totalBits = (uint)exp.BitCount (); - - uint [] wkspace = new uint [mod.length << 1]; - - // perform squaring and multiply exponentiation - for (uint pos = 0; pos < totalBits; pos++) { - if (exp.TestBit (pos)) { - - Array.Clear (wkspace, 0, wkspace.Length); - Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0); - resultNum.length += tempNum.length; - uint [] t = wkspace; - wkspace = resultNum.data; - resultNum.data = t; - - Montgomery.Reduce (resultNum, mod, mPrime); - } - - // the value of tempNum is required in the last loop - if (pos < totalBits - 1) { - Kernel.SquarePositive (tempNum, ref wkspace); - Montgomery.Reduce (tempNum, mod, mPrime); - } - } - - Montgomery.Reduce (resultNum, mod, mPrime); - return resultNum; - } -#endif - #region Pow Small Base - - // TODO: Make tests for this, not really needed b/c prime stuff - // checks it, but still would be nice -#if !INSIDE_CORLIB - [CLSCompliant (false)] -#endif -#if true - public BigInteger Pow (uint b, BigInteger exp) - { - return Pow (new BigInteger (b), exp); - } -#else - public BigInteger Pow (uint b, BigInteger exp) - { -// if (b != 2) { - if ((mod.data [0] & 1) == 1) - return OddPow (b, exp); - else - return EvenPow (b, exp); -/* buggy in some cases (like the well tested primes) - } else { - if ((mod.data [0] & 1) == 1) - return OddModTwoPow (exp); - else - return EvenModTwoPow (exp); - }*/ - } - - private unsafe BigInteger OddPow (uint b, BigInteger exp) - { - exp.Normalize (); - uint [] wkspace = new uint [mod.length << 1 + 1]; - - BigInteger resultNum = Montgomery.ToMont ((BigInteger)b, this.mod); - resultNum = new BigInteger (resultNum, mod.length << 1 +1); - - uint mPrime = Montgomery.Inverse (mod.data [0]); - - int bc = exp.BitCount () - 2; - uint pos = (bc > 1 ? (uint) bc : 1); - - // - // We know that the first itr will make the val b - // - - do { - // - // r = r ^ 2 % m - // - Kernel.SquarePositive (resultNum, ref wkspace); - resultNum = Montgomery.Reduce (resultNum, mod, mPrime); - - if (exp.TestBit (pos)) { - - // - // r = r * b % m - // - - // TODO: Is Unsafe really speeding things up? - fixed (uint* u = resultNum.data) { - - uint i = 0; - ulong mc = 0; - - do { - mc += (ulong)u [i] * (ulong)b; - u [i] = (uint)mc; - mc >>= 32; - } while (++i < resultNum.length); - - if (resultNum.length < mod.length) { - if (mc != 0) { - u [i] = (uint)mc; - resultNum.length++; - while (resultNum >= mod) - Kernel.MinusEq (resultNum, mod); - } - } else if (mc != 0) { - - // - // First, we estimate the quotient by dividing - // the first part of each of the numbers. Then - // we correct this, if necessary, with a subtraction. - // - - uint cc = (uint)mc; - - // We would rather have this estimate overshoot, - // so we add one to the divisor - uint divEstimate; - if (mod.data [mod.length - 1] < UInt32.MaxValue) { - divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) / - (mod.data [mod.length-1] + 1)); - } - else { - // guess but don't divide by 0 - divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) / - (mod.data [mod.length-1])); - } - - uint t; - - i = 0; - mc = 0; - do { - mc += (ulong)mod.data [i] * (ulong)divEstimate; - t = u [i]; - u [i] -= (uint)mc; - mc >>= 32; - if (u [i] > t) mc++; - i++; - } while (i < resultNum.length); - cc -= (uint)mc; - - if (cc != 0) { - - uint sc = 0, j = 0; - uint [] s = mod.data; - do { - uint a = s [j]; - if (((a += sc) < sc) | ((u [j] -= a) > ~a)) sc = 1; - else sc = 0; - j++; - } while (j < resultNum.length); - cc -= sc; - } - while (resultNum >= mod) - Kernel.MinusEq (resultNum, mod); - } else { - while (resultNum >= mod) - Kernel.MinusEq (resultNum, mod); - } - } - } - } while (pos-- > 0); - - resultNum = Montgomery.Reduce (resultNum, mod, mPrime); - return resultNum; - - } - - private unsafe BigInteger EvenPow (uint b, BigInteger exp) - { - exp.Normalize (); - uint [] wkspace = new uint [mod.length << 1 + 1]; - BigInteger resultNum = new BigInteger ((BigInteger)b, mod.length << 1 + 1); - - uint pos = (uint)exp.BitCount () - 2; - - // - // We know that the first itr will make the val b - // - - do { - // - // r = r ^ 2 % m - // - Kernel.SquarePositive (resultNum, ref wkspace); - if (!(resultNum.length < mod.length)) - BarrettReduction (resultNum); - - if (exp.TestBit (pos)) { - - // - // r = r * b % m - // - - // TODO: Is Unsafe really speeding things up? - fixed (uint* u = resultNum.data) { - - uint i = 0; - ulong mc = 0; - - do { - mc += (ulong)u [i] * (ulong)b; - u [i] = (uint)mc; - mc >>= 32; - } while (++i < resultNum.length); - - if (resultNum.length < mod.length) { - if (mc != 0) { - u [i] = (uint)mc; - resultNum.length++; - while (resultNum >= mod) - Kernel.MinusEq (resultNum, mod); - } - } else if (mc != 0) { - - // - // First, we estimate the quotient by dividing - // the first part of each of the numbers. Then - // we correct this, if necessary, with a subtraction. - // - - uint cc = (uint)mc; - - // We would rather have this estimate overshoot, - // so we add one to the divisor - uint divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) / - (mod.data [mod.length-1] + 1)); - - uint t; - - i = 0; - mc = 0; - do { - mc += (ulong)mod.data [i] * (ulong)divEstimate; - t = u [i]; - u [i] -= (uint)mc; - mc >>= 32; - if (u [i] > t) mc++; - i++; - } while (i < resultNum.length); - cc -= (uint)mc; - - if (cc != 0) { - - uint sc = 0, j = 0; - uint [] s = mod.data; - do { - uint a = s [j]; - if (((a += sc) < sc) | ((u [j] -= a) > ~a)) sc = 1; - else sc = 0; - j++; - } while (j < resultNum.length); - cc -= sc; - } - while (resultNum >= mod) - Kernel.MinusEq (resultNum, mod); - } else { - while (resultNum >= mod) - Kernel.MinusEq (resultNum, mod); - } - } - } - } while (pos-- > 0); - - return resultNum; - } -#endif -/* known to be buggy in some cases */ -#if false - private unsafe BigInteger EvenModTwoPow (BigInteger exp) - { - exp.Normalize (); - uint [] wkspace = new uint [mod.length << 1 + 1]; - - BigInteger resultNum = new BigInteger (2, mod.length << 1 +1); - - uint value = exp.data [exp.length - 1]; - uint mask = 0x80000000; - - // Find the first bit of the exponent - while ((value & mask) == 0) - mask >>= 1; - - // - // We know that the first itr will make the val 2, - // so eat one bit of the exponent - // - mask >>= 1; - - uint wPos = exp.length - 1; - - do { - value = exp.data [wPos]; - do { - Kernel.SquarePositive (resultNum, ref wkspace); - if (resultNum.length >= mod.length) - BarrettReduction (resultNum); - - if ((value & mask) != 0) { - // - // resultNum = (resultNum * 2) % mod - // - - fixed (uint* u = resultNum.data) { - // - // Double - // - uint* uu = u; - uint* uuE = u + resultNum.length; - uint x, carry = 0; - while (uu < uuE) { - x = *uu; - *uu = (x << 1) | carry; - carry = x >> (32 - 1); - uu++; - } - - // subtraction inlined because we know it is square - if (carry != 0 || resultNum >= mod) { - uu = u; - uint c = 0; - uint [] s = mod.data; - uint i = 0; - do { - uint a = s [i]; - if (((a += c) < c) | ((* (uu++) -= a) > ~a)) - c = 1; - else - c = 0; - i++; - } while (uu < uuE); - } - } - } - } while ((mask >>= 1) > 0); - mask = 0x80000000; - } while (wPos-- > 0); - - return resultNum; - } - - private unsafe BigInteger OddModTwoPow (BigInteger exp) - { - - uint [] wkspace = new uint [mod.length << 1 + 1]; - - BigInteger resultNum = Montgomery.ToMont ((BigInteger)2, this.mod); - resultNum = new BigInteger (resultNum, mod.length << 1 +1); - - uint mPrime = Montgomery.Inverse (mod.data [0]); - - // - // TODO: eat small bits, the ones we can do with no modular reduction - // - uint pos = (uint)exp.BitCount () - 2; - - do { - Kernel.SquarePositive (resultNum, ref wkspace); - resultNum = Montgomery.Reduce (resultNum, mod, mPrime); - - if (exp.TestBit (pos)) { - // - // resultNum = (resultNum * 2) % mod - // - - fixed (uint* u = resultNum.data) { - // - // Double - // - uint* uu = u; - uint* uuE = u + resultNum.length; - uint x, carry = 0; - while (uu < uuE) { - x = *uu; - *uu = (x << 1) | carry; - carry = x >> (32 - 1); - uu++; - } - - // subtraction inlined because we know it is square - if (carry != 0 || resultNum >= mod) { - fixed (uint* s = mod.data) { - uu = u; - uint c = 0; - uint* ss = s; - do { - uint a = *ss++; - if (((a += c) < c) | ((* (uu++) -= a) > ~a)) - c = 1; - else - c = 0; - } while (uu < uuE); - } - } - } - } - } while (pos-- > 0); - - resultNum = Montgomery.Reduce (resultNum, mod, mPrime); - return resultNum; - } -#endif - #endregion - } - - /// - /// Low level functions for the BigInteger - /// - private sealed class Kernel { - - #region Addition/Subtraction - - /// - /// Adds two numbers with the same sign. - /// - /// A BigInteger - /// A BigInteger - /// bi1 + bi2 - public static BigInteger AddSameSign (BigInteger bi1, BigInteger bi2) - { - uint [] x, y; - uint yMax, xMax, i = 0; - - // x should be bigger - if (bi1.length < bi2.length) { - x = bi2.data; - xMax = bi2.length; - y = bi1.data; - yMax = bi1.length; - } else { - x = bi1.data; - xMax = bi1.length; - y = bi2.data; - yMax = bi2.length; - } - - BigInteger result = new BigInteger (Sign.Positive, xMax + 1); - - uint [] r = result.data; - - ulong sum = 0; - - // Add common parts of both numbers - do { - sum = ((ulong)x [i]) + ((ulong)y [i]) + sum; - r [i] = (uint)sum; - sum >>= 32; - } while (++i < yMax); - - // Copy remainder of longer number while carry propagation is required - bool carry = (sum != 0); - - if (carry) { - - if (i < xMax) { - do - carry = ((r [i] = x [i] + 1) == 0); - while (++i < xMax && carry); - } - - if (carry) { - r [i] = 1; - result.length = ++i; - return result; - } - } - - // Copy the rest - if (i < xMax) { - do - r [i] = x [i]; - while (++i < xMax); - } - - result.Normalize (); - return result; - } - - public static BigInteger Subtract (BigInteger big, BigInteger small) - { - BigInteger result = new BigInteger (Sign.Positive, big.length); - - uint [] r = result.data, b = big.data, s = small.data; - uint i = 0, c = 0; - - do { - - uint x = s [i]; - if (((x += c) < c) | ((r [i] = b [i] - x) > ~x)) - c = 1; - else - c = 0; - - } while (++i < small.length); - - if (i == big.length) goto fixup; - - if (c == 1) { - do - r [i] = b [i] - 1; - while (b [i++] == 0 && i < big.length); - - if (i == big.length) goto fixup; - } - - do - r [i] = b [i]; - while (++i < big.length); - - fixup: - - result.Normalize (); - return result; - } - - public static void MinusEq (BigInteger big, BigInteger small) - { - uint [] b = big.data, s = small.data; - uint i = 0, c = 0; - - do { - uint x = s [i]; - if (((x += c) < c) | ((b [i] -= x) > ~x)) - c = 1; - else - c = 0; - } while (++i < small.length); - - if (i == big.length) goto fixup; - - if (c == 1) { - do - b [i]--; - while (b [i++] == 0 && i < big.length); - } - - fixup: - - // Normalize length - while (big.length > 0 && big.data [big.length-1] == 0) big.length--; - - // Check for zero - if (big.length == 0) - big.length++; - - } - - public static void PlusEq (BigInteger bi1, BigInteger bi2) - { - uint [] x, y; - uint yMax, xMax, i = 0; - bool flag = false; - - // x should be bigger - if (bi1.length < bi2.length){ - flag = true; - x = bi2.data; - xMax = bi2.length; - y = bi1.data; - yMax = bi1.length; - } else { - x = bi1.data; - xMax = bi1.length; - y = bi2.data; - yMax = bi2.length; - } - - uint [] r = bi1.data; - - ulong sum = 0; - - // Add common parts of both numbers - do { - sum += ((ulong)x [i]) + ((ulong)y [i]); - r [i] = (uint)sum; - sum >>= 32; - } while (++i < yMax); - - // Copy remainder of longer number while carry propagation is required - bool carry = (sum != 0); - - if (carry){ - - if (i < xMax) { - do - carry = ((r [i] = x [i] + 1) == 0); - while (++i < xMax && carry); - } - - if (carry) { - r [i] = 1; - bi1.length = ++i; - return; - } - } - - // Copy the rest - if (flag && i < xMax - 1) { - do - r [i] = x [i]; - while (++i < xMax); - } - - bi1.length = xMax + 1; - bi1.Normalize (); - } - - #endregion - - #region Compare - - /// - /// Compares two BigInteger - /// - /// A BigInteger - /// A BigInteger - /// The sign of bi1 - bi2 - public static Sign Compare (BigInteger bi1, BigInteger bi2) - { - // - // Step 1. Compare the lengths - // - uint l1 = bi1.length, l2 = bi2.length; - - while (l1 > 0 && bi1.data [l1-1] == 0) l1--; - while (l2 > 0 && bi2.data [l2-1] == 0) l2--; - - if (l1 == 0 && l2 == 0) return Sign.Zero; - - // bi1 len < bi2 len - if (l1 < l2) return Sign.Negative; - // bi1 len > bi2 len - else if (l1 > l2) return Sign.Positive; - - // - // Step 2. Compare the bits - // - - uint pos = l1 - 1; - - while (pos != 0 && bi1.data [pos] == bi2.data [pos]) pos--; - - if (bi1.data [pos] < bi2.data [pos]) - return Sign.Negative; - else if (bi1.data [pos] > bi2.data [pos]) - return Sign.Positive; - else - return Sign.Zero; - } - - #endregion - - #region Division - - #region Dword - - /// - /// Performs n / d and n % d in one operation. - /// - /// A BigInteger, upon exit this will hold n / d - /// The divisor - /// n % d - public static uint SingleByteDivideInPlace (BigInteger n, uint d) - { - ulong r = 0; - uint i = n.length; - - while (i-- > 0) { - r <<= 32; - r |= n.data [i]; - n.data [i] = (uint)(r / d); - r %= d; - } - n.Normalize (); - - return (uint)r; - } - - public static uint DwordMod (BigInteger n, uint d) - { - ulong r = 0; - uint i = n.length; - - while (i-- > 0) { - r <<= 32; - r |= n.data [i]; - r %= d; - } - - return (uint)r; - } - - public static BigInteger DwordDiv (BigInteger n, uint d) - { - BigInteger ret = new BigInteger (Sign.Positive, n.length); - - ulong r = 0; - uint i = n.length; - - while (i-- > 0) { - r <<= 32; - r |= n.data [i]; - ret.data [i] = (uint)(r / d); - r %= d; - } - ret.Normalize (); - - return ret; - } - - public static BigInteger [] DwordDivMod (BigInteger n, uint d) - { - BigInteger ret = new BigInteger (Sign.Positive , n.length); - - ulong r = 0; - uint i = n.length; - - while (i-- > 0) { - r <<= 32; - r |= n.data [i]; - ret.data [i] = (uint)(r / d); - r %= d; - } - ret.Normalize (); - - BigInteger rem = (uint)r; - - return new BigInteger [] {ret, rem}; - } - - #endregion - - #region BigNum - - public static BigInteger [] multiByteDivide (BigInteger bi1, BigInteger bi2) - { - if (Kernel.Compare (bi1, bi2) == Sign.Negative) - return new BigInteger [2] { 0, new BigInteger (bi1) }; - - bi1.Normalize (); bi2.Normalize (); - - if (bi2.length == 1) - return DwordDivMod (bi1, bi2.data [0]); - - uint remainderLen = bi1.length + 1; - int divisorLen = (int)bi2.length + 1; - - uint mask = 0x80000000; - uint val = bi2.data [bi2.length - 1]; - int shift = 0; - int resultPos = (int)bi1.length - (int)bi2.length; - - while (mask != 0 && (val & mask) == 0) { - shift++; mask >>= 1; - } - - BigInteger quot = new BigInteger (Sign.Positive, bi1.length - bi2.length + 1); - BigInteger rem = (bi1 << shift); - - uint [] remainder = rem.data; - - bi2 = bi2 << shift; - - int j = (int)(remainderLen - bi2.length); - int pos = (int)remainderLen - 1; - - uint firstDivisorByte = bi2.data [bi2.length-1]; - ulong secondDivisorByte = bi2.data [bi2.length-2]; - - while (j > 0) { - ulong dividend = ((ulong)remainder [pos] << 32) + (ulong)remainder [pos-1]; - - ulong q_hat = dividend / (ulong)firstDivisorByte; - ulong r_hat = dividend % (ulong)firstDivisorByte; - - do { - - if (q_hat == 0x100000000 || - (q_hat * secondDivisorByte) > ((r_hat << 32) + remainder [pos-2])) { - q_hat--; - r_hat += (ulong)firstDivisorByte; - - if (r_hat < 0x100000000) - continue; - } - break; - } while (true); - - // - // At this point, q_hat is either exact, or one too large - // (more likely to be exact) so, we attempt to multiply the - // divisor by q_hat, if we get a borrow, we just subtract - // one from q_hat and add the divisor back. - // - - uint t; - uint dPos = 0; - int nPos = pos - divisorLen + 1; - ulong mc = 0; - uint uint_q_hat = (uint)q_hat; - do { - mc += (ulong)bi2.data [dPos] * (ulong)uint_q_hat; - t = remainder [nPos]; - remainder [nPos] -= (uint)mc; - mc >>= 32; - if (remainder [nPos] > t) mc++; - dPos++; nPos++; - } while (dPos < divisorLen); - - nPos = pos - divisorLen + 1; - dPos = 0; - - // Overestimate - if (mc != 0) { - uint_q_hat--; - ulong sum = 0; - - do { - sum = ((ulong)remainder [nPos]) + ((ulong)bi2.data [dPos]) + sum; - remainder [nPos] = (uint)sum; - sum >>= 32; - dPos++; nPos++; - } while (dPos < divisorLen); - - } - - quot.data [resultPos--] = (uint)uint_q_hat; - - pos--; - j--; - } - - quot.Normalize (); - rem.Normalize (); - BigInteger [] ret = new BigInteger [2] { quot, rem }; - - if (shift != 0) - ret [1] >>= shift; - - return ret; - } - - #endregion - - #endregion - - #region Shift - public static BigInteger LeftShift (BigInteger bi, int n) - { - if (n == 0) return new BigInteger (bi, bi.length + 1); - - int w = n >> 5; - n &= ((1 << 5) - 1); - - BigInteger ret = new BigInteger (Sign.Positive, bi.length + 1 + (uint)w); - - uint i = 0, l = bi.length; - if (n != 0) { - uint x, carry = 0; - while (i < l) { - x = bi.data [i]; - ret.data [i + w] = (x << n) | carry; - carry = x >> (32 - n); - i++; - } - ret.data [i + w] = carry; - } else { - while (i < l) { - ret.data [i + w] = bi.data [i]; - i++; - } - } - - ret.Normalize (); - return ret; - } - - public static BigInteger RightShift (BigInteger bi, int n) - { - if (n == 0) return new BigInteger (bi); - - int w = n >> 5; - int s = n & ((1 << 5) - 1); - - BigInteger ret = new BigInteger (Sign.Positive, bi.length - (uint)w + 1); - uint l = (uint)ret.data.Length - 1; - - if (s != 0) { - - uint x, carry = 0; - - while (l-- > 0) { - x = bi.data [l + w]; - ret.data [l] = (x >> n) | carry; - carry = x << (32 - n); - } - } else { - while (l-- > 0) - ret.data [l] = bi.data [l + w]; - - } - ret.Normalize (); - return ret; - } - - #endregion - - #region Multiply - - public static BigInteger MultiplyByDword (BigInteger n, uint f) - { - BigInteger ret = new BigInteger (Sign.Positive, n.length + 1); - - uint i = 0; - ulong c = 0; - - do { - c += (ulong)n.data [i] * (ulong)f; - ret.data [i] = (uint)c; - c >>= 32; - } while (++i < n.length); - ret.data [i] = (uint)c; - ret.Normalize (); - return ret; - - } - - /// - /// Multiplies the data in x [xOffset:xOffset+xLen] by - /// y [yOffset:yOffset+yLen] and puts it into - /// d [dOffset:dOffset+xLen+yLen]. - /// - /// - /// This code is unsafe! It is the caller's responsibility to make - /// sure that it is safe to access x [xOffset:xOffset+xLen], - /// y [yOffset:yOffset+yLen], and d [dOffset:dOffset+xLen+yLen]. - /// - public static unsafe void Multiply (uint [] x, uint xOffset, uint xLen, uint [] y, uint yOffset, uint yLen, uint [] d, uint dOffset) - { - fixed (uint* xx = x, yy = y, dd = d) { - uint* xP = xx + xOffset, - xE = xP + xLen, - yB = yy + yOffset, - yE = yB + yLen, - dB = dd + dOffset; - - for (; xP < xE; xP++, dB++) { - - if (*xP == 0) continue; - - ulong mcarry = 0; - - uint* dP = dB; - for (uint* yP = yB; yP < yE; yP++, dP++) { - mcarry += ((ulong)*xP * (ulong)*yP) + (ulong)*dP; - - *dP = (uint)mcarry; - mcarry >>= 32; - } - - if (mcarry != 0) - *dP = (uint)mcarry; - } - } - } - - /// - /// Multiplies the data in x [xOffset:xOffset+xLen] by - /// y [yOffset:yOffset+yLen] and puts the low mod words into - /// d [dOffset:dOffset+mod]. - /// - /// - /// This code is unsafe! It is the caller's responsibility to make - /// sure that it is safe to access x [xOffset:xOffset+xLen], - /// y [yOffset:yOffset+yLen], and d [dOffset:dOffset+mod]. - /// - public static unsafe void MultiplyMod2p32pmod (uint [] x, int xOffset, int xLen, uint [] y, int yOffest, int yLen, uint [] d, int dOffset, int mod) - { - fixed (uint* xx = x, yy = y, dd = d) { - uint* xP = xx + xOffset, - xE = xP + xLen, - yB = yy + yOffest, - yE = yB + yLen, - dB = dd + dOffset, - dE = dB + mod; - - for (; xP < xE; xP++, dB++) { - - if (*xP == 0) continue; - - ulong mcarry = 0; - uint* dP = dB; - for (uint* yP = yB; yP < yE && dP < dE; yP++, dP++) { - mcarry += ((ulong)*xP * (ulong)*yP) + (ulong)*dP; - - *dP = (uint)mcarry; - mcarry >>= 32; - } - - if (mcarry != 0 && dP < dE) - *dP = (uint)mcarry; - } - } - } - - public static unsafe void SquarePositive (BigInteger bi, ref uint [] wkSpace) - { - uint [] t = wkSpace; - wkSpace = bi.data; - uint [] d = bi.data; - uint dl = bi.length; - bi.data = t; - - fixed (uint* dd = d, tt = t) { - - uint* ttE = tt + t.Length; - // Clear the dest - for (uint* ttt = tt; ttt < ttE; ttt++) - *ttt = 0; - - uint* dP = dd, tP = tt; - - for (uint i = 0; i < dl; i++, dP++) { - if (*dP == 0) - continue; - - ulong mcarry = 0; - uint bi1val = *dP; - - uint* dP2 = dP + 1, tP2 = tP + 2*i + 1; - - for (uint j = i + 1; j < dl; j++, tP2++, dP2++) { - // k = i + j - mcarry += ((ulong)bi1val * (ulong)*dP2) + *tP2; - - *tP2 = (uint)mcarry; - mcarry >>= 32; - } - - if (mcarry != 0) - *tP2 = (uint)mcarry; - } - - // Double t. Inlined for speed. - - tP = tt; - - uint x, carry = 0; - while (tP < ttE) { - x = *tP; - *tP = (x << 1) | carry; - carry = x >> (32 - 1); - tP++; - } - if (carry != 0) *tP = carry; - - // Add in the diagnals - - dP = dd; - tP = tt; - for (uint* dE = dP + dl; (dP < dE); dP++, tP++) { - ulong val = (ulong)*dP * (ulong)*dP + *tP; - *tP = (uint)val; - val >>= 32; - *(++tP) += (uint)val; - if (*tP < (uint)val) { - uint* tP3 = tP; - // Account for the first carry - (*++tP3)++; - - // Keep adding until no carry - while ((*tP3++) == 0) - (*tP3)++; - } - - } - - bi.length <<= 1; - - // Normalize length - while (tt [bi.length-1] == 0 && bi.length > 1) bi.length--; - - } - } - -/* - * Never called in BigInteger (and part of a private class) - * public static bool Double (uint [] u, int l) - { - uint x, carry = 0; - uint i = 0; - while (i < l) { - x = u [i]; - u [i] = (x << 1) | carry; - carry = x >> (32 - 1); - i++; - } - if (carry != 0) u [l] = carry; - return carry != 0; - }*/ - - #endregion - - #region Number Theory - - public static BigInteger gcd (BigInteger a, BigInteger b) - { - BigInteger x = a; - BigInteger y = b; - - BigInteger g = y; - - while (x.length > 1) { - g = x; - x = y % x; - y = g; - - } - if (x == 0) return g; - - // TODO: should we have something here if we can convert to long? - - // - // Now we can just do it with single precision. I am using the binary gcd method, - // as it should be faster. - // - - uint yy = x.data [0]; - uint xx = y % yy; - - int t = 0; - - while (((xx | yy) & 1) == 0) { - xx >>= 1; yy >>= 1; t++; - } - while (xx != 0) { - while ((xx & 1) == 0) xx >>= 1; - while ((yy & 1) == 0) yy >>= 1; - if (xx >= yy) - xx = (xx - yy) >> 1; - else - yy = (yy - xx) >> 1; - } - - return yy << t; - } - - public static uint modInverse (BigInteger bi, uint modulus) - { - uint a = modulus, b = bi % modulus; - uint p0 = 0, p1 = 1; - - while (b != 0) { - if (b == 1) - return p1; - p0 += (a / b) * p1; - a %= b; - - if (a == 0) - break; - if (a == 1) - return modulus-p0; - - p1 += (b / a) * p0; - b %= a; - - } - return 0; - } - - public static BigInteger modInverse (BigInteger bi, BigInteger modulus) - { - if (modulus.length == 1) return modInverse (bi, modulus.data [0]); - - BigInteger [] p = { 0, 1 }; - BigInteger [] q = new BigInteger [2]; // quotients - BigInteger [] r = { 0, 0 }; // remainders - - int step = 0; - - BigInteger a = modulus; - BigInteger b = bi; - - ModulusRing mr = new ModulusRing (modulus); - - while (b != 0) { - - if (step > 1) { - - BigInteger pval = mr.Difference (p [0], p [1] * q [0]); - p [0] = p [1]; p [1] = pval; - } - - BigInteger [] divret = multiByteDivide (a, b); - - q [0] = q [1]; q [1] = divret [0]; - r [0] = r [1]; r [1] = divret [1]; - a = b; - b = divret [1]; - - step++; - } - - if (r [0] != 1) - throw (new ArithmeticException ("No inverse!")); - - return mr.Difference (p [0], p [1] * q [0]); - - } - #endregion - } - } -} diff --git a/mcs/class/corlib/Mono.Math/ChangeLog b/mcs/class/corlib/Mono.Math/ChangeLog deleted file mode 100644 index f91df6a6e12..00000000000 --- a/mcs/class/corlib/Mono.Math/ChangeLog +++ /dev/null @@ -1,78 +0,0 @@ -2007-05-31 Alan McGovern - - * BigInteger.cs: Don't instantiate a new BigInteger after - multiplying - it's not needed. - -2007-09-12 Sebastien Pouliot - - * BigInteger.cs: Updated to match Mono.Security sources. - -2007-07-28 Miguel de Icaza - - * BigInteger.cs: Do not cast inside Equals,instead use the as - operator, as reported by Jesse Jones. - -2004-12-03 Sebastien Pouliot - - * BigInteger.cs: Fix issue #70169 in ModPow when modulus is a power of - two. - -2004-10-19 Sebastien Pouliot - - * BigInteger.cs: Fix issue #68452 when Randomize was being called on a - 0 BigInteger (i.e. BitCount == 0). - -2004-05-14 Marek Safar - - * BigInteger.cs: Removed useless [CLSCompliant (false)] - -2004-05-07 Sebastien Pouliot - - * BigInteger.cs: In sync with Mono.Security.dll version. - -2004-04-30 Ben Maurer - - * BigInteger.cs: use readonly for prime array. - -2004-04-28 Sebastien Pouliot - - * BigInteger.cs: In sync with Mono.Security.dll version. - -2004-02-23 Sebastien Pouliot - - * BigInteger.cs: Corrected isProbablePrime by removing the redundant - loop. Fix #54750. - -2004-02-13 Sebastien Pouliot - - * BigInteger.cs: Fixed isProbablePrime() and added Parse method from - patch provided by Pieter (#51229). Changed SmallPrimeSppTest to - RabinMillerTest (#51229, #54262). Removed obsoleted method - isProbablePrime(int). - -2004-02-09 Sebastien Pouliot - - * BigInteger.cs: Added INSIDE_CORLIB to define ModulusRing as - internal. Without this the unit tests for Mono.Math (now in - Mono.Security assembly) wont compile (see bugzilla #44845). - -2003-11-20 Ben Maurer - - * BigInteger.cs: Fix prob. prime test for small numbers (Pieter Philippaerts) - -2003-06-11 Sebastien Pouliot - - * BigInteger.cs: Added Clear to zeroize big integers and code to allow - compares with null (because operators == and != are re-defined). Note: - The class may still leak some private info in temp arrays (thanks Ben). - -2003-04-22 Sebastien Pouliot - - * BigInteger.cs: New, much faster, version by Ben Maurer. - Warning: this version requires "unsafe" compilation switch - (which isn't a problem in corlib but may be elsewhere) - -2003-02-08 Sebastien Pouliot - - * BigInteger.cs: Renamed namespace to match new location. - diff --git a/mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeBase.cs b/mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeBase.cs deleted file mode 100644 index bee47e7b045..00000000000 --- a/mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeBase.cs +++ /dev/null @@ -1,281 +0,0 @@ -// -// AuthenticodeBase.cs: Authenticode signature base class -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004, 2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.Security.Cryptography; - -namespace Mono.Security.Authenticode { - - // References: - // a. http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt - -#if INSIDE_CORLIB - internal -#else - public -#endif - enum Authority { - Individual, - Commercial, - Maximum - } - -#if INSIDE_CORLIB - internal -#else - public -#endif - class AuthenticodeBase { - - public const string spcIndirectDataContext = "1.3.6.1.4.1.311.2.1.4"; - - private byte[] fileblock; - private FileStream fs; - private int blockNo; - private int blockLength; - private int peOffset; - private int dirSecurityOffset; - private int dirSecuritySize; - private int coffSymbolTableOffset; - - public AuthenticodeBase () - { - fileblock = new byte [4096]; - } - - internal int PEOffset { - get { - if (blockNo < 1) - ReadFirstBlock (); - return peOffset; - } - } - - internal int CoffSymbolTableOffset { - get { - if (blockNo < 1) - ReadFirstBlock (); - return coffSymbolTableOffset; - } - } - - internal int SecurityOffset { - get { - if (blockNo < 1) - ReadFirstBlock (); - return dirSecurityOffset; - } - } - - internal void Open (string filename) - { - if (fs != null) - Close (); - fs = new FileStream (filename, FileMode.Open, FileAccess.Read, FileShare.Read); - } - - internal void Close () - { - if (fs != null) { - fs.Close (); - fs = null; - blockNo = 0; - } - } - - internal bool ReadFirstBlock () - { - if (fs == null) - return false; - - fs.Position = 0; - // read first block - it will include (100% sure) - // the MZ header and (99.9% sure) the PE header - blockLength = fs.Read (fileblock, 0, fileblock.Length); - blockNo = 1; - if (blockLength < 64) - return false; // invalid PE file - - // 1. Validate the MZ header informations - // 1.1. Check for magic MZ at start of header - if (BitConverterLE.ToUInt16 (fileblock, 0) != 0x5A4D) - return false; - - // 1.2. Find the offset of the PE header - peOffset = BitConverterLE.ToInt32 (fileblock, 60); - if (peOffset > fileblock.Length) { - // just in case (0.1%) this can actually happen - string msg = String.Format (Locale.GetText ( - "Header size too big (> {0} bytes)."), - fileblock.Length); - throw new NotSupportedException (msg); - } - if (peOffset > fs.Length) - return false; - - // 2. Read between DOS header and first part of PE header - // 2.1. Check for magic PE at start of header - // PE - NT header ('P' 'E' 0x00 0x00) - if (BitConverterLE.ToUInt32 (fileblock, peOffset) != 0x4550) - return false; - - // 2.2. Locate IMAGE_DIRECTORY_ENTRY_SECURITY (offset and size) - dirSecurityOffset = BitConverterLE.ToInt32 (fileblock, peOffset + 152); - dirSecuritySize = BitConverterLE.ToInt32 (fileblock, peOffset + 156); - - // COFF symbol tables are deprecated - we'll strip them if we see them! - // (otherwise the signature won't work on MS and we don't want to support COFF for that) - coffSymbolTableOffset = BitConverterLE.ToInt32 (fileblock, peOffset + 12); - - return true; - } - - internal byte[] GetSecurityEntry () - { - if (blockNo < 1) - ReadFirstBlock (); - - if (dirSecuritySize > 8) { - // remove header from size (not ASN.1 based) - byte[] secEntry = new byte [dirSecuritySize - 8]; - // position after header and read entry - fs.Position = dirSecurityOffset + 8; - fs.Read (secEntry, 0, secEntry.Length); - return secEntry; - } - return null; - } - - internal byte[] GetHash (HashAlgorithm hash) - { - if (blockNo < 1) - ReadFirstBlock (); - fs.Position = blockLength; - - // hash the rest of the file - long n; - int addsize = 0; - // minus any authenticode signature (with 8 bytes header) - if (dirSecurityOffset > 0) { - // it is also possible that the signature block - // starts within the block in memory (small EXE) - if (dirSecurityOffset < blockLength) { - blockLength = dirSecurityOffset; - n = 0; - } else { - n = dirSecurityOffset - blockLength; - } - } else if (coffSymbolTableOffset > 0) { - fileblock[PEOffset + 12] = 0; - fileblock[PEOffset + 13] = 0; - fileblock[PEOffset + 14] = 0; - fileblock[PEOffset + 15] = 0; - fileblock[PEOffset + 16] = 0; - fileblock[PEOffset + 17] = 0; - fileblock[PEOffset + 18] = 0; - fileblock[PEOffset + 19] = 0; - // it is also possible that the signature block - // starts within the block in memory (small EXE) - if (coffSymbolTableOffset < blockLength) { - blockLength = coffSymbolTableOffset; - n = 0; - } else { - n = coffSymbolTableOffset - blockLength; - } - } else { - addsize = (int) (fs.Length & 7); - if (addsize > 0) - addsize = 8 - addsize; - - n = fs.Length - blockLength; - } - - // Authenticode(r) gymnastics - // Hash from (generally) 0 to 215 (216 bytes) - int pe = peOffset + 88; - hash.TransformBlock (fileblock, 0, pe, fileblock, 0); - // then skip 4 for checksum - pe += 4; - // Continue hashing from (generally) 220 to 279 (60 bytes) - hash.TransformBlock (fileblock, pe, 60, fileblock, pe); - // then skip 8 bytes for IMAGE_DIRECTORY_ENTRY_SECURITY - pe += 68; - - // everything is present so start the hashing - if (n == 0) { - // hash the (only) block - hash.TransformFinalBlock (fileblock, pe, blockLength - pe); - } - else { - // hash the last part of the first (already in memory) block - hash.TransformBlock (fileblock, pe, blockLength - pe, fileblock, pe); - - // hash by blocks of 4096 bytes - long blocks = (n >> 12); - int remainder = (int)(n - (blocks << 12)); - if (remainder == 0) { - blocks--; - remainder = 4096; - } - // blocks - while (blocks-- > 0) { - fs.Read (fileblock, 0, fileblock.Length); - hash.TransformBlock (fileblock, 0, fileblock.Length, fileblock, 0); - } - // remainder - if (fs.Read (fileblock, 0, remainder) != remainder) - return null; - - if (addsize > 0) { - hash.TransformBlock (fileblock, 0, remainder, fileblock, 0); - hash.TransformFinalBlock (new byte [addsize], 0, addsize); - } else { - hash.TransformFinalBlock (fileblock, 0, remainder); - } - } - return hash.Hash; - } - - // for compatibility only - protected byte[] HashFile (string fileName, string hashName) - { - try { - Open (fileName); - HashAlgorithm hash = HashAlgorithm.Create (hashName); - byte[] result = GetHash (hash); - Close (); - return result; - } - catch { - return null; - } - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeDeformatter.cs b/mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeDeformatter.cs deleted file mode 100644 index a92affc4e54..00000000000 --- a/mcs/class/corlib/Mono.Security.Authenticode/AuthenticodeDeformatter.cs +++ /dev/null @@ -1,456 +0,0 @@ -// -// AuthenticodeDeformatter.cs: Authenticode signature validator -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.Cryptography; - -using Mono.Security.Cryptography; -using Mono.Security.X509; - -namespace Mono.Security.Authenticode { - - // References: - // a. http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt - -#if INSIDE_CORLIB - internal -#else - public -#endif - class AuthenticodeDeformatter : AuthenticodeBase { - - private string filename; - private byte[] hash; - private X509CertificateCollection coll; - private ASN1 signedHash; - private DateTime timestamp; - private X509Certificate signingCertificate; - private int reason; - private bool trustedRoot; - private bool trustedTimestampRoot; - private byte[] entry; - - private X509Chain signerChain; - private X509Chain timestampChain; - - public AuthenticodeDeformatter () : base () - { - reason = -1; - signerChain = new X509Chain (); - timestampChain = new X509Chain (); - } - - public AuthenticodeDeformatter (string fileName) : this () - { - FileName = fileName; - } - - public string FileName { - get { return filename; } - set { - Reset (); - try { - CheckSignature (value); - } - catch (SecurityException) { - throw; - } - catch (Exception) { - reason = 1; - } - } - } - - public byte[] Hash { - get { - if (signedHash == null) - return null; - return (byte[]) signedHash.Value.Clone (); - } - } - - public int Reason { - get { - if (reason == -1) - IsTrusted (); - return reason; - } - } - - public bool IsTrusted () - { - if (entry == null) { - reason = 1; - return false; - } - - if (signingCertificate == null) { - reason = 7; - return false; - } - - if ((signerChain.Root == null) || !trustedRoot) { - reason = 6; - return false; - } - - if (timestamp != DateTime.MinValue) { - if ((timestampChain.Root == null) || !trustedTimestampRoot) { - reason = 6; - return false; - } - - // check that file was timestamped when certificates were valid - if (!signingCertificate.WasCurrent (Timestamp)) { - reason = 4; - return false; - } - } - else if (!signingCertificate.IsCurrent) { - // signature only valid if the certificate is valid - reason = 8; - return false; - } - - if (reason == -1) - reason = 0; - return true; - } - - public byte[] Signature { - get { - if (entry == null) - return null; - return (byte[]) entry.Clone (); - } - } - - public DateTime Timestamp { - get { return timestamp; } - } - - public X509CertificateCollection Certificates { - get { return coll; } - } - - public X509Certificate SigningCertificate { - get { return signingCertificate; } - } - - private bool CheckSignature (string fileName) - { - filename = fileName; - Open (filename); - entry = GetSecurityEntry (); - if (entry == null) { - // no signature is present - reason = 1; - Close (); - return false; - } - - PKCS7.ContentInfo ci = new PKCS7.ContentInfo (entry); - if (ci.ContentType != PKCS7.Oid.signedData) { - Close (); - return false; - } - - PKCS7.SignedData sd = new PKCS7.SignedData (ci.Content); - if (sd.ContentInfo.ContentType != spcIndirectDataContext) { - Close (); - return false; - } - - coll = sd.Certificates; - - ASN1 spc = sd.ContentInfo.Content; - signedHash = spc [0][1][1]; - - HashAlgorithm ha = null; - switch (signedHash.Length) { - case 16: - ha = HashAlgorithm.Create ("MD5"); - hash = GetHash (ha); - break; - case 20: - ha = HashAlgorithm.Create ("SHA1"); - hash = GetHash (ha); - break; - default: - reason = 5; - Close (); - return false; - } - Close (); - - if (!signedHash.CompareValue (hash)) { - reason = 2; - } - - // messageDigest is a hash of spcIndirectDataContext (which includes the file hash) - byte[] spcIDC = spc [0].Value; - ha.Initialize (); // re-using hash instance - byte[] messageDigest = ha.ComputeHash (spcIDC); - - bool sign = VerifySignature (sd, messageDigest, ha); - return (sign && (reason == 0)); - } - - private bool CompareIssuerSerial (string issuer, byte[] serial, X509Certificate x509) - { - if (issuer != x509.IssuerName) - return false; - if (serial.Length != x509.SerialNumber.Length) - return false; - // MS shows the serial number inversed (so is Mono.Security.X509.X509Certificate) - int n = serial.Length; - for (int i=0; i < serial.Length; i++) { - if (serial [i] != x509.SerialNumber [--n]) - return false; - } - // must be true - return true; - } - - //private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName) - private bool VerifySignature (PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) - { - string contentType = null; - ASN1 messageDigest = null; -// string spcStatementType = null; -// string spcSpOpusInfo = null; - - for (int i=0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { - ASN1 attr = (ASN1) sd.SignerInfo.AuthenticatedAttributes [i]; - string oid = ASN1Convert.ToOid (attr[0]); - switch (oid) { - case "1.2.840.113549.1.9.3": - // contentType - contentType = ASN1Convert.ToOid (attr[1][0]); - break; - case "1.2.840.113549.1.9.4": - // messageDigest - messageDigest = attr[1][0]; - break; - case "1.3.6.1.4.1.311.2.1.11": - // spcStatementType (Microsoft code signing) - // possible values - // - individualCodeSigning (1 3 6 1 4 1 311 2 1 21) - // - commercialCodeSigning (1 3 6 1 4 1 311 2 1 22) -// spcStatementType = ASN1Convert.ToOid (attr[1][0][0]); - break; - case "1.3.6.1.4.1.311.2.1.12": - // spcSpOpusInfo (Microsoft code signing) -/* try { - spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value); - } - catch (NullReferenceException) { - spcSpOpusInfo = null; - }*/ - break; - default: - break; - } - } - if (contentType != spcIndirectDataContext) - return false; - - // verify message digest - if (messageDigest == null) - return false; - if (!messageDigest.CompareValue (calculatedMessageDigest)) - return false; - - // verify signature - string hashOID = CryptoConfig.MapNameToOID (ha.ToString ()); - - // change to SET OF (not [0]) as per PKCS #7 1.5 - ASN1 aa = new ASN1 (0x31); - foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes) - aa.Add (a); - ha.Initialize (); - byte[] p7hash = ha.ComputeHash (aa.GetBytes ()); - - byte[] signature = sd.SignerInfo.Signature; - // we need to find the specified certificate - string issuer = sd.SignerInfo.IssuerName; - byte[] serial = sd.SignerInfo.SerialNumber; - foreach (X509Certificate x509 in coll) { - if (CompareIssuerSerial (issuer, serial, x509)) { - // don't verify is key size don't match - if (x509.PublicKey.Length > (signature.Length >> 3)) { - // return the signing certificate even if the signature isn't correct - // (required behaviour for 2.0 support) - signingCertificate = x509; - RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA; - if (rsa.VerifyHash (p7hash, hashOID, signature)) { - signerChain.LoadCertificates (coll); - trustedRoot = signerChain.Build (x509); - break; - } - } - } - } - - // timestamp signature is optional - if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { - trustedTimestampRoot = true; - } else { - for (int i = 0; i < sd.SignerInfo.UnauthenticatedAttributes.Count; i++) { - ASN1 attr = (ASN1) sd.SignerInfo.UnauthenticatedAttributes[i]; - string oid = ASN1Convert.ToOid (attr[0]); - switch (oid) { - case PKCS7.Oid.countersignature: - // SEQUENCE { - // OBJECT IDENTIFIER - // countersignature (1 2 840 113549 1 9 6) - // SET { - PKCS7.SignerInfo cs = new PKCS7.SignerInfo (attr[1]); - trustedTimestampRoot = VerifyCounterSignature (cs, signature); - break; - default: - // we don't support other unauthenticated attributes - break; - } - } - } - - return (trustedRoot && trustedTimestampRoot); - } - - private bool VerifyCounterSignature (PKCS7.SignerInfo cs, byte[] signature) - { - // SEQUENCE { - // INTEGER 1 - if (cs.Version != 1) - return false; - // SEQUENCE { - // SEQUENCE { - - string contentType = null; - ASN1 messageDigest = null; - for (int i=0; i < cs.AuthenticatedAttributes.Count; i++) { - // SEQUENCE { - // OBJECT IDENTIFIER - ASN1 attr = (ASN1) cs.AuthenticatedAttributes [i]; - string oid = ASN1Convert.ToOid (attr[0]); - switch (oid) { - case "1.2.840.113549.1.9.3": - // contentType - contentType = ASN1Convert.ToOid (attr[1][0]); - break; - case "1.2.840.113549.1.9.4": - // messageDigest - messageDigest = attr[1][0]; - break; - case "1.2.840.113549.1.9.5": - // SEQUENCE { - // OBJECT IDENTIFIER - // signingTime (1 2 840 113549 1 9 5) - // SET { - // UTCTime '030124013651Z' - // } - // } - timestamp = ASN1Convert.ToDateTime (attr[1][0]); - break; - default: - break; - } - } - - if (contentType != PKCS7.Oid.data) - return false; - - // verify message digest - if (messageDigest == null) - return false; - // TODO: must be read from the ASN.1 structure - string hashName = null; - switch (messageDigest.Length) { - case 16: - hashName = "MD5"; - break; - case 20: - hashName = "SHA1"; - break; - } - HashAlgorithm ha = HashAlgorithm.Create (hashName); - if (!messageDigest.CompareValue (ha.ComputeHash (signature))) - return false; - - // verify signature - byte[] counterSignature = cs.Signature; - - // change to SET OF (not [0]) as per PKCS #7 1.5 - ASN1 aa = new ASN1 (0x31); - foreach (ASN1 a in cs.AuthenticatedAttributes) - aa.Add (a); - byte[] p7hash = ha.ComputeHash (aa.GetBytes ()); - - // we need to try all certificates - string issuer = cs.IssuerName; - byte[] serial = cs.SerialNumber; - foreach (X509Certificate x509 in coll) { - if (CompareIssuerSerial (issuer, serial, x509)) { - if (x509.PublicKey.Length > counterSignature.Length) { - RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA; - // we need to HACK around bad (PKCS#1 1.5) signatures made by Verisign Timestamp Service - // and this means copying stuff into our own RSAManaged to get the required flexibility - RSAManaged rsam = new RSAManaged (); - rsam.ImportParameters (rsa.ExportParameters (false)); - if (PKCS1.Verify_v15 (rsam, ha, p7hash, counterSignature, true)) { - timestampChain.LoadCertificates (coll); - return (timestampChain.Build (x509)); - } - } - } - } - // no certificate can verify this signature! - return false; - } - - private void Reset () - { - filename = null; - entry = null; - hash = null; - signedHash = null; - signingCertificate = null; - reason = -1; - trustedRoot = false; - trustedTimestampRoot = false; - signerChain.Reset (); - timestampChain.Reset (); - timestamp = DateTime.MinValue; - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Authenticode/ChangeLog b/mcs/class/corlib/Mono.Security.Authenticode/ChangeLog deleted file mode 100644 index 07ce4c9f149..00000000000 --- a/mcs/class/corlib/Mono.Security.Authenticode/ChangeLog +++ /dev/null @@ -1,72 +0,0 @@ -2010-03-16 Jb Evain - - * AuthenticodeBase.cs, AuthenticodeDeformatter.cs: use MOONLIGHT - symbol to disambiguate MonoTouch and Moonlight code. - -2009-04-30 Sebastien Pouliot - - * AuthenticodeBase.cs, AuthenticodeDeformatter.cs: Remove from NET_2_1 - -2008-01-10 Sebastien Pouliot - - * AuthenticodeDeformatter.cs: Use RSAManaged and the new overloaded - PKCS1.Verify_v15 with tryNonStandardEncoding == true when verifying - timestamping certificate signatures. Fix for #350958 - -2007-04-26 Sebastien Pouliot - - * AuthenticodeBase.cs: Synch with latest Mono.Security version - * AuthenticodeDeformatter.cs: Synch with latest Mono.Security version - -2006-11-08 Sebastien Pouliot - - * AuthenticodeDeformatter.cs: Return (find) the SigningCertificate - even if the signature isn't verifiable. This is the behaviour required - for 2.0. - -2006-06-14 Sebastien Pouliot - - * AuthenticodeBase.cs: Fix destination offset. Note that this works - under MS but not under Mono. - * AuthenticodeDeformatter.cs: Report a more useful error if the file - hash doesn't match the signed hash. - -2005-03-24 Sebastien Pouliot - - * AuthenticodeDeformatter.cs: Don't hide the SecurityException (e.g. - file access). - -2004-09-16 Sebastien Pouliot - - * AuthenticodeDeformatter.cs: Fixed warning (l4) for unused variables. - -2004-09-07 Sebastien Pouliot - - * AuthenticodeBase.cs: Merge from Mono.Security.dll. This version is - less memory consuming (it works by 4kb blocks instead of loading the - entire assembly). - * AuthenticodeDeformatter.cs: Merge from Mono.Security.dll. Hash will - only be created if the assembly is signed. Benefits from Authenticode - Base changes. - -2004-04-28 Sebastien Pouliot - - * AuthenticodeBase.cs: In sync with Mono.Security.dll version. - * AuthenticodeDeformatter.cs: In sync with Mono.Security.dll version. - -2004-04-08 Bernie Solomon - - * AuthenticodeBase.cs: Use BitConverterLE - -2003-12-15 Sebastien Pouliot - - * AuthenticodeDeformatter.cs: Now throw a COMException for invalid - signature. Added a SigningCertificate property (to be independant of - the certificate collection ordering). - -2003-10-12 Sebastien Pouliot - - * AuthenticodeBase.cs: Added from Mono.Security assembly for - Authenticode support in X509Certificate.CreateFromSignedFile - * AuthenticodeDeformatter.cs: Added from Mono.Security assembly for - Authenticode support in X509Certificate.CreateFromSignedFile diff --git a/mcs/class/corlib/Mono.Security.Cryptography/CryptoConvert.cs b/mcs/class/corlib/Mono.Security.Cryptography/CryptoConvert.cs deleted file mode 100644 index a56e94d01e2..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/CryptoConvert.cs +++ /dev/null @@ -1,754 +0,0 @@ -// -// CryptoConvert.cs - Crypto Convertion Routines -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Security.Cryptography; -using System.Text; - -namespace Mono.Security.Cryptography { - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class CryptoConvert { - - private CryptoConvert () - { - } - - static private int ToInt32LE (byte [] bytes, int offset) - { - return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]; - } - - static private uint ToUInt32LE (byte [] bytes, int offset) - { - return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]); - } - - static private byte [] GetBytesLE (int val) - { - return new byte [] { - (byte) (val & 0xff), - (byte) ((val >> 8) & 0xff), - (byte) ((val >> 16) & 0xff), - (byte) ((val >> 24) & 0xff) - }; - } - - static private byte[] Trim (byte[] array) - { - for (int i=0; i < array.Length; i++) { - if (array [i] != 0x00) { - byte[] result = new byte [array.Length - i]; - Buffer.BlockCopy (array, i, result, 0, result.Length); - return result; - } - } - return null; - } - - // convert the key from PRIVATEKEYBLOB to RSA - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp - // e.g. SNK files, PVK files - static public RSA FromCapiPrivateKeyBlob (byte[] blob) - { - return FromCapiPrivateKeyBlob (blob, 0); - } - - static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) - { - if (blob == null) - throw new ArgumentNullException ("blob"); - if (offset >= blob.Length) - throw new ArgumentException ("blob is too small."); - - RSAParameters rsap = new RSAParameters (); - try { - if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) - (blob [offset+1] != 0x02) || // Version (0x02) - (blob [offset+2] != 0x00) || // Reserved (word) - (blob [offset+3] != 0x00) || - (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2 - throw new CryptographicException ("Invalid blob header"); - - // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) - // int algId = ToInt32LE (blob, offset+4); - - // DWORD bitlen - int bitLen = ToInt32LE (blob, offset+12); - - // DWORD public exponent - byte[] exp = new byte [4]; - Buffer.BlockCopy (blob, offset+16, exp, 0, 4); - Array.Reverse (exp); - rsap.Exponent = Trim (exp); - - int pos = offset+20; - // BYTE modulus[rsapubkey.bitlen/8]; - int byteLen = (bitLen >> 3); - rsap.Modulus = new byte [byteLen]; - Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); - Array.Reverse (rsap.Modulus); - pos += byteLen; - - // BYTE prime1[rsapubkey.bitlen/16]; - int byteHalfLen = (byteLen >> 1); - rsap.P = new byte [byteHalfLen]; - Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); - Array.Reverse (rsap.P); - pos += byteHalfLen; - - // BYTE prime2[rsapubkey.bitlen/16]; - rsap.Q = new byte [byteHalfLen]; - Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); - Array.Reverse (rsap.Q); - pos += byteHalfLen; - - // BYTE exponent1[rsapubkey.bitlen/16]; - rsap.DP = new byte [byteHalfLen]; - Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); - Array.Reverse (rsap.DP); - pos += byteHalfLen; - - // BYTE exponent2[rsapubkey.bitlen/16]; - rsap.DQ = new byte [byteHalfLen]; - Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); - Array.Reverse (rsap.DQ); - pos += byteHalfLen; - - // BYTE coefficient[rsapubkey.bitlen/16]; - rsap.InverseQ = new byte [byteHalfLen]; - Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); - Array.Reverse (rsap.InverseQ); - pos += byteHalfLen; - - // ok, this is hackish but CryptoAPI support it so... - // note: only works because CRT is used by default - // http://bugzilla.ximian.com/show_bug.cgi?id=57941 - rsap.D = new byte [byteLen]; // must be allocated - if (pos + byteLen + offset <= blob.Length) { - // BYTE privateExponent[rsapubkey.bitlen/8]; - Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); - Array.Reverse (rsap.D); - } - } - catch (Exception e) { - throw new CryptographicException ("Invalid blob.", e); - } - -#if NET_2_1 - RSA rsa = RSA.Create (); - rsa.ImportParameters (rsap); -#else - RSA rsa = null; - try { - rsa = RSA.Create (); - rsa.ImportParameters (rsap); - } - catch (CryptographicException ce) { - // this may cause problem when this code is run under - // the SYSTEM identity on Windows (e.g. ASP.NET). See - // http://bugzilla.ximian.com/show_bug.cgi?id=77559 - try { - CspParameters csp = new CspParameters (); - csp.Flags = CspProviderFlags.UseMachineKeyStore; - rsa = new RSACryptoServiceProvider (csp); - rsa.ImportParameters (rsap); - } - catch { - // rethrow original, not the later, exception if this fails - throw ce; - } - } -#endif - return rsa; - } - - static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob) - { - return FromCapiPrivateKeyBlobDSA (blob, 0); - } - - static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob, int offset) - { - if (blob == null) - throw new ArgumentNullException ("blob"); - if (offset >= blob.Length) - throw new ArgumentException ("blob is too small."); - - DSAParameters dsap = new DSAParameters (); - try { - if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) - (blob [offset + 1] != 0x02) || // Version (0x02) - (blob [offset + 2] != 0x00) || // Reserved (word) - (blob [offset + 3] != 0x00) || - (ToUInt32LE (blob, offset + 8) != 0x32535344)) // DWORD magic - throw new CryptographicException ("Invalid blob header"); - - int bitlen = ToInt32LE (blob, offset + 12); - int bytelen = bitlen >> 3; - int pos = offset + 16; - - dsap.P = new byte [bytelen]; - Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen); - Array.Reverse (dsap.P); - pos += bytelen; - - dsap.Q = new byte [20]; - Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20); - Array.Reverse (dsap.Q); - pos += 20; - - dsap.G = new byte [bytelen]; - Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen); - Array.Reverse (dsap.G); - pos += bytelen; - - dsap.X = new byte [20]; - Buffer.BlockCopy (blob, pos, dsap.X, 0, 20); - Array.Reverse (dsap.X); - pos += 20; - - dsap.Counter = ToInt32LE (blob, pos); - pos += 4; - - dsap.Seed = new byte [20]; - Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20); - Array.Reverse (dsap.Seed); - pos += 20; - } - catch (Exception e) { - throw new CryptographicException ("Invalid blob.", e); - } - -#if NET_2_1 - DSA dsa = (DSA)DSA.Create (); - dsa.ImportParameters (dsap); -#else - DSA dsa = null; - try { - dsa = (DSA)DSA.Create (); - dsa.ImportParameters (dsap); - } - catch (CryptographicException ce) { - // this may cause problem when this code is run under - // the SYSTEM identity on Windows (e.g. ASP.NET). See - // http://bugzilla.ximian.com/show_bug.cgi?id=77559 - try { - CspParameters csp = new CspParameters (); - csp.Flags = CspProviderFlags.UseMachineKeyStore; - dsa = new DSACryptoServiceProvider (csp); - dsa.ImportParameters (dsap); - } - catch { - // rethrow original, not the later, exception if this fails - throw ce; - } - } -#endif - return dsa; - } - - static public byte[] ToCapiPrivateKeyBlob (RSA rsa) - { - RSAParameters p = rsa.ExportParameters (true); - int keyLength = p.Modulus.Length; // in bytes - byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)]; - - blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07) - blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) - // [2], [3] // RESERVED - Always 0 - blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) - blob [8] = 0x52; // Magic - RSA2 (ASCII in hex) - blob [9] = 0x53; - blob [10] = 0x41; - blob [11] = 0x32; - - byte[] bitlen = GetBytesLE (keyLength << 3); - blob [12] = bitlen [0]; // bitlen - blob [13] = bitlen [1]; - blob [14] = bitlen [2]; - blob [15] = bitlen [3]; - - // public exponent (DWORD) - int pos = 16; - int n = p.Exponent.Length; - while (n > 0) - blob [pos++] = p.Exponent [--n]; - // modulus - pos = 20; - byte[] part = p.Modulus; - int len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - // private key - part = p.P; - len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - - part = p.Q; - len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - - part = p.DP; - len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - - part = p.DQ; - len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - - part = p.InverseQ; - len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - - part = p.D; - len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - - return blob; - } - - static public byte[] ToCapiPrivateKeyBlob (DSA dsa) - { - DSAParameters p = dsa.ExportParameters (true); - int keyLength = p.P.Length; // in bytes - - // header + P + Q + G + X + count + seed - byte[] blob = new byte [16 + keyLength + 20 + keyLength + 20 + 4 + 20]; - - blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07) - blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) - // [2], [3] // RESERVED - Always 0 - blob [5] = 0x22; // ALGID - blob [8] = 0x44; // Magic - blob [9] = 0x53; - blob [10] = 0x53; - blob [11] = 0x32; - - byte[] bitlen = GetBytesLE (keyLength << 3); - blob [12] = bitlen [0]; - blob [13] = bitlen [1]; - blob [14] = bitlen [2]; - blob [15] = bitlen [3]; - - int pos = 16; - byte[] part = p.P; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, keyLength); - pos += keyLength; - - part = p.Q; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, 20); - pos += 20; - - part = p.G; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, keyLength); - pos += keyLength; - - part = p.X; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, 20); - pos += 20; - - Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4); - pos += 4; - - part = p.Seed; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, 20); - - return blob; - } - - static public RSA FromCapiPublicKeyBlob (byte[] blob) - { - return FromCapiPublicKeyBlob (blob, 0); - } - - static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset) - { - if (blob == null) - throw new ArgumentNullException ("blob"); - if (offset >= blob.Length) - throw new ArgumentException ("blob is too small."); - - try { - if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) - (blob [offset+1] != 0x02) || // Version (0x02) - (blob [offset+2] != 0x00) || // Reserved (word) - (blob [offset+3] != 0x00) || - (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1 - throw new CryptographicException ("Invalid blob header"); - - // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) - // int algId = ToInt32LE (blob, offset+4); - - // DWORD bitlen - int bitLen = ToInt32LE (blob, offset+12); - - // DWORD public exponent - RSAParameters rsap = new RSAParameters (); - rsap.Exponent = new byte [3]; - rsap.Exponent [0] = blob [offset+18]; - rsap.Exponent [1] = blob [offset+17]; - rsap.Exponent [2] = blob [offset+16]; - - int pos = offset+20; - // BYTE modulus[rsapubkey.bitlen/8]; - int byteLen = (bitLen >> 3); - rsap.Modulus = new byte [byteLen]; - Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); - Array.Reverse (rsap.Modulus); -#if NET_2_1 - RSA rsa = RSA.Create (); - rsa.ImportParameters (rsap); -#else - RSA rsa = null; - try { - rsa = RSA.Create (); - rsa.ImportParameters (rsap); - } - catch (CryptographicException) { - // this may cause problem when this code is run under - // the SYSTEM identity on Windows (e.g. ASP.NET). See - // http://bugzilla.ximian.com/show_bug.cgi?id=77559 - CspParameters csp = new CspParameters (); - csp.Flags = CspProviderFlags.UseMachineKeyStore; - rsa = new RSACryptoServiceProvider (csp); - rsa.ImportParameters (rsap); - } -#endif - return rsa; - } - catch (Exception e) { - throw new CryptographicException ("Invalid blob.", e); - } - } - - static public DSA FromCapiPublicKeyBlobDSA (byte[] blob) - { - return FromCapiPublicKeyBlobDSA (blob, 0); - } - - static public DSA FromCapiPublicKeyBlobDSA (byte[] blob, int offset) - { - if (blob == null) - throw new ArgumentNullException ("blob"); - if (offset >= blob.Length) - throw new ArgumentException ("blob is too small."); - - try { - if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) - (blob [offset + 1] != 0x02) || // Version (0x02) - (blob [offset + 2] != 0x00) || // Reserved (word) - (blob [offset + 3] != 0x00) || - (ToUInt32LE (blob, offset + 8) != 0x31535344)) // DWORD magic - throw new CryptographicException ("Invalid blob header"); - - int bitlen = ToInt32LE (blob, offset + 12); - DSAParameters dsap = new DSAParameters (); - int bytelen = bitlen >> 3; - int pos = offset + 16; - - dsap.P = new byte [bytelen]; - Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen); - Array.Reverse (dsap.P); - pos += bytelen; - - dsap.Q = new byte [20]; - Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20); - Array.Reverse (dsap.Q); - pos += 20; - - dsap.G = new byte [bytelen]; - Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen); - Array.Reverse (dsap.G); - pos += bytelen; - - dsap.Y = new byte [bytelen]; - Buffer.BlockCopy (blob, pos, dsap.Y, 0, bytelen); - Array.Reverse (dsap.Y); - pos += bytelen; - - dsap.Counter = ToInt32LE (blob, pos); - pos += 4; - - dsap.Seed = new byte [20]; - Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20); - Array.Reverse (dsap.Seed); - pos += 20; - - DSA dsa = (DSA)DSA.Create (); - dsa.ImportParameters (dsap); - return dsa; - } - catch (Exception e) { - throw new CryptographicException ("Invalid blob.", e); - } - } - - static public byte[] ToCapiPublicKeyBlob (RSA rsa) - { - RSAParameters p = rsa.ExportParameters (false); - int keyLength = p.Modulus.Length; // in bytes - byte[] blob = new byte [20 + keyLength]; - - blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) - blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) - // [2], [3] // RESERVED - Always 0 - blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) - blob [8] = 0x52; // Magic - RSA1 (ASCII in hex) - blob [9] = 0x53; - blob [10] = 0x41; - blob [11] = 0x31; - - byte[] bitlen = GetBytesLE (keyLength << 3); - blob [12] = bitlen [0]; // bitlen - blob [13] = bitlen [1]; - blob [14] = bitlen [2]; - blob [15] = bitlen [3]; - - // public exponent (DWORD) - int pos = 16; - int n = p.Exponent.Length; - while (n > 0) - blob [pos++] = p.Exponent [--n]; - // modulus - pos = 20; - byte[] part = p.Modulus; - int len = part.Length; - Array.Reverse (part, 0, len); - Buffer.BlockCopy (part, 0, blob, pos, len); - pos += len; - return blob; - } - - static public byte[] ToCapiPublicKeyBlob (DSA dsa) - { - DSAParameters p = dsa.ExportParameters (false); - int keyLength = p.P.Length; // in bytes - - // header + P + Q + G + Y + count + seed - byte[] blob = new byte [16 + keyLength + 20 + keyLength + keyLength + 4 + 20]; - - blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) - blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) - // [2], [3] // RESERVED - Always 0 - blob [5] = 0x22; // ALGID - blob [8] = 0x44; // Magic - blob [9] = 0x53; - blob [10] = 0x53; - blob [11] = 0x31; - - byte[] bitlen = GetBytesLE (keyLength << 3); - blob [12] = bitlen [0]; - blob [13] = bitlen [1]; - blob [14] = bitlen [2]; - blob [15] = bitlen [3]; - - int pos = 16; - byte[] part; - - part = p.P; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, keyLength); - pos += keyLength; - - part = p.Q; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, 20); - pos += 20; - - part = p.G; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, keyLength); - pos += keyLength; - - part = p.Y; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, keyLength); - pos += keyLength; - - Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4); - pos += 4; - - part = p.Seed; - Array.Reverse (part); - Buffer.BlockCopy (part, 0, blob, pos, 20); - - return blob; - } - - // PRIVATEKEYBLOB - // PUBLICKEYBLOB - static public RSA FromCapiKeyBlob (byte[] blob) - { - return FromCapiKeyBlob (blob, 0); - } - - static public RSA FromCapiKeyBlob (byte[] blob, int offset) - { - if (blob == null) - throw new ArgumentNullException ("blob"); - if (offset >= blob.Length) - throw new ArgumentException ("blob is too small."); - - switch (blob [offset]) { - case 0x00: - // this could be a public key inside an header - // like "sn -e" would produce - if (blob [offset + 12] == 0x06) { - return FromCapiPublicKeyBlob (blob, offset + 12); - } - break; - case 0x06: - return FromCapiPublicKeyBlob (blob, offset); - case 0x07: - return FromCapiPrivateKeyBlob (blob, offset); - } - throw new CryptographicException ("Unknown blob format."); - } - - static public DSA FromCapiKeyBlobDSA (byte[] blob) - { - return FromCapiKeyBlobDSA (blob, 0); - } - - static public DSA FromCapiKeyBlobDSA (byte[] blob, int offset) - { - if (blob == null) - throw new ArgumentNullException ("blob"); - if (offset >= blob.Length) - throw new ArgumentException ("blob is too small."); - - switch (blob [offset]) { - case 0x06: - return FromCapiPublicKeyBlobDSA (blob, offset); - case 0x07: - return FromCapiPrivateKeyBlobDSA (blob, offset); - } - throw new CryptographicException ("Unknown blob format."); - } - - static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey) - { - if (keypair == null) - throw new ArgumentNullException ("keypair"); - - // check between RSA and DSA (and potentially others like DH) - if (keypair is RSA) - return ToCapiKeyBlob ((RSA)keypair, includePrivateKey); - else if (keypair is DSA) - return ToCapiKeyBlob ((DSA)keypair, includePrivateKey); - else - return null; // TODO - } - - static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey) - { - if (rsa == null) - throw new ArgumentNullException ("rsa"); - - if (includePrivateKey) - return ToCapiPrivateKeyBlob (rsa); - else - return ToCapiPublicKeyBlob (rsa); - } - - static public byte[] ToCapiKeyBlob (DSA dsa, bool includePrivateKey) - { - if (dsa == null) - throw new ArgumentNullException ("dsa"); - - if (includePrivateKey) - return ToCapiPrivateKeyBlob (dsa); - else - return ToCapiPublicKeyBlob (dsa); - } - - static public string ToHex (byte[] input) - { - if (input == null) - return null; - - StringBuilder sb = new StringBuilder (input.Length * 2); - foreach (byte b in input) { - sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture)); - } - return sb.ToString (); - } - - static private byte FromHexChar (char c) - { - if ((c >= 'a') && (c <= 'f')) - return (byte) (c - 'a' + 10); - if ((c >= 'A') && (c <= 'F')) - return (byte) (c - 'A' + 10); - if ((c >= '0') && (c <= '9')) - return (byte) (c - '0'); - throw new ArgumentException ("invalid hex char"); - } - - static public byte[] FromHex (string hex) - { - if (hex == null) - return null; - if ((hex.Length & 0x1) == 0x1) - throw new ArgumentException ("Length must be a multiple of 2"); - - byte[] result = new byte [hex.Length >> 1]; - int n = 0; - int i = 0; - while (n < result.Length) { - result [n] = (byte) (FromHexChar (hex [i++]) << 4); - result [n++] += FromHexChar (hex [i++]); - } - return result; - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Cryptography/CryptoTools.cs b/mcs/class/corlib/Mono.Security.Cryptography/CryptoTools.cs deleted file mode 100644 index a528714f861..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/CryptoTools.cs +++ /dev/null @@ -1,143 +0,0 @@ -// -// Mono.Security.Cryptography.CryptoTools -// Shared class for common cryptographic functionalities -// -// Authors: -// Sebastien Pouliot -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004, 2008 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Security.Cryptography; - -namespace Mono.Security.Cryptography { - -#if INSIDE_CORLIB || INSIDE_SYSCORE - internal -#else - public -#endif - sealed class KeyBuilder { - - static private RandomNumberGenerator rng; - - private KeyBuilder () - { - } - - static RandomNumberGenerator Rng { - get { - if (rng == null) - rng = RandomNumberGenerator.Create (); - return rng; - } - } - - static public byte[] Key (int size) - { - byte[] key = new byte [size]; - Rng.GetBytes (key); - return key; - } - - static public byte[] IV (int size) - { - byte[] iv = new byte [size]; - Rng.GetBytes (iv); - return iv; - } - } - - // Process an array as a sequence of blocks -#if INSIDE_CORLIB || INSIDE_SYSCORE - internal -#else - public -#endif - class BlockProcessor { - private ICryptoTransform transform; - private byte[] block; - private int blockSize; // in bytes (not in bits) - private int blockCount; - - public BlockProcessor (ICryptoTransform transform) - : this (transform, transform.InputBlockSize) {} - - // some Transforms (like HashAlgorithm descendant) return 1 for - // block size (which isn't their real internal block size) - public BlockProcessor (ICryptoTransform transform, int blockSize) - { - this.transform = transform; - this.blockSize = blockSize; - block = new byte [blockSize]; - } - - ~BlockProcessor () - { - // zeroize our block (so we don't retain any information) - Array.Clear (block, 0, blockSize); - } - - public void Initialize () - { - Array.Clear (block, 0, blockSize); - blockCount = 0; - } - - public void Core (byte[] rgb) - { - Core (rgb, 0, rgb.Length); - } - - public void Core (byte[] rgb, int ib, int cb) - { - // 1. fill the rest of the "block" - int n = System.Math.Min (blockSize - blockCount, cb); - Buffer.BlockCopy (rgb, ib, block, blockCount, n); - blockCount += n; - - // 2. if block is full then transform it - if (blockCount == blockSize) { - transform.TransformBlock (block, 0, blockSize, block, 0); - - // 3. transform any other full block in specified buffer - int b = (int) ((cb - n) / blockSize); - for (int i=0; i < b; i++) { - transform.TransformBlock (rgb, n + ib, blockSize, block, 0); - n += blockSize; - } - - // 4. if data is still present fill the "block" with the remainder - blockCount = cb - n; - if (blockCount > 0) - Buffer.BlockCopy (rgb, n + ib, block, 0, blockCount); - } - } - - public byte[] Final () - { - return transform.TransformFinalBlock (block, 0, blockCount); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Cryptography/KeyPairPersistence.cs b/mcs/class/corlib/Mono.Security.Cryptography/KeyPairPersistence.cs deleted file mode 100644 index 0615770aaf5..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/KeyPairPersistence.cs +++ /dev/null @@ -1,454 +0,0 @@ -// -// KeyPairPersistence.cs: Keypair persistence -// -// Author: -// Sebastien Pouliot -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.Cryptography; -using System.Security.Permissions; -using System.Text; - -using Mono.Xml; - -namespace Mono.Security.Cryptography { - - /* File name - * [type][unique name][key number].xml - * - * where - * type CspParameters.ProviderType - * unique name A unique name for the keypair, which is - * a. default (for a provider default keypair) - * b. a GUID derived from - * i. random if no container name was - * specified at generation time - * ii. the MD5 hash of the container - * name (CspParameters.KeyContainerName) - * key number CspParameters.KeyNumber - * - * File format - * - * - * - * - * - * - * RSAKeyValue, DSAKeyValue ... - * - * - */ - - /* NOTES - * - * - There's NO confidentiality / integrity built in this - * persistance mechanism. The container directories (both user and - * machine) are created with restrited ACL. The ACL is also checked - * when a key is accessed (so totally public keys won't be used). - * see /mono/mono/metadata/security.c for implementation - * - * - As we do not use CSP we limit ourselves to provider types (not - * names). This means that for a same type and container type, but - * two different provider names) will return the same keypair. This - * should work as CspParameters always requires a csp type in its - * constructors. - * - * - Assert (CAS) are used so only the OS permission will limit access - * to the keypair files. I.e. this will work even in high-security - * scenarios where users do not have access to file system (e.g. web - * application). We can allow this because the filename used is - * TOTALLY under our control (no direct user input is used). - * - * - You CAN'T changes properties of the keypair once it's been - * created (saved). You must remove the container than save it - * back. This is the same behaviour as CSP under Windows. - */ - -#if INSIDE_CORLIB - internal -#else - public -#endif - class KeyPairPersistence { - - private static bool _userPathExists; // check at 1st use - private static string _userPath; - - private static bool _machinePathExists; // check at 1st use - private static string _machinePath; - - private CspParameters _params; - private string _keyvalue; - private string _filename; - private string _container; - - // constructors - - public KeyPairPersistence (CspParameters parameters) - : this (parameters, null) - { - } - - public KeyPairPersistence (CspParameters parameters, string keyPair) - { - if (parameters == null) - throw new ArgumentNullException ("parameters"); - - _params = Copy (parameters); - _keyvalue = keyPair; - } - - // properties - - public string Filename { - get { - if (_filename == null) { - _filename = String.Format (CultureInfo.InvariantCulture, - "[{0}][{1}][{2}].xml", - _params.ProviderType, - this.ContainerName, - _params.KeyNumber); - if (UseMachineKeyStore) - _filename = Path.Combine (MachinePath, _filename); - else - _filename = Path.Combine (UserPath, _filename); - } - return _filename; - } - } - - public string KeyValue { - get { return _keyvalue; } - set { - if (this.CanChange) - _keyvalue = value; - } - } - - // return a (read-only) copy - public CspParameters Parameters { - get { return Copy (_params); } - } - - // methods - - public bool Load () - { - // see NOTES -// FIXME new FileIOPermission (FileIOPermissionAccess.Read, this.Filename).Assert (); - - bool result = File.Exists (this.Filename); - if (result) { - using (StreamReader sr = File.OpenText (this.Filename)) { - FromXml (sr.ReadToEnd ()); - } - } - return result; - } - - public void Save () - { - // see NOTES -// FIXME new FileIOPermission (FileIOPermissionAccess.Write, this.Filename).Assert (); - - using (FileStream fs = File.Open (this.Filename, FileMode.Create)) { - StreamWriter sw = new StreamWriter (fs, Encoding.UTF8); - sw.Write (this.ToXml ()); - sw.Close (); - } - // apply protection to newly created files - if (UseMachineKeyStore) - ProtectMachine (Filename); - else - ProtectUser (Filename); - } - - public void Remove () - { - // see NOTES -// FIXME new FileIOPermission (FileIOPermissionAccess.Write, this.Filename).Assert (); - - File.Delete (this.Filename); - // it's now possible to change the keypair un the container - } - - // private static stuff - - static object lockobj = new object (); - - private static string UserPath { - get { - lock (lockobj) { - if ((_userPath == null) || (!_userPathExists)) { - _userPath = Path.Combine ( - Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), - ".mono"); - _userPath = Path.Combine (_userPath, "keypairs"); - - _userPathExists = Directory.Exists (_userPath); - if (!_userPathExists) { - try { - Directory.CreateDirectory (_userPath); - ProtectUser (_userPath); - _userPathExists = true; - } - catch (Exception e) { - string msg = Locale.GetText ("Could not create user key store '{0}'."); - throw new CryptographicException (String.Format (msg, _userPath), e); - } - } - } - } - // is it properly protected ? - if (!IsUserProtected (_userPath)) { - string msg = Locale.GetText ("Improperly protected user's key pairs in '{0}'."); - throw new CryptographicException (String.Format (msg, _userPath)); - } - return _userPath; - } - } - - private static string MachinePath { - get { - lock (lockobj) { - if ((_machinePath == null) || (!_machinePathExists)) { - _machinePath = Path.Combine ( - Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData), - ".mono"); - _machinePath = Path.Combine (_machinePath, "keypairs"); - - _machinePathExists = Directory.Exists (_machinePath); - if (!_machinePathExists) { - try { - Directory.CreateDirectory (_machinePath); - ProtectMachine (_machinePath); - _machinePathExists = true; - } - catch (Exception e) { - string msg = Locale.GetText ("Could not create machine key store '{0}'."); - throw new CryptographicException (String.Format (msg, _machinePath), e); - } - } - } - } - // is it properly protected ? - if (!IsMachineProtected (_machinePath)) { - string msg = Locale.GetText ("Improperly protected machine's key pairs in '{0}'."); - throw new CryptographicException (String.Format (msg, _machinePath)); - } - return _machinePath; - } - } - -#if INSIDE_CORLIB - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal static extern bool _CanSecure (string root); - - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal static extern bool _ProtectUser (string path); - - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal static extern bool _ProtectMachine (string path); - - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal static extern bool _IsUserProtected (string path); - - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal static extern bool _IsMachineProtected (string path); -#else - // Mono.Security.dll assembly can't use the internal - // call (and still run with other runtimes) - - // Note: Class is only available in Mono.Security.dll as - // a management helper (e.g. build a GUI app) - - internal static bool _CanSecure (string root) - { - return true; - } - - internal static bool _ProtectUser (string path) - { - return true; - } - - internal static bool _ProtectMachine (string path) - { - return true; - } - - internal static bool _IsUserProtected (string path) - { - return true; - } - - internal static bool _IsMachineProtected (string path) - { - return true; - } -#endif - // private stuff - - private static bool CanSecure (string path) - { - // we assume POSIX filesystems can always be secured - - // check for Unix platforms - see FAQ for more details - // http://www.mono-project.com/FAQ:_Technical#How_to_detect_the_execution_platform_.3F - int platform = (int) Environment.OSVersion.Platform; - if ((platform == 4) || (platform == 128) || (platform == 6)) - return true; - - // while we ask the runtime for Windows OS - return _CanSecure (Path.GetPathRoot (path)); - } - - private static bool ProtectUser (string path) - { - // we cannot protect on some filsystem (like FAT) - if (CanSecure (path)) { - return _ProtectUser (path); - } - // but Mono still needs to run on them :( - return true; - } - - private static bool ProtectMachine (string path) - { - // we cannot protect on some filsystem (like FAT) - if (CanSecure (path)) { - return _ProtectMachine (path); - } - // but Mono still needs to run on them :( - return true; - } - - private static bool IsUserProtected (string path) - { - // we cannot protect on some filsystem (like FAT) - if (CanSecure (path)) { - return _IsUserProtected (path); - } - // but Mono still needs to run on them :( - return true; - } - - private static bool IsMachineProtected (string path) - { - // we cannot protect on some filsystem (like FAT) - if (CanSecure (path)) { - return _IsMachineProtected (path); - } - // but Mono still needs to run on them :( - return true; - } - - private bool CanChange { - get { return (_keyvalue == null); } - } - - private bool UseDefaultKeyContainer { - get { return ((_params.Flags & CspProviderFlags.UseDefaultKeyContainer) == CspProviderFlags.UseDefaultKeyContainer); } - } - - private bool UseMachineKeyStore { - get { return ((_params.Flags & CspProviderFlags.UseMachineKeyStore) == CspProviderFlags.UseMachineKeyStore); } - } - - private string ContainerName { - get { - if (_container == null) { - if (UseDefaultKeyContainer) { - // easy to spot - _container = "default"; - } - else if ((_params.KeyContainerName == null) || (_params.KeyContainerName.Length == 0)) { - _container = Guid.NewGuid ().ToString (); - } - else { - // we don't want to trust the key container name as we don't control it - // anyway some characters may not be compatible with the file system - byte[] data = Encoding.UTF8.GetBytes (_params.KeyContainerName); - // Note: We use MD5 as it is faster than SHA1 and has the same length - // as a GUID. Recent problems found in MD5 (like collisions) aren't a - // problem in this case. - MD5 hash = MD5.Create (); - byte[] result = hash.ComputeHash (data); - _container = new Guid (result).ToString (); - } - } - return _container; - } - } - - // we do not want any changes after receiving the csp informations - private CspParameters Copy (CspParameters p) - { - CspParameters copy = new CspParameters (p.ProviderType, p.ProviderName, p.KeyContainerName); - copy.KeyNumber = p.KeyNumber; - copy.Flags = p.Flags; - return copy; - } - - private void FromXml (string xml) - { - SecurityParser sp = new SecurityParser (); - sp.LoadXml (xml); - - SecurityElement root = sp.ToXml (); - if (root.Tag == "KeyPair") { - //SecurityElement prop = root.SearchForChildByTag ("Properties"); - SecurityElement keyv = root.SearchForChildByTag ("KeyValue"); - if (keyv.Children.Count > 0) - _keyvalue = keyv.Children [0].ToString (); - // Note: we do not read other stuff because - // it can't be changed after key creation - } - } - - private string ToXml () - { - // note: we do not use SecurityElement here because the - // keypair is a XML string (requiring parsing) - StringBuilder xml = new StringBuilder (); - xml.AppendFormat ("{0}\t{0}\t\t{1}\t\t{1}\t{1}\t{1}\t\t{0}{1}\t{1}{1}", this.KeyValue, Environment.NewLine); - return xml.ToString (); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs b/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs deleted file mode 100644 index 3b3252db949..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs +++ /dev/null @@ -1,416 +0,0 @@ -// -// PKCS1.cs - Implements PKCS#1 primitives. -// -// Author: -// Sebastien Pouliot -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Security.Cryptography; - -namespace Mono.Security.Cryptography { - - // References: - // a. PKCS#1: RSA Cryptography Standard - // http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/index.html - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class PKCS1 { - - private PKCS1 () - { - } - - private static bool Compare (byte[] array1, byte[] array2) - { - bool result = (array1.Length == array2.Length); - if (result) { - for (int i=0; i < array1.Length; i++) - if (array1[i] != array2[i]) - return false; - } - return result; - } - - private static byte[] xor (byte[] array1, byte[] array2) - { - byte[] result = new byte [array1.Length]; - for (int i=0; i < result.Length; i++) - result[i] = (byte) (array1[i] ^ array2[i]); - return result; - } - - private static byte[] emptySHA1 = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 }; - private static byte[] emptySHA256 = { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }; - private static byte[] emptySHA384 = { 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b }; - private static byte[] emptySHA512 = { 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e }; - - private static byte[] GetEmptyHash (HashAlgorithm hash) - { - if (hash is SHA1) - return emptySHA1; - else if (hash is SHA256) - return emptySHA256; - else if (hash is SHA384) - return emptySHA384; - else if (hash is SHA512) - return emptySHA512; - else - return hash.ComputeHash ((byte[])null); - } - - // PKCS #1 v.2.1, Section 4.1 - // I2OSP converts a non-negative integer to an octet string of a specified length. - public static byte[] I2OSP (int x, int size) - { - byte[] array = BitConverterLE.GetBytes (x); - Array.Reverse (array, 0, array.Length); - return I2OSP (array, size); - } - - public static byte[] I2OSP (byte[] x, int size) - { - byte[] result = new byte [size]; - Buffer.BlockCopy (x, 0, result, (result.Length - x.Length), x.Length); - return result; - } - - // PKCS #1 v.2.1, Section 4.2 - // OS2IP converts an octet string to a nonnegative integer. - public static byte[] OS2IP (byte[] x) - { - int i = 0; - while ((x [i++] == 0x00) && (i < x.Length)) { - // confuse compiler into reporting a warning with {} - } - i--; - if (i > 0) { - byte[] result = new byte [x.Length - i]; - Buffer.BlockCopy (x, i, result, 0, result.Length); - return result; - } - else - return x; - } - - // PKCS #1 v.2.1, Section 5.1.1 - public static byte[] RSAEP (RSA rsa, byte[] m) - { - // c = m^e mod n - return rsa.EncryptValue (m); - } - - // PKCS #1 v.2.1, Section 5.1.2 - public static byte[] RSADP (RSA rsa, byte[] c) - { - // m = c^d mod n - // Decrypt value may apply CRT optimizations - return rsa.DecryptValue (c); - } - - // PKCS #1 v.2.1, Section 5.2.1 - public static byte[] RSASP1 (RSA rsa, byte[] m) - { - // first form: s = m^d mod n - // Decrypt value may apply CRT optimizations - return rsa.DecryptValue (m); - } - - // PKCS #1 v.2.1, Section 5.2.2 - public static byte[] RSAVP1 (RSA rsa, byte[] s) - { - // m = s^e mod n - return rsa.EncryptValue (s); - } - - // PKCS #1 v.2.1, Section 7.1.1 - // RSAES-OAEP-ENCRYPT ((n, e), M, L) - public static byte[] Encrypt_OAEP (RSA rsa, HashAlgorithm hash, RandomNumberGenerator rng, byte[] M) - { - int size = rsa.KeySize / 8; - int hLen = hash.HashSize / 8; - if (M.Length > size - 2 * hLen - 2) - throw new CryptographicException ("message too long"); - // empty label L SHA1 hash - byte[] lHash = GetEmptyHash (hash); - int PSLength = (size - M.Length - 2 * hLen - 2); - // DB = lHash || PS || 0x01 || M - byte[] DB = new byte [lHash.Length + PSLength + 1 + M.Length]; - Buffer.BlockCopy (lHash, 0, DB, 0, lHash.Length); - DB [(lHash.Length + PSLength)] = 0x01; - Buffer.BlockCopy (M, 0, DB, (DB.Length - M.Length), M.Length); - - byte[] seed = new byte [hLen]; - rng.GetBytes (seed); - - byte[] dbMask = MGF1 (hash, seed, size - hLen - 1); - byte[] maskedDB = xor (DB, dbMask); - byte[] seedMask = MGF1 (hash, maskedDB, hLen); - byte[] maskedSeed = xor (seed, seedMask); - // EM = 0x00 || maskedSeed || maskedDB - byte[] EM = new byte [maskedSeed.Length + maskedDB.Length + 1]; - Buffer.BlockCopy (maskedSeed, 0, EM, 1, maskedSeed.Length); - Buffer.BlockCopy (maskedDB, 0, EM, maskedSeed.Length + 1, maskedDB.Length); - - byte[] m = OS2IP (EM); - byte[] c = RSAEP (rsa, m); - return I2OSP (c, size); - } - - // PKCS #1 v.2.1, Section 7.1.2 - // RSAES-OAEP-DECRYPT (K, C, L) - public static byte[] Decrypt_OAEP (RSA rsa, HashAlgorithm hash, byte[] C) - { - int size = rsa.KeySize / 8; - int hLen = hash.HashSize / 8; - if ((size < (2 * hLen + 2)) || (C.Length != size)) - throw new CryptographicException ("decryption error"); - - byte[] c = OS2IP (C); - byte[] m = RSADP (rsa, c); - byte[] EM = I2OSP (m, size); - - // split EM = Y || maskedSeed || maskedDB - byte[] maskedSeed = new byte [hLen]; - Buffer.BlockCopy (EM, 1, maskedSeed, 0, maskedSeed.Length); - byte[] maskedDB = new byte [size - hLen - 1]; - Buffer.BlockCopy (EM, (EM.Length - maskedDB.Length), maskedDB, 0, maskedDB.Length); - - byte[] seedMask = MGF1 (hash, maskedDB, hLen); - byte[] seed = xor (maskedSeed, seedMask); - byte[] dbMask = MGF1 (hash, seed, size - hLen - 1); - byte[] DB = xor (maskedDB, dbMask); - - byte[] lHash = GetEmptyHash (hash); - // split DB = lHash' || PS || 0x01 || M - byte[] dbHash = new byte [lHash.Length]; - Buffer.BlockCopy (DB, 0, dbHash, 0, dbHash.Length); - bool h = Compare (lHash, dbHash); - - // find separator 0x01 - int nPos = lHash.Length; - while (DB[nPos] == 0) - nPos++; - - int Msize = DB.Length - nPos - 1; - byte[] M = new byte [Msize]; - Buffer.BlockCopy (DB, (nPos + 1), M, 0, Msize); - - // we could have returned EM[0] sooner but would be helping a timing attack - if ((EM[0] != 0) || (!h) || (DB[nPos] != 0x01)) - return null; - return M; - } - - // PKCS #1 v.2.1, Section 7.2.1 - // RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M) - public static byte[] Encrypt_v15 (RSA rsa, RandomNumberGenerator rng, byte[] M) - { - int size = rsa.KeySize / 8; - if (M.Length > size - 11) - throw new CryptographicException ("message too long"); - int PSLength = System.Math.Max (8, (size - M.Length - 3)); - byte[] PS = new byte [PSLength]; - rng.GetNonZeroBytes (PS); - byte[] EM = new byte [size]; - EM [1] = 0x02; - Buffer.BlockCopy (PS, 0, EM, 2, PSLength); - Buffer.BlockCopy (M, 0, EM, (size - M.Length), M.Length); - - byte[] m = OS2IP (EM); - byte[] c = RSAEP (rsa, m); - byte[] C = I2OSP (c, size); - return C; - } - - // PKCS #1 v.2.1, Section 7.2.2 - // RSAES-PKCS1-V1_5-DECRYPT (K, C) - public static byte[] Decrypt_v15 (RSA rsa, byte[] C) - { - int size = rsa.KeySize >> 3; // div by 8 - if ((size < 11) || (C.Length > size)) - throw new CryptographicException ("decryption error"); - byte[] c = OS2IP (C); - byte[] m = RSADP (rsa, c); - byte[] EM = I2OSP (m, size); - - if ((EM [0] != 0x00) || (EM [1] != 0x02)) - return null; - - int mPos = 10; - // PS is a minimum of 8 bytes + 2 bytes for header - while ((EM [mPos] != 0x00) && (mPos < EM.Length)) - mPos++; - if (EM [mPos] != 0x00) - return null; - mPos++; - byte[] M = new byte [EM.Length - mPos]; - Buffer.BlockCopy (EM, mPos, M, 0, M.Length); - return M; - } - - // PKCS #1 v.2.1, Section 8.2.1 - // RSASSA-PKCS1-V1_5-SIGN (K, M) - public static byte[] Sign_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue) - { - int size = (rsa.KeySize >> 3); // div 8 - byte[] EM = Encode_v15 (hash, hashValue, size); - byte[] m = OS2IP (EM); - byte[] s = RSASP1 (rsa, m); - byte[] S = I2OSP (s, size); - return S; - } - - // PKCS #1 v.2.1, Section 8.2.2 - // RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S) - public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue, byte[] signature) - { - return Verify_v15 (rsa, hash, hashValue, signature, false); - } - - // DO NOT USE WITHOUT A VERY GOOD REASON - public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte [] hashValue, byte [] signature, bool tryNonStandardEncoding) - { - int size = (rsa.KeySize >> 3); // div 8 - byte[] s = OS2IP (signature); - byte[] m = RSAVP1 (rsa, s); - byte[] EM2 = I2OSP (m, size); - byte[] EM = Encode_v15 (hash, hashValue, size); - bool result = Compare (EM, EM2); - if (result || !tryNonStandardEncoding) - return result; - - // NOTE: some signatures don't include the hash OID (pretty lame but real) - // and compatible with MS implementation. E.g. Verisign Authenticode Timestamps - - // we're making this "as safe as possible" - if ((EM2 [0] != 0x00) || (EM2 [1] != 0x01)) - return false; - int i; - for (i = 2; i < EM2.Length - hashValue.Length - 1; i++) { - if (EM2 [i] != 0xFF) - return false; - } - if (EM2 [i++] != 0x00) - return false; - - byte [] decryptedHash = new byte [hashValue.Length]; - Buffer.BlockCopy (EM2, i, decryptedHash, 0, decryptedHash.Length); - return Compare (decryptedHash, hashValue); - } - - // PKCS #1 v.2.1, Section 9.2 - // EMSA-PKCS1-v1_5-Encode - public static byte[] Encode_v15 (HashAlgorithm hash, byte[] hashValue, int emLength) - { - if (hashValue.Length != (hash.HashSize >> 3)) - throw new CryptographicException ("bad hash length for " + hash.ToString ()); - - // DigestInfo ::= SEQUENCE { - // digestAlgorithm AlgorithmIdentifier, - // digest OCTET STRING - // } - - byte[] t = null; - - string oid = CryptoConfig.MapNameToOID (hash.ToString ()); - if (oid != null) - { - ASN1 digestAlgorithm = new ASN1 (0x30); - digestAlgorithm.Add (new ASN1 (CryptoConfig.EncodeOID (oid))); - digestAlgorithm.Add (new ASN1 (0x05)); // NULL - ASN1 digest = new ASN1 (0x04, hashValue); - ASN1 digestInfo = new ASN1 (0x30); - digestInfo.Add (digestAlgorithm); - digestInfo.Add (digest); - - t = digestInfo.GetBytes (); - } - else - { - // There are no valid OID, in this case t = hashValue - // This is the case of the MD5SHA hash algorithm - t = hashValue; - } - - Buffer.BlockCopy (hashValue, 0, t, t.Length - hashValue.Length, hashValue.Length); - - int PSLength = System.Math.Max (8, emLength - t.Length - 3); - // PS = PSLength of 0xff - - // EM = 0x00 | 0x01 | PS | 0x00 | T - byte[] EM = new byte [PSLength + t.Length + 3]; - EM [1] = 0x01; - for (int i=2; i < PSLength + 2; i++) - EM[i] = 0xff; - Buffer.BlockCopy (t, 0, EM, PSLength + 3, t.Length); - - return EM; - } - - // PKCS #1 v.2.1, Section B.2.1 - public static byte[] MGF1 (HashAlgorithm hash, byte[] mgfSeed, int maskLen) - { - // 1. If maskLen > 2^32 hLen, output "mask too long" and stop. - // easy - this is impossible by using a int (31bits) as parameter ;-) - // BUT with a signed int we do have to check for negative values! - if (maskLen < 0) - throw new OverflowException(); - - int mgfSeedLength = mgfSeed.Length; - int hLen = (hash.HashSize >> 3); // from bits to bytes - int iterations = (maskLen / hLen); - if (maskLen % hLen != 0) - iterations++; - // 2. Let T be the empty octet string. - byte[] T = new byte [iterations * hLen]; - - byte[] toBeHashed = new byte [mgfSeedLength + 4]; - int pos = 0; - // 3. For counter from 0 to \ceil (maskLen / hLen) - 1, do the following: - for (int counter = 0; counter < iterations; counter++) { - // a. Convert counter to an octet string C of length 4 octets - byte[] C = I2OSP (counter, 4); - - // b. Concatenate the hash of the seed mgfSeed and C to the octet string T: - // T = T || Hash (mgfSeed || C) - Buffer.BlockCopy (mgfSeed, 0, toBeHashed, 0, mgfSeedLength); - Buffer.BlockCopy (C, 0, toBeHashed, mgfSeedLength, 4); - byte[] output = hash.ComputeHash (toBeHashed); - Buffer.BlockCopy (output, 0, T, pos, hLen); - pos += hLen; - } - - // 4. Output the leading maskLen octets of T as the octet string mask. - byte[] mask = new byte [maskLen]; - Buffer.BlockCopy (T, 0, mask, 0, maskLen); - return mask; - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Cryptography/PKCS8.cs b/mcs/class/corlib/Mono.Security.Cryptography/PKCS8.cs deleted file mode 100644 index d26b85c9c75..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/PKCS8.cs +++ /dev/null @@ -1,500 +0,0 @@ -// -// PKCS8.cs: PKCS #8 - Private-Key Information Syntax Standard -// ftp://ftp.rsasecurity.com/pub/pkcs/doc/pkcs-8.doc -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.Security.Cryptography; -using System.Text; - -using Mono.Security.X509; - -namespace Mono.Security.Cryptography { - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class PKCS8 { - - public enum KeyInfo { - PrivateKey, - EncryptedPrivateKey, - Unknown - } - - private PKCS8 () - { - } - - static public KeyInfo GetType (byte[] data) - { - if (data == null) - throw new ArgumentNullException ("data"); - - KeyInfo ki = KeyInfo.Unknown; - try { - ASN1 top = new ASN1 (data); - if ((top.Tag == 0x30) && (top.Count > 0)) { - ASN1 firstLevel = top [0]; - switch (firstLevel.Tag) { - case 0x02: - ki = KeyInfo.PrivateKey; - break; - case 0x30: - ki = KeyInfo.EncryptedPrivateKey; - break; - } - } - } - catch { - throw new CryptographicException ("invalid ASN.1 data"); - } - return ki; - } - - /* - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL - * } - * - * Version ::= INTEGER - * - * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - * - * PrivateKey ::= OCTET STRING - * - * Attributes ::= SET OF Attribute - */ - public class PrivateKeyInfo { - - private int _version; - private string _algorithm; - private byte[] _key; - private ArrayList _list; - - public PrivateKeyInfo () - { - _version = 0; - _list = new ArrayList (); - } - - public PrivateKeyInfo (byte[] data) : this () - { - Decode (data); - } - - // properties - - public string Algorithm { - get { return _algorithm; } - set { _algorithm = value; } - } - - public ArrayList Attributes { - get { return _list; } - } - - public byte[] PrivateKey { - get { - if (_key == null) - return null; - return (byte[]) _key.Clone (); - } - set { - if (value == null) - throw new ArgumentNullException ("PrivateKey"); - _key = (byte[]) value.Clone (); - } - } - - public int Version { - get { return _version; } - set { - if (value < 0) - throw new ArgumentOutOfRangeException ("negative version"); - _version = value; - } - } - - // methods - - private void Decode (byte[] data) - { - ASN1 privateKeyInfo = new ASN1 (data); - if (privateKeyInfo.Tag != 0x30) - throw new CryptographicException ("invalid PrivateKeyInfo"); - - ASN1 version = privateKeyInfo [0]; - if (version.Tag != 0x02) - throw new CryptographicException ("invalid version"); - _version = version.Value [0]; - - ASN1 privateKeyAlgorithm = privateKeyInfo [1]; - if (privateKeyAlgorithm.Tag != 0x30) - throw new CryptographicException ("invalid algorithm"); - - ASN1 algorithm = privateKeyAlgorithm [0]; - if (algorithm.Tag != 0x06) - throw new CryptographicException ("missing algorithm OID"); - _algorithm = ASN1Convert.ToOid (algorithm); - - ASN1 privateKey = privateKeyInfo [2]; - _key = privateKey.Value; - - // attributes [0] IMPLICIT Attributes OPTIONAL - if (privateKeyInfo.Count > 3) { - ASN1 attributes = privateKeyInfo [3]; - for (int i=0; i < attributes.Count; i++) { - _list.Add (attributes [i]); - } - } - } - - public byte[] GetBytes () - { - ASN1 privateKeyAlgorithm = new ASN1 (0x30); - privateKeyAlgorithm.Add (ASN1Convert.FromOid (_algorithm)); - privateKeyAlgorithm.Add (new ASN1 (0x05)); // ASN.1 NULL - - ASN1 pki = new ASN1 (0x30); - pki.Add (new ASN1 (0x02, new byte [1] { (byte) _version })); - pki.Add (privateKeyAlgorithm); - pki.Add (new ASN1 (0x04, _key)); - - if (_list.Count > 0) { - ASN1 attributes = new ASN1 (0xA0); - foreach (ASN1 attribute in _list) { - attributes.Add (attribute); - } - pki.Add (attributes); - } - - return pki.GetBytes (); - } - - // static methods - - static private byte[] RemoveLeadingZero (byte[] bigInt) - { - int start = 0; - int length = bigInt.Length; - if (bigInt [0] == 0x00) { - start = 1; - length--; - } - byte[] bi = new byte [length]; - Buffer.BlockCopy (bigInt, start, bi, 0, length); - return bi; - } - - static private byte[] Normalize (byte[] bigInt, int length) - { - if (bigInt.Length == length) - return bigInt; - else if (bigInt.Length > length) - return RemoveLeadingZero (bigInt); - else { - // pad with 0 - byte[] bi = new byte [length]; - Buffer.BlockCopy (bigInt, 0, bi, (length - bigInt.Length), bigInt.Length); - return bi; - } - } - - /* - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - */ - static public RSA DecodeRSA (byte[] keypair) - { - ASN1 privateKey = new ASN1 (keypair); - if (privateKey.Tag != 0x30) - throw new CryptographicException ("invalid private key format"); - - ASN1 version = privateKey [0]; - if (version.Tag != 0x02) - throw new CryptographicException ("missing version"); - - if (privateKey.Count < 9) - throw new CryptographicException ("not enough key parameters"); - - RSAParameters param = new RSAParameters (); - // note: MUST remove leading 0 - else MS wont import the key - param.Modulus = RemoveLeadingZero (privateKey [1].Value); - int keysize = param.Modulus.Length; - int keysize2 = (keysize >> 1); // half-size - // size must be normalized - else MS wont import the key - param.D = Normalize (privateKey [3].Value, keysize); - param.DP = Normalize (privateKey [6].Value, keysize2); - param.DQ = Normalize (privateKey [7].Value, keysize2); - param.Exponent = RemoveLeadingZero (privateKey [2].Value); - param.InverseQ = Normalize (privateKey [8].Value, keysize2); - param.P = Normalize (privateKey [4].Value, keysize2); - param.Q = Normalize (privateKey [5].Value, keysize2); - RSA rsa = null; - try { - rsa = RSA.Create (); - rsa.ImportParameters (param); - } - catch (CryptographicException) { - // this may cause problem when this code is run under - // the SYSTEM identity on Windows (e.g. ASP.NET). See - // http://bugzilla.ximian.com/show_bug.cgi?id=77559 - CspParameters csp = new CspParameters (); - csp.Flags = CspProviderFlags.UseMachineKeyStore; - rsa = new RSACryptoServiceProvider (csp); - rsa.ImportParameters (param); - } - return rsa; - } - - /* - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - */ - static public byte[] Encode (RSA rsa) - { - RSAParameters param = rsa.ExportParameters (true); - - ASN1 rsaPrivateKey = new ASN1 (0x30); - rsaPrivateKey.Add (new ASN1 (0x02, new byte [1] { 0x00 })); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Modulus)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Exponent)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.D)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.P)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Q)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DP)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DQ)); - rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.InverseQ)); - - return rsaPrivateKey.GetBytes (); - } - - // DSA only encode it's X private key inside an ASN.1 INTEGER (Hint: Tag == 0x02) - // which isn't enough for rebuilding the keypair. The other parameters - // can be found (98% of the time) in the X.509 certificate associated - // with the private key or (2% of the time) the parameters are in it's - // issuer X.509 certificate (not supported in the .NET framework). - static public DSA DecodeDSA (byte[] privateKey, DSAParameters dsaParameters) - { - ASN1 pvk = new ASN1 (privateKey); - if (pvk.Tag != 0x02) - throw new CryptographicException ("invalid private key format"); - - // X is ALWAYS 20 bytes (no matter if the key length is 512 or 1024 bits) - dsaParameters.X = Normalize (pvk.Value, 20); - DSA dsa = DSA.Create (); - dsa.ImportParameters (dsaParameters); - return dsa; - } - - static public byte[] Encode (DSA dsa) - { - DSAParameters param = dsa.ExportParameters (true); - return ASN1Convert.FromUnsignedBigInteger (param.X).GetBytes (); - } - - static public byte[] Encode (AsymmetricAlgorithm aa) - { - if (aa is RSA) - return Encode ((RSA)aa); - else if (aa is DSA) - return Encode ((DSA)aa); - else - throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ()); - } - } - - /* - * EncryptedPrivateKeyInfo ::= SEQUENCE { - * encryptionAlgorithm EncryptionAlgorithmIdentifier, - * encryptedData EncryptedData - * } - * - * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedData ::= OCTET STRING - * - * -- - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * -- from PKCS#5 - * PBEParameter ::= SEQUENCE { - * salt OCTET STRING SIZE(8), - * iterationCount INTEGER - * } - */ - public class EncryptedPrivateKeyInfo { - - private string _algorithm; - private byte[] _salt; - private int _iterations; - private byte[] _data; - - public EncryptedPrivateKeyInfo () {} - - public EncryptedPrivateKeyInfo (byte[] data) : this () - { - Decode (data); - } - - // properties - - public string Algorithm { - get { return _algorithm; } - set { _algorithm = value; } - } - - public byte[] EncryptedData { - get { return (_data == null) ? null : (byte[]) _data.Clone (); } - set { _data = (value == null) ? null : (byte[]) value.Clone (); } - } - - public byte[] Salt { - get { - if (_salt == null) { - RandomNumberGenerator rng = RandomNumberGenerator.Create (); - _salt = new byte [8]; - rng.GetBytes (_salt); - } - return (byte[]) _salt.Clone (); - } - set { _salt = (byte[]) value.Clone (); } - } - - public int IterationCount { - get { return _iterations; } - set { - if (value < 0) - throw new ArgumentOutOfRangeException ("IterationCount", "Negative"); - _iterations = value; - } - } - - // methods - - private void Decode (byte[] data) - { - ASN1 encryptedPrivateKeyInfo = new ASN1 (data); - if (encryptedPrivateKeyInfo.Tag != 0x30) - throw new CryptographicException ("invalid EncryptedPrivateKeyInfo"); - - ASN1 encryptionAlgorithm = encryptedPrivateKeyInfo [0]; - if (encryptionAlgorithm.Tag != 0x30) - throw new CryptographicException ("invalid encryptionAlgorithm"); - ASN1 algorithm = encryptionAlgorithm [0]; - if (algorithm.Tag != 0x06) - throw new CryptographicException ("invalid algorithm"); - _algorithm = ASN1Convert.ToOid (algorithm); - // parameters ANY DEFINED BY algorithm OPTIONAL - if (encryptionAlgorithm.Count > 1) { - ASN1 parameters = encryptionAlgorithm [1]; - if (parameters.Tag != 0x30) - throw new CryptographicException ("invalid parameters"); - - ASN1 salt = parameters [0]; - if (salt.Tag != 0x04) - throw new CryptographicException ("invalid salt"); - _salt = salt.Value; - - ASN1 iterationCount = parameters [1]; - if (iterationCount.Tag != 0x02) - throw new CryptographicException ("invalid iterationCount"); - _iterations = ASN1Convert.ToInt32 (iterationCount); - } - - ASN1 encryptedData = encryptedPrivateKeyInfo [1]; - if (encryptedData.Tag != 0x04) - throw new CryptographicException ("invalid EncryptedData"); - _data = encryptedData.Value; - } - - // Note: PKCS#8 doesn't define how to generate the key required for encryption - // so you're on your own. Just don't try to copy the big guys too much ;) - // Netscape: http://www.cs.auckland.ac.nz/~pgut001/pubs/netscape.txt - // Microsoft: http://www.cs.auckland.ac.nz/~pgut001/pubs/breakms.txt - public byte[] GetBytes () - { - if (_algorithm == null) - throw new CryptographicException ("No algorithm OID specified"); - - ASN1 encryptionAlgorithm = new ASN1 (0x30); - encryptionAlgorithm.Add (ASN1Convert.FromOid (_algorithm)); - - // parameters ANY DEFINED BY algorithm OPTIONAL - if ((_iterations > 0) || (_salt != null)) { - ASN1 salt = new ASN1 (0x04, _salt); - ASN1 iterations = ASN1Convert.FromInt32 (_iterations); - - ASN1 parameters = new ASN1 (0x30); - parameters.Add (salt); - parameters.Add (iterations); - encryptionAlgorithm.Add (parameters); - } - - // encapsulates EncryptedData into an OCTET STRING - ASN1 encryptedData = new ASN1 (0x04, _data); - - ASN1 encryptedPrivateKeyInfo = new ASN1 (0x30); - encryptedPrivateKeyInfo.Add (encryptionAlgorithm); - encryptedPrivateKeyInfo.Add (encryptedData); - - return encryptedPrivateKeyInfo.GetBytes (); - } - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Cryptography/RSAManaged.cs b/mcs/class/corlib/Mono.Security.Cryptography/RSAManaged.cs deleted file mode 100644 index 9c406a200c7..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/RSAManaged.cs +++ /dev/null @@ -1,506 +0,0 @@ -// -// RSAManaged.cs - Implements the RSA algorithm. -// -// Authors: -// Sebastien Pouliot (sebastien@ximian.com) -// Ben Maurer (bmaurer@users.sf.net) -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Portions (C) 2003 Ben Maurer -// Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com) -// -// Key generation translated from Bouncy Castle JCE (http://www.bouncycastle.org/) -// See bouncycastle.txt for license. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Security.Cryptography; -using System.Text; - -using Mono.Math; - -// Big chunks of code are coming from the original RSACryptoServiceProvider class. -// The class was refactored to : -// a. ease integration of new hash algorithm (like MD2, RIPEMD160, ...); -// b. provide better support for the coming SSL implementation (requires -// EncryptValue/DecryptValue) with, or without, Mono runtime/corlib; -// c. provide an alternative RSA implementation for all Windows (like using -// OAEP without Windows XP). - -namespace Mono.Security.Cryptography { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class RSAManaged : RSA { - - private const int defaultKeySize = 1024; - - private bool isCRTpossible = false; - private bool keyBlinding = true; - private bool keypairGenerated = false; - private bool m_disposed = false; - - private BigInteger d; - private BigInteger p; - private BigInteger q; - private BigInteger dp; - private BigInteger dq; - private BigInteger qInv; - private BigInteger n; // modulus - private BigInteger e; - - public RSAManaged () : this (defaultKeySize) - { - } - - public RSAManaged (int keySize) - { - LegalKeySizesValue = new KeySizes [1]; - LegalKeySizesValue [0] = new KeySizes (384, 16384, 8); - base.KeySize = keySize; - } - - ~RSAManaged () - { - // Zeroize private key - Dispose (false); - } - - private void GenerateKeyPair () - { - // p and q values should have a length of half the strength in bits - int pbitlength = ((KeySize + 1) >> 1); - int qbitlength = (KeySize - pbitlength); - const uint uint_e = 17; - e = uint_e; // fixed - - // generate p, prime and (p-1) relatively prime to e - for (;;) { - p = BigInteger.GeneratePseudoPrime (pbitlength); - if (p % uint_e != 1) - break; - } - // generate a modulus of the required length - for (;;) { - // generate q, prime and (q-1) relatively prime to e, - // and not equal to p - for (;;) { - q = BigInteger.GeneratePseudoPrime (qbitlength); - if ((q % uint_e != 1) && (p != q)) - break; - } - - // calculate the modulus - n = p * q; - if (n.BitCount () == KeySize) - break; - - // if we get here our primes aren't big enough, make the largest - // of the two p and try again - if (p < q) - p = q; - } - - BigInteger pSub1 = (p - 1); - BigInteger qSub1 = (q - 1); - BigInteger phi = pSub1 * qSub1; - - // calculate the private exponent - d = e.ModInverse (phi); - - // calculate the CRT factors - dp = d % pSub1; - dq = d % qSub1; - qInv = q.ModInverse (p); - - keypairGenerated = true; - isCRTpossible = true; - - if (KeyGenerated != null) - KeyGenerated (this, null); - } - - // overrides from RSA class - - public override int KeySize { - get { - // in case keypair hasn't been (yet) generated - if (keypairGenerated) { - int ks = n.BitCount (); - if ((ks & 7) != 0) - ks = ks + (8 - (ks & 7)); - return ks; - } - else - return base.KeySize; - } - } - public override string KeyExchangeAlgorithm { - get { return "RSA-PKCS1-KeyEx"; } - } - - // note: when (if) we generate a keypair then it will have both - // the public and private keys - public bool PublicOnly { - get { return (keypairGenerated && ((d == null) || (n == null))); } - } - - public override string SignatureAlgorithm { - get { return "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; } - } - - public override byte[] DecryptValue (byte[] rgb) - { - if (m_disposed) - throw new ObjectDisposedException ("private key"); - - // decrypt operation is used for signature - if (!keypairGenerated) - GenerateKeyPair (); - - BigInteger input = new BigInteger (rgb); - BigInteger r = null; - - // we use key blinding (by default) against timing attacks - if (keyBlinding) { - // x = (r^e * g) mod n - // *new* random number (so it's timing is also random) - r = BigInteger.GenerateRandom (n.BitCount ()); - input = r.ModPow (e, n) * input % n; - } - - BigInteger output; - // decrypt (which uses the private key) can be - // optimized by using CRT (Chinese Remainder Theorem) - if (isCRTpossible) { - // m1 = c^dp mod p - BigInteger m1 = input.ModPow (dp, p); - // m2 = c^dq mod q - BigInteger m2 = input.ModPow (dq, q); - BigInteger h; - if (m2 > m1) { - // thanks to benm! - h = p - ((m2 - m1) * qInv % p); - output = m2 + q * h; - } else { - // h = (m1 - m2) * qInv mod p - h = (m1 - m2) * qInv % p; - // m = m2 + q * h; - output = m2 + q * h; - } - } else if (!PublicOnly) { - // m = c^d mod n - output = input.ModPow (d, n); - } else { - throw new CryptographicException (Locale.GetText ("Missing private key to decrypt value.")); - } - - if (keyBlinding) { - // Complete blinding - // x^e / r mod n - output = output * r.ModInverse (n) % n; - r.Clear (); - } - - // it's sometimes possible for the results to be a byte short - // and this can break some software (see #79502) so we 0x00 pad the result - byte[] result = GetPaddedValue (output, (KeySize >> 3)); - // zeroize values - input.Clear (); - output.Clear (); - return result; - } - - public override byte[] EncryptValue (byte[] rgb) - { - if (m_disposed) - throw new ObjectDisposedException ("public key"); - - if (!keypairGenerated) - GenerateKeyPair (); - - BigInteger input = new BigInteger (rgb); - BigInteger output = input.ModPow (e, n); - // it's sometimes possible for the results to be a byte short - // and this can break some software (see #79502) so we 0x00 pad the result - byte[] result = GetPaddedValue (output, (KeySize >> 3)); - // zeroize value - input.Clear (); - output.Clear (); - return result; - } - - - - public override RSAParameters ExportParameters (bool includePrivateParameters) - { - if (m_disposed) - throw new ObjectDisposedException (Locale.GetText ("Keypair was disposed")); - - if (!keypairGenerated) - GenerateKeyPair (); - - RSAParameters param = new RSAParameters (); - param.Exponent = e.GetBytes (); - param.Modulus = n.GetBytes (); - if (includePrivateParameters) { - // some parameters are required for exporting the private key - if (d == null) - throw new CryptographicException ("Missing private key"); - param.D = d.GetBytes (); - // hack for bugzilla #57941 where D wasn't provided - if (param.D.Length != param.Modulus.Length) { - byte[] normalizedD = new byte [param.Modulus.Length]; - Buffer.BlockCopy (param.D, 0, normalizedD, (normalizedD.Length - param.D.Length), param.D.Length); - param.D = normalizedD; - } - // but CRT parameters are optionals - if ((p != null) && (q != null) && (dp != null) && (dq != null) && (qInv != null)) { - // and we include them only if we have them all - int length = (KeySize >> 4); - param.P = GetPaddedValue (p, length); - param.Q = GetPaddedValue (q, length); - param.DP = GetPaddedValue (dp, length); - param.DQ = GetPaddedValue (dq, length); - param.InverseQ = GetPaddedValue (qInv, length); - } - } - return param; - } - - public override void ImportParameters (RSAParameters parameters) - { - if (m_disposed) - throw new ObjectDisposedException (Locale.GetText ("Keypair was disposed")); - - // if missing "mandatory" parameters - if (parameters.Exponent == null) - throw new CryptographicException (Locale.GetText ("Missing Exponent")); - if (parameters.Modulus == null) - throw new CryptographicException (Locale.GetText ("Missing Modulus")); - - e = new BigInteger (parameters.Exponent); - n = new BigInteger (parameters.Modulus); - // only if the private key is present - if (parameters.D != null) - d = new BigInteger (parameters.D); - if (parameters.DP != null) - dp = new BigInteger (parameters.DP); - if (parameters.DQ != null) - dq = new BigInteger (parameters.DQ); - if (parameters.InverseQ != null) - qInv = new BigInteger (parameters.InverseQ); - if (parameters.P != null) - p = new BigInteger (parameters.P); - if (parameters.Q != null) - q = new BigInteger (parameters.Q); - - // we now have a keypair - keypairGenerated = true; - bool privateKey = ((p != null) && (q != null) && (dp != null)); - isCRTpossible = (privateKey && (dq != null) && (qInv != null)); - - // check if the public/private keys match - // the way the check is made allows a bad D to work if CRT is available (like MS does, see unit tests) - if (!privateKey) - return; - - // always check n == p * q - bool ok = (n == (p * q)); - if (ok) { - // we now know that p and q are correct, so (p - 1), (q - 1) and phi will be ok too - BigInteger pSub1 = (p - 1); - BigInteger qSub1 = (q - 1); - BigInteger phi = pSub1 * qSub1; - // e is fairly static but anyway we can ensure it makes sense by recomputing d - BigInteger dcheck = e.ModInverse (phi); - - // now if our new d(check) is different than the d we're provided then we cannot - // be sure if 'd' or 'e' is invalid... (note that, from experience, 'd' is more - // likely to be invalid since it's twice as large as DP (or DQ) and sits at the - // end of the structure (e.g. truncation). - ok = (d == dcheck); - - // ... unless we have the pre-computed CRT parameters - if (!ok && isCRTpossible) { - // we can override the previous decision since Mono always prefer, for - // performance reasons, using the CRT algorithm - ok = (dp == (dcheck % pSub1)) && (dq == (dcheck % qSub1)) && - (qInv == q.ModInverse (p)); - } - } - - if (!ok) - throw new CryptographicException (Locale.GetText ("Private/public key mismatch")); - } - - protected override void Dispose (bool disposing) - { - if (!m_disposed) { - // Always zeroize private key - if (d != null) { - d.Clear (); - d = null; - } - if (p != null) { - p.Clear (); - p = null; - } - if (q != null) { - q.Clear (); - q = null; - } - if (dp != null) { - dp.Clear (); - dp = null; - } - if (dq != null) { - dq.Clear (); - dq = null; - } - if (qInv != null) { - qInv.Clear (); - qInv = null; - } - - if (disposing) { - // clear public key - if (e != null) { - e.Clear (); - e = null; - } - if (n != null) { - n.Clear (); - n = null; - } - } - } - // call base class - // no need as they all are abstract before us - m_disposed = true; - } - - public delegate void KeyGeneratedEventHandler (object sender, EventArgs e); - - public event KeyGeneratedEventHandler KeyGenerated; - - public override string ToXmlString (bool includePrivateParameters) - { - StringBuilder sb = new StringBuilder (); - RSAParameters rsaParams = ExportParameters (includePrivateParameters); - try { - sb.Append (""); - - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.Modulus)); - sb.Append (""); - - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.Exponent)); - sb.Append (""); - - if (includePrivateParameters) { - if (rsaParams.P != null) { - sb.Append ("

"); - sb.Append (Convert.ToBase64String (rsaParams.P)); - sb.Append ("

"); - } - if (rsaParams.Q != null) { - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.Q)); - sb.Append (""); - } - if (rsaParams.DP != null) { - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.DP)); - sb.Append (""); - } - if (rsaParams.DQ != null) { - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.DQ)); - sb.Append (""); - } - if (rsaParams.InverseQ != null) { - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.InverseQ)); - sb.Append (""); - } - sb.Append (""); - sb.Append (Convert.ToBase64String (rsaParams.D)); - sb.Append (""); - } - - sb.Append ("
"); - } - catch { - if (rsaParams.P != null) - Array.Clear (rsaParams.P, 0, rsaParams.P.Length); - if (rsaParams.Q != null) - Array.Clear (rsaParams.Q, 0, rsaParams.Q.Length); - if (rsaParams.DP != null) - Array.Clear (rsaParams.DP, 0, rsaParams.DP.Length); - if (rsaParams.DQ != null) - Array.Clear (rsaParams.DQ, 0, rsaParams.DQ.Length); - if (rsaParams.InverseQ != null) - Array.Clear (rsaParams.InverseQ, 0, rsaParams.InverseQ.Length); - if (rsaParams.D != null) - Array.Clear (rsaParams.D, 0, rsaParams.D.Length); - throw; - } - - return sb.ToString (); - } - - // internal for Mono 1.0.x in order to preserve public contract - // they are public for Mono 1.1.x (for 1.2) as the API isn't froze ATM - - public bool UseKeyBlinding { - get { return keyBlinding; } - // you REALLY shoudn't touch this (true is fine ;-) - set { keyBlinding = value; } - } - - public bool IsCrtPossible { - // either the key pair isn't generated (and will be - // generated with CRT parameters) or CRT is (or isn't) - // possible (in case the key was imported) - get { return (!keypairGenerated || isCRTpossible); } - } - - private byte[] GetPaddedValue (BigInteger value, int length) - { - byte[] result = value.GetBytes (); - if (result.Length >= length) - return result; - - // left-pad 0x00 value on the result (same integer, correct length) - byte[] padded = new byte[length]; - Buffer.BlockCopy (result, 0, padded, (length - result.Length), result.Length); - // temporary result may contain decrypted (plaintext) data, clear it - Array.Clear (result, 0, result.Length); - return padded; - } - } -} diff --git a/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs b/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs deleted file mode 100644 index 221f0fb695d..00000000000 --- a/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs +++ /dev/null @@ -1,491 +0,0 @@ -// -// Mono.Security.Cryptography.SymmetricTransform implementation -// -// Authors: -// Thomas Neidhart (tome@sbox.tugraz.at) -// Sebastien Pouliot -// -// Portions (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2008 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Security.Cryptography; - -namespace Mono.Security.Cryptography { - - // This class implement most of the common code required for symmetric - // algorithm transforms, like: - // - CipherMode: Builds CBC and CFB on top of (descendant supplied) ECB - // - PaddingMode, transform properties, multiple blocks, reuse... - // - // Descendants MUST: - // - intialize themselves (like key expansion, ...) - // - override the ECB (Electronic Code Book) method which will only be - // called using BlockSize byte[] array. - internal abstract class SymmetricTransform : ICryptoTransform { - protected SymmetricAlgorithm algo; - protected bool encrypt; - protected int BlockSizeByte; - protected byte[] temp; - protected byte[] temp2; - private byte[] workBuff; - private byte[] workout; - protected PaddingMode padmode; - // Silverlight 2.0 does not support any feedback mode - protected int FeedBackByte; - private bool m_disposed = false; - protected bool lastBlock; - - public SymmetricTransform (SymmetricAlgorithm symmAlgo, bool encryption, byte[] rgbIV) - { - algo = symmAlgo; - encrypt = encryption; - BlockSizeByte = (algo.BlockSize >> 3); - - if (rgbIV == null) { - rgbIV = KeyBuilder.IV (BlockSizeByte); - } else { - rgbIV = (byte[]) rgbIV.Clone (); - } - // compare the IV length with the "currently selected" block size and *ignore* IV that are too big - if (rgbIV.Length < BlockSizeByte) { - string msg = Locale.GetText ("IV is too small ({0} bytes), it should be {1} bytes long.", - rgbIV.Length, BlockSizeByte); - throw new CryptographicException (msg); - } - padmode = algo.Padding; - // mode buffers - temp = new byte [BlockSizeByte]; - Buffer.BlockCopy (rgbIV, 0, temp, 0, System.Math.Min (BlockSizeByte, rgbIV.Length)); - temp2 = new byte [BlockSizeByte]; - FeedBackByte = (algo.FeedbackSize >> 3); - // transform buffers - workBuff = new byte [BlockSizeByte]; - workout = new byte [BlockSizeByte]; - } - - ~SymmetricTransform () - { - Dispose (false); - } - - void IDisposable.Dispose () - { - Dispose (true); - GC.SuppressFinalize (this); // Finalization is now unnecessary - } - - // MUST be overriden by classes using unmanaged ressources - // the override method must call the base class - protected virtual void Dispose (bool disposing) - { - if (!m_disposed) { - if (disposing) { - // dispose managed object: zeroize and free - Array.Clear (temp, 0, BlockSizeByte); - temp = null; - Array.Clear (temp2, 0, BlockSizeByte); - temp2 = null; - } - m_disposed = true; - } - } - - public virtual bool CanTransformMultipleBlocks { - get { return true; } - } - - public virtual bool CanReuseTransform { - get { return false; } - } - - public virtual int InputBlockSize { - get { return BlockSizeByte; } - } - - public virtual int OutputBlockSize { - get { return BlockSizeByte; } - } - - // note: Each block MUST be BlockSizeValue in size!!! - // i.e. Any padding must be done before calling this method - protected virtual void Transform (byte[] input, byte[] output) - { - switch (algo.Mode) { - case CipherMode.ECB: - ECB (input, output); - break; - case CipherMode.CBC: - CBC (input, output); - break; - case CipherMode.CFB: - CFB (input, output); - break; - case CipherMode.OFB: - OFB (input, output); - break; - case CipherMode.CTS: - CTS (input, output); - break; - default: - throw new NotImplementedException ("Unkown CipherMode" + algo.Mode.ToString ()); - } - } - - // Electronic Code Book (ECB) - protected abstract void ECB (byte[] input, byte[] output); - - // Cipher-Block-Chaining (CBC) - protected virtual void CBC (byte[] input, byte[] output) - { - if (encrypt) { - for (int i = 0; i < BlockSizeByte; i++) - temp[i] ^= input[i]; - ECB (temp, output); - Buffer.BlockCopy (output, 0, temp, 0, BlockSizeByte); - } - else { - Buffer.BlockCopy (input, 0, temp2, 0, BlockSizeByte); - ECB (input, output); - for (int i = 0; i < BlockSizeByte; i++) - output[i] ^= temp[i]; - Buffer.BlockCopy (temp2, 0, temp, 0, BlockSizeByte); - } - } - - // Cipher-FeedBack (CFB) - // this is how *CryptoServiceProvider implements CFB - // only AesCryptoServiceProvider support CFB > 8 - // RijndaelManaged is incompatible with this implementation (and overrides it in it's own transform) - protected virtual void CFB (byte[] input, byte[] output) - { - if (encrypt) { - for (int x = 0; x < BlockSizeByte; x++) { - // temp is first initialized with the IV - ECB (temp, temp2); - output [x] = (byte) (temp2 [0] ^ input [x]); - Buffer.BlockCopy (temp, 1, temp, 0, BlockSizeByte - 1); - Buffer.BlockCopy (output, x, temp, BlockSizeByte - 1, 1); - } - } - else { - for (int x = 0; x < BlockSizeByte; x++) { - // we do not really decrypt this data! - encrypt = true; - // temp is first initialized with the IV - ECB (temp, temp2); - encrypt = false; - - Buffer.BlockCopy (temp, 1, temp, 0, BlockSizeByte - 1); - Buffer.BlockCopy (input, x, temp, BlockSizeByte - 1, 1); - output [x] = (byte) (temp2 [0] ^ input [x]); - } - } - } - - // Output-FeedBack (OFB) - protected virtual void OFB (byte[] input, byte[] output) - { - throw new CryptographicException ("OFB isn't supported by the framework"); - } - - // Cipher Text Stealing (CTS) - protected virtual void CTS (byte[] input, byte[] output) - { - throw new CryptographicException ("CTS isn't supported by the framework"); - } - - private void CheckInput (byte[] inputBuffer, int inputOffset, int inputCount) - { - if (inputBuffer == null) - throw new ArgumentNullException ("inputBuffer"); - if (inputOffset < 0) - throw new ArgumentOutOfRangeException ("inputOffset", "< 0"); - if (inputCount < 0) - throw new ArgumentOutOfRangeException ("inputCount", "< 0"); - // ordered to avoid possible integer overflow - if (inputOffset > inputBuffer.Length - inputCount) - throw new ArgumentException ("inputBuffer", Locale.GetText ("Overflow")); - } - - // this method may get called MANY times so this is the one to optimize - public virtual int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) - { - if (m_disposed) - throw new ObjectDisposedException ("Object is disposed"); - CheckInput (inputBuffer, inputOffset, inputCount); - // check output parameters - if (outputBuffer == null) - throw new ArgumentNullException ("outputBuffer"); - if (outputOffset < 0) - throw new ArgumentOutOfRangeException ("outputOffset", "< 0"); - - // ordered to avoid possible integer overflow - int len = outputBuffer.Length - inputCount - outputOffset; - if (!encrypt && (0 > len) && ((padmode == PaddingMode.None) || (padmode == PaddingMode.Zeros))) { - throw new CryptographicException ("outputBuffer", Locale.GetText ("Overflow")); - } else if (KeepLastBlock) { - if (0 > len + BlockSizeByte) { - throw new CryptographicException ("outputBuffer", Locale.GetText ("Overflow")); - } - } else { - if (0 > len) { - // there's a special case if this is the end of the decryption process - if (inputBuffer.Length - inputOffset - outputBuffer.Length == BlockSizeByte) - inputCount = outputBuffer.Length - outputOffset; - else - throw new CryptographicException ("outputBuffer", Locale.GetText ("Overflow")); - } - } - return InternalTransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); - } - - private bool KeepLastBlock { - get { - return ((!encrypt) && (padmode != PaddingMode.None) && (padmode != PaddingMode.Zeros)); - } - } - - private int InternalTransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) - { - int offs = inputOffset; - int full; - - // this way we don't do a modulo every time we're called - // and we may save a division - if (inputCount != BlockSizeByte) { - if ((inputCount % BlockSizeByte) != 0) - throw new CryptographicException ("Invalid input block size."); - - full = inputCount / BlockSizeByte; - } - else - full = 1; - - if (KeepLastBlock) - full--; - - int total = 0; - - if (lastBlock) { - Transform (workBuff, workout); - Buffer.BlockCopy (workout, 0, outputBuffer, outputOffset, BlockSizeByte); - outputOffset += BlockSizeByte; - total += BlockSizeByte; - lastBlock = false; - } - - for (int i = 0; i < full; i++) { - Buffer.BlockCopy (inputBuffer, offs, workBuff, 0, BlockSizeByte); - Transform (workBuff, workout); - Buffer.BlockCopy (workout, 0, outputBuffer, outputOffset, BlockSizeByte); - offs += BlockSizeByte; - outputOffset += BlockSizeByte; - total += BlockSizeByte; - } - - if (KeepLastBlock) { - Buffer.BlockCopy (inputBuffer, offs, workBuff, 0, BlockSizeByte); - lastBlock = true; - } - - return total; - } - - RandomNumberGenerator _rng; - - private void Random (byte[] buffer, int start, int length) - { - if (_rng == null) { - _rng = RandomNumberGenerator.Create (); - } - byte[] random = new byte [length]; - _rng.GetBytes (random); - Buffer.BlockCopy (random, 0, buffer, start, length); - } - - private void ThrowBadPaddingException (PaddingMode padding, int length, int position) - { - string msg = String.Format (Locale.GetText ("Bad {0} padding."), padding); - if (length >= 0) - msg += String.Format (Locale.GetText (" Invalid length {0}."), length); - if (position >= 0) - msg += String.Format (Locale.GetText (" Error found at position {0}."), position); - throw new CryptographicException (msg); - } - - protected virtual byte[] FinalEncrypt (byte[] inputBuffer, int inputOffset, int inputCount) - { - // are there still full block to process ? - int full = (inputCount / BlockSizeByte) * BlockSizeByte; - int rem = inputCount - full; - int total = full; - - switch (padmode) { - case PaddingMode.ANSIX923: - case PaddingMode.ISO10126: - case PaddingMode.PKCS7: - // we need to add an extra block for padding - total += BlockSizeByte; - break; - default: - if (inputCount == 0) - return new byte [0]; - if (rem != 0) { - if (padmode == PaddingMode.None) - throw new CryptographicException ("invalid block length"); - // zero padding the input (by adding a block for the partial data) - byte[] paddedInput = new byte [full + BlockSizeByte]; - Buffer.BlockCopy (inputBuffer, inputOffset, paddedInput, 0, inputCount); - inputBuffer = paddedInput; - inputOffset = 0; - inputCount = paddedInput.Length; - total = inputCount; - } - break; - } - - byte[] res = new byte [total]; - int outputOffset = 0; - - // process all blocks except the last (final) block - while (total > BlockSizeByte) { - InternalTransformBlock (inputBuffer, inputOffset, BlockSizeByte, res, outputOffset); - inputOffset += BlockSizeByte; - outputOffset += BlockSizeByte; - total -= BlockSizeByte; - } - - // now we only have a single last block to encrypt - byte padding = (byte) (BlockSizeByte - rem); - switch (padmode) { - case PaddingMode.ANSIX923: - // XX 00 00 00 00 00 00 07 (zero + padding length) - res [res.Length - 1] = padding; - Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); - // the last padded block will be transformed in-place - InternalTransformBlock (res, full, BlockSizeByte, res, full); - break; - case PaddingMode.ISO10126: - // XX 3F 52 2A 81 AB F7 07 (random + padding length) - Random (res, res.Length - padding, padding - 1); - res [res.Length - 1] = padding; - Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); - // the last padded block will be transformed in-place - InternalTransformBlock (res, full, BlockSizeByte, res, full); - break; - case PaddingMode.PKCS7: - // XX 07 07 07 07 07 07 07 (padding length) - for (int i = res.Length; --i >= (res.Length - padding);) - res [i] = padding; - Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); - // the last padded block will be transformed in-place - InternalTransformBlock (res, full, BlockSizeByte, res, full); - break; - default: - InternalTransformBlock (inputBuffer, inputOffset, BlockSizeByte, res, outputOffset); - break; - } - return res; - } - - protected virtual byte[] FinalDecrypt (byte[] inputBuffer, int inputOffset, int inputCount) - { - int full = inputCount; - int total = inputCount; - if (lastBlock) - total += BlockSizeByte; - - byte[] res = new byte [total]; - int outputOffset = 0; - - while (full > 0) { - int len = InternalTransformBlock (inputBuffer, inputOffset, BlockSizeByte, res, outputOffset); - inputOffset += BlockSizeByte; - outputOffset += len; - full -= BlockSizeByte; - } - - if (lastBlock) { - Transform (workBuff, workout); - Buffer.BlockCopy (workout, 0, res, outputOffset, BlockSizeByte); - outputOffset += BlockSizeByte; - lastBlock = false; - } - - // total may be 0 (e.g. PaddingMode.None) - byte padding = ((total > 0) ? res [total - 1] : (byte) 0); - switch (padmode) { - case PaddingMode.ANSIX923: - if ((padding == 0) || (padding > BlockSizeByte)) - ThrowBadPaddingException (padmode, padding, -1); - for (int i = padding - 1; i > 0; i--) { - if (res [total - 1 - i] != 0x00) - ThrowBadPaddingException (padmode, -1, i); - } - total -= padding; - break; - case PaddingMode.ISO10126: - if ((padding == 0) || (padding > BlockSizeByte)) - ThrowBadPaddingException (padmode, padding, -1); - total -= padding; - break; - case PaddingMode.PKCS7: - if ((padding == 0) || (padding > BlockSizeByte)) - ThrowBadPaddingException (padmode, padding, -1); - for (int i = padding - 1; i > 0; i--) { - if (res [total - 1 - i] != padding) - ThrowBadPaddingException (padmode, -1, i); - } - total -= padding; - break; - case PaddingMode.None: // nothing to do - it's a multiple of block size - case PaddingMode.Zeros: // nothing to do - user must unpad himself - break; - } - - // return output without padding - if (total > 0) { - byte[] data = new byte [total]; - Buffer.BlockCopy (res, 0, data, 0, total); - // zeroize decrypted data (copy with padding) - Array.Clear (res, 0, res.Length); - return data; - } - else - return new byte [0]; - } - - public virtual byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) - { - if (m_disposed) - throw new ObjectDisposedException ("Object is disposed"); - CheckInput (inputBuffer, inputOffset, inputCount); - - if (encrypt) - return FinalEncrypt (inputBuffer, inputOffset, inputCount); - else - return FinalDecrypt (inputBuffer, inputOffset, inputCount); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509.Extensions/BasicConstraintsExtension.cs b/mcs/class/corlib/Mono.Security.X509.Extensions/BasicConstraintsExtension.cs deleted file mode 100644 index 335fe92c654..00000000000 --- a/mcs/class/corlib/Mono.Security.X509.Extensions/BasicConstraintsExtension.cs +++ /dev/null @@ -1,139 +0,0 @@ -// -// BasicConstraintsExtension.cs: Handles X.509 BasicConstrains extensions. -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Text; - -using Mono.Security; -using Mono.Security.X509; - -namespace Mono.Security.X509.Extensions { - - // References: - // 1. RFC 3280: Internet X.509 Public Key Infrastructure, Section 4.2.1.10 - // http://www.ietf.org/rfc/rfc3280.txt - - /* id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } - * - * BasicConstraints ::= SEQUENCE { - * cA BOOLEAN DEFAULT FALSE, - * pathLenConstraint INTEGER (0..MAX) OPTIONAL - * } - */ -#if INSIDE_CORLIB - internal -#else - public -#endif - class BasicConstraintsExtension : X509Extension { - - public const int NoPathLengthConstraint = -1; - - private bool cA; - private int pathLenConstraint; - - public BasicConstraintsExtension () : base () - { - extnOid = "2.5.29.19"; - pathLenConstraint = NoPathLengthConstraint; - } - - public BasicConstraintsExtension (ASN1 asn1) : base (asn1) {} - - public BasicConstraintsExtension (X509Extension extension) : base (extension) {} - - protected override void Decode () - { - // default values - cA = false; - pathLenConstraint = NoPathLengthConstraint; - - ASN1 sequence = new ASN1 (extnValue.Value); - if (sequence.Tag != 0x30) - throw new ArgumentException ("Invalid BasicConstraints extension"); - int n = 0; - ASN1 a = sequence [n++]; - if ((a != null) && (a.Tag == 0x01)) { - cA = (a.Value [0] == 0xFF); - a = sequence [n++]; - } - if ((a != null) && (a.Tag == 0x02)) - pathLenConstraint = ASN1Convert.ToInt32 (a); - } - - protected override void Encode () - { - ASN1 seq = new ASN1 (0x30); - if (cA) - seq.Add (new ASN1 (0x01, new byte[] { 0xFF })); - // CAs MUST NOT include the pathLenConstraint field unless the cA boolean is asserted - if (cA && (pathLenConstraint >= 0)) - seq.Add (ASN1Convert.FromInt32 (pathLenConstraint)); - - extnValue = new ASN1 (0x04); - extnValue.Add (seq); - } - - public bool CertificateAuthority { - get { return cA; } - set { cA = value; } - } - - public override string Name { - get { return "Basic Constraints"; } - } - - public int PathLenConstraint { - get { return pathLenConstraint; } - set { - if (value < NoPathLengthConstraint) { - string msg = Locale.GetText ("PathLenConstraint must be positive or -1 for none ({0}).", value); - throw new ArgumentOutOfRangeException (msg); - } - pathLenConstraint = value; - } - } - - public override string ToString () - { - StringBuilder sb = new StringBuilder (); - sb.Append ("Subject Type="); - sb.Append ((cA) ? "CA" : "End Entity"); - sb.Append (Environment.NewLine); - sb.Append ("Path Length Constraint="); - if (pathLenConstraint == NoPathLengthConstraint) - sb.Append ("None"); - else - sb.Append (pathLenConstraint.ToString (CultureInfo.InvariantCulture)); - sb.Append (Environment.NewLine); - return sb.ToString (); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509.Extensions/ChangeLog b/mcs/class/corlib/Mono.Security.X509.Extensions/ChangeLog deleted file mode 100644 index e07075fbd6b..00000000000 --- a/mcs/class/corlib/Mono.Security.X509.Extensions/ChangeLog +++ /dev/null @@ -1,13 +0,0 @@ -2006-01-04 Sebastien Pouliot - - * BasicConstraintsExtension.cs: Keep in sync with Mono.Security.dll. - * KeyUsageExtension.cs: Keep in sync with Mono.Security.dll. - -2004-04-28 Sebastien Pouliot - - * BasicConstaintExtension.cs: New in corlib. In sync with - Mono.Security.dll version. - * KeyUsageExtension.cs: New in corlib. In sync with Mono.Security.dll - version. - * SubjectKeyIdentifierExtension.cs: New in corlib. In sync with - Mono.Security.dll version. diff --git a/mcs/class/corlib/Mono.Security.X509.Extensions/KeyUsageExtension.cs b/mcs/class/corlib/Mono.Security.X509.Extensions/KeyUsageExtension.cs deleted file mode 100644 index d0ad93c925e..00000000000 --- a/mcs/class/corlib/Mono.Security.X509.Extensions/KeyUsageExtension.cs +++ /dev/null @@ -1,197 +0,0 @@ -// -// KeyUsageExtension.cs: Handles X.509 KeyUsage extensions. -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Text; - -using Mono.Security; -using Mono.Security.X509; - -namespace Mono.Security.X509.Extensions { - - /* - * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } - * - * KeyUsage ::= BIT STRING { - * digitalSignature (0), - * nonRepudiation (1), - * keyEncipherment (2), - * dataEncipherment (3), - * keyAgreement (4), - * keyCertSign (5), - * cRLSign (6), - * encipherOnly (7), - * decipherOnly (8) - * } - */ - // note: because nothing is simple in ASN.1 bits are reversed - [Flags] -#if INSIDE_CORLIB - internal -#else - public -#endif - enum KeyUsages { - digitalSignature = 0x80, - nonRepudiation = 0x40, - keyEncipherment = 0x20, - dataEncipherment = 0x10, - keyAgreement = 0x08, - keyCertSign = 0x04, - cRLSign = 0x02, - encipherOnly = 0x01, - decipherOnly = 0x800, - none = 0x0 - } - -#if INSIDE_CORLIB - internal -#else - public -#endif - class KeyUsageExtension : X509Extension { - - private int kubits; - - public KeyUsageExtension (ASN1 asn1) : base (asn1) {} - - public KeyUsageExtension (X509Extension extension) : base (extension) {} - - public KeyUsageExtension () : base () - { - extnOid = "2.5.29.15"; - } - - protected override void Decode () - { - ASN1 bitString = new ASN1 (extnValue.Value); - if (bitString.Tag != 0x03) - throw new ArgumentException ("Invalid KeyUsage extension"); - int i = 1; // byte zero has the number of unused bits (ASN1's BITSTRING) - while (i < bitString.Value.Length) - kubits = (kubits << 8) + bitString.Value [i++]; - } - - protected override void Encode () - { - extnValue = new ASN1 (0x04); - - ushort ku = (ushort) kubits; - byte unused = 16; - if (ku > 0) { - // count the unused bits - for (unused = 15; unused > 0; unused--) { - if ((ku & 0x8000) == 0x8000) - break; - ku <<= 1; - } - - if (kubits > Byte.MaxValue) { - unused -= 8; - extnValue.Add (new ASN1 (0x03, new byte[] { unused, (byte) kubits, (byte) (kubits >> 8) })); - } else { - extnValue.Add (new ASN1 (0x03, new byte[] { unused, (byte) kubits })); - } - } else { - // note: a BITSTRING with a 0 length is invalid (in ASN.1), so would an - // empty OCTETSTRING (at the parent level) so we're encoding a 0 - extnValue.Add (new ASN1 (0x03, new byte[] { 7, 0 })); - } - } - - public KeyUsages KeyUsage { - get { return (KeyUsages) kubits; } - set { kubits = Convert.ToInt32 (value, CultureInfo.InvariantCulture); } - } - - public override string Name { - get { return "Key Usage"; } - } - - public bool Support (KeyUsages usage) - { - int x = Convert.ToInt32 (usage, CultureInfo.InvariantCulture); - return ((x & kubits) == x); - } - - public override string ToString () - { - const string separator = " , "; - StringBuilder sb = new StringBuilder (); - if (Support (KeyUsages.digitalSignature)) - sb.Append ("Digital Signature"); - if (Support (KeyUsages.nonRepudiation)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Non-Repudiation"); - } - if (Support (KeyUsages.keyEncipherment)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Key Encipherment"); - } - if (Support (KeyUsages.dataEncipherment)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Data Encipherment"); - } - if (Support (KeyUsages.keyAgreement)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Key Agreement"); - } - if (Support (KeyUsages.keyCertSign)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Certificate Signing"); - } - if (Support (KeyUsages.cRLSign)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("CRL Signing"); - } - if (Support (KeyUsages.encipherOnly)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Encipher Only "); // ??? - } - if (Support (KeyUsages.decipherOnly)) { - if (sb.Length > 0) - sb.Append (separator); - sb.Append ("Decipher Only"); // ??? - } - sb.Append ("("); - sb.Append (kubits.ToString ("X2", CultureInfo.InvariantCulture)); - sb.Append (")"); - sb.Append (Environment.NewLine); - return sb.ToString (); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509.Extensions/SubjectKeyIdentifierExtension.cs b/mcs/class/corlib/Mono.Security.X509.Extensions/SubjectKeyIdentifierExtension.cs deleted file mode 100644 index 878c3cc4383..00000000000 --- a/mcs/class/corlib/Mono.Security.X509.Extensions/SubjectKeyIdentifierExtension.cs +++ /dev/null @@ -1,108 +0,0 @@ -// -// SubjectKeyIdentifierExtension.cs: Handles X.509 SubjectKeyIdentifier extensions. -// -// Author: -// Sebastien Pouliot -// -// (C) 2004 Novell (http://www.novell.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Text; - -using Mono.Security; -using Mono.Security.X509; - -namespace Mono.Security.X509.Extensions { - - /* - * id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } - * - * SubjectKeyIdentifier ::= KeyIdentifier - * - * KeyIdentifier ::= OCTET STRING - */ - -#if INSIDE_CORLIB - internal -#else - public -#endif - class SubjectKeyIdentifierExtension : X509Extension { - - private byte[] ski; - - public SubjectKeyIdentifierExtension () : base () - { - extnOid = "2.5.29.14"; - } - - public SubjectKeyIdentifierExtension (ASN1 asn1) : base (asn1) - { - } - - public SubjectKeyIdentifierExtension (X509Extension extension) : base (extension) - { - } - - protected override void Decode () - { - ASN1 sequence = new ASN1 (extnValue.Value); - if (sequence.Tag != 0x04) - throw new ArgumentException ("Invalid SubjectKeyIdentifier extension"); - ski = sequence.Value; - } - - public override string Name { - get { return "Subject Key Identifier"; } - } - - public byte[] Identifier { - get { - if (ski == null) - return null; - return (byte[]) ski.Clone (); - } - } - - public override string ToString () - { - if (ski == null) - return null; - - StringBuilder sb = new StringBuilder (); - int x = 0; - while (x < ski.Length) { - sb.Append (ski [x].ToString ("X2", CultureInfo.InvariantCulture)); - if (x % 2 == 1) - sb.Append (" "); - x++; - } - return sb.ToString (); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/ChangeLog b/mcs/class/corlib/Mono.Security.X509/ChangeLog deleted file mode 100644 index 39c5b855fac..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/ChangeLog +++ /dev/null @@ -1,174 +0,0 @@ -2010-05-10 Sebastien Pouliot - - * X509CertificateCollection.cs: - * X509Certificate.cs: - * X509Extension.cs: - * X509Extensions.cs: - Keep them public for Moonlight. Other types in other - assemblies needs it and the linker will eventually - internalize everything. - -2010-03-16 Jb Evain - - * X509Certificate.cs: use MOONLIGHT symbol to disambiguate - MonoTouch and Moonlight code. - -2009-04-30 Sebastien Pouliot - - * X509Certificate.cs: Adapt to work with only [DSA|RSA]Managed when - built for NET_2_1, i.e. remove use of [DSA|RSA]CryptoServiceProvider - -2008-09-12 Sebastien Pouliot - - * PKCS12.cs, X509Store.cs: Use File.Create instead of OpenWrite to - make sure nothing else if left at the end of the file. Issue reported - by Christophe Chevalier. - -2008-06-03 Sebastien Pouliot - - * X509Certificate.cs: Accept text before the PEM certificate itself. - [Fix bug #396486] - -2008-01-10 Sebastien Pouliot - - * PKCS12.cs, X509Certificate.cs, X509Chain.cs, X509Extension.cs: - Synchronize/update with Mono.Security assembly - -2006-12-14 Sebastien Pouliot - - * X501Name.cs: Added support for (some cases of) T.61 strings, like - the latin-1 encoded accentued characters founds in some DN. Fix bug - #77295. - -2006-12-11 Sebastien Pouliot - - * PKCS12.cs: Synchronize source with Mono.Security.dll - * X501Name.cs: Synchronize source with Mono.Security.dll - * X509Certificate.cs: Synchronize source with Mono.Security.dll - * X509CRL.cs: Synchronize source with Mono.Security.dll - * X509Store.cs: Synchronize source with Mono.Security.dll - * X509Stores.cs: Synchronize source with Mono.Security.dll - * X520Attributes.cs: Synchronize source with Mono.Security.dll - -2006-11-13 Sebastien Pouliot - - * X509Certificate.cs: Add support for PEM encoded (base64) x.509 - certificates (supported in 2.0). - -2006-11-08 Sebastien Pouliot - - * X501Name.cs: Refactor ToString method to allow most options available - when using fx 2.0. - * X509Certificate.cs: Add methods to retrieve the Issuer and Subject - Distinguished Names in binary (ASN.1) form. Reverse (actually correct) - the text representation of Issuer and Subject for 2.0. - * X520Attributes.cs: Keep in sync with latest version from - Mono.Security.dll assembly (required for X501Name update). - -2006-10-08 Sebastien Pouliot - - * PKCS12.cs: Synch implementation with Mono.Security.dll. Fix bug - #79617. - -2006-09-05 Sebastien Pouliot - - * X509Certificate.cs: Keep in sync with Mono.Security.dll (#79262). - -2006-01-04 Sebastien Pouliot - - * X509Extension.cs: Keep in sync with Mono.Security.dll. - -2005-11-18 Sebastien Pouliot - - * X509Extension.cs: Keep in sync with Mono.Security.dll. - -2005-10-11 Sebastien Pouliot - - * X509Certificate.cs: Fixed bug #76407. ValidFrom and ValidUntil are - local date/time so IsCurrent most also use a local date/time. - * X509CRL.cs: Updated from Mono.Security.dll (same IsCurrent problem - and another previously fixed bug). - -2005-09-09 Sebastien Pouliot - - * X509Certificate.cs: Fixed version property (bug #76012). Added - ISerializable (for 2.0 so we're not breaking current compatibility). - -2005-04-27 Sebastien Pouliot - - * PKCS12.cs: New. Copied from Mono.Security.dll to allow support of - PKCS#12 files in X509Certificate for 2.0. - * X509Certificate.cs: Added new features required to support 2.0. - -2005-02-25 Sebastien Pouliot - - * X501Name.cs: In sync with Mono.Security.dll version. - * X520Attributes.cs: In sync with Mono.Security.dll version. - -2005-01-10 Sebastien Pouliot - - * X509Certificate.cs: Fixed NullReferenceException when asking for - data that wasn't a proper X.509 certificate. - -2004-09-16 Sebastien Pouliot - - * X509Certificate.cs: Fixed warning (l4) for unused variable. - * X509Extension.cs: Fixed warning (l4) for unused variable. - -2004-09-07 Sebastien Pouliot - - * X509Chain.cs: Merge from Mono.Security. Fix two bugs (chain - construction from collection) and Reset-ing empty chain. - -2004-05-27 Sebastien Pouliot - - * X509Certificate.cs: Rethrow original exception when parsing X.509 - certificates (inside a CryptographicException) so people can see if - their changes affects certificate decoding. - -2004-04-28 Sebastien Pouliot - - * X501Name.cs: In sync with Mono.Security.dll version. - * X509CRL.cs: New in corlib. In sync with Mono.Security.dll version. - * X509Certificate.cs: In sync with Mono.Security.dll version. - * X509CertificateCollection.cs: In sync with Mono.Security.dll version. - * X509Chain.cs: In sync with Mono.Security.dll version. - * X509ChainStatusFlag.cs: New in corlib. In sync with Mono.Security.dll - version. - * X509Extension.cs: In sync with Mono.Security.dll version. - * X509Extensions.cs: In sync with Mono.Security.dll version. - * X509Store.cs: New in corlib. In sync with Mono.Security.dll version. - * X509StoreManager.cs: New in corlib. In sync with Mono.Security.dll version. - * X509Stores.cs: New in corlib. In sync with Mono.Security.dll version. - * X520Attributes.cs: In sync with Mono.Security.dll version. - -2003-12-15 Sebastien Pouliot - - * TrustAnchors.cs: Added a new trusted root, Thawte, for code signing. - -2003-10-12 Sebastien Pouliot - - * ITrustAnchors.cs: Added from Mono.Security assembly to - support Authenticode in X509Certificate.CreateFromSignedFile - * TestAnchors.cs: Added from Mono.Security assembly to - support Authenticode in X509Certificate.CreateFromSignedFile - * TrustAnchors.cs: Added from Mono.Security assembly to - support Authenticode in X509Certificate.CreateFromSignedFile - * X509CertificateCollection.cs: Added from Mono.Security assembly to - support Authenticode in X509Certificate.CreateFromSignedFile - * X509Chain.cs: Added from Mono.Security assembly to - support Authenticode in X509Certificate.CreateFromSignedFile - -2003-05-16 Sebastien Pouliot - - * X509Certificate.cs: Added support for "really" NULL key parameters - (i.e. not ASN.1 encoded NULL). - -2003-03-15 Sebastien Pouliot - - * X501Name.cs: New. X.501 Distinguished Names stuff - * X509Certificate.cs: New. A more complete class to handle X.509 - certificates. - * X509Extension.cs: New. A base class for all X.509 extensions. - * X509Extensions.cs: New. X509Extension collection. - * X520Attributes.cs: New. X.520 attributes (mainly for X501 names) diff --git a/mcs/class/corlib/Mono.Security.X509/ITrustAnchors.cs b/mcs/class/corlib/Mono.Security.X509/ITrustAnchors.cs deleted file mode 100644 index a73d2726014..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/ITrustAnchors.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// ITrustAnchors.cs: Trust Anchors Interface -// -// Author: -// Sebastien Pouliot (spouliot@motus.com) -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - interface ITrustAnchors - { - X509CertificateCollection Anchors { get; } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/PKCS12.cs b/mcs/class/corlib/Mono.Security.X509/PKCS12.cs deleted file mode 100644 index 848ce803589..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/PKCS12.cs +++ /dev/null @@ -1,1972 +0,0 @@ -// -// PKCS12.cs: PKCS 12 - Personal Information Exchange Syntax -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004,2005,2006 Novell Inc. (http://www.novell.com) -// -// Key derivation translated from Bouncy Castle JCE (http://www.bouncycastle.org/) -// See bouncycastle.txt for license. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.IO; -using System.Security.Cryptography; -using System.Text; - -using Mono.Security; -using Mono.Security.Cryptography; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class PKCS5 { - - public const string pbeWithMD2AndDESCBC = "1.2.840.113549.1.5.1"; - public const string pbeWithMD5AndDESCBC = "1.2.840.113549.1.5.3"; - public const string pbeWithMD2AndRC2CBC = "1.2.840.113549.1.5.4"; - public const string pbeWithMD5AndRC2CBC = "1.2.840.113549.1.5.6"; - public const string pbeWithSHA1AndDESCBC = "1.2.840.113549.1.5.10"; - public const string pbeWithSHA1AndRC2CBC = "1.2.840.113549.1.5.11"; - - public PKCS5 () {} - } - -#if INSIDE_CORLIB - internal -#else - public -#endif - class PKCS9 { - - public const string friendlyName = "1.2.840.113549.1.9.20"; - public const string localKeyId = "1.2.840.113549.1.9.21"; - - public PKCS9 () {} - } - - - internal class SafeBag { - private string _bagOID; - private ASN1 _asn1; - - public SafeBag(string bagOID, ASN1 asn1) { - _bagOID = bagOID; - _asn1 = asn1; - } - - public string BagOID { - get { return _bagOID; } - } - - public ASN1 ASN1 { - get { return _asn1; } - } - } - - -#if INSIDE_CORLIB - internal -#else - public -#endif - class PKCS12 : ICloneable { - - public const string pbeWithSHAAnd128BitRC4 = "1.2.840.113549.1.12.1.1"; - public const string pbeWithSHAAnd40BitRC4 = "1.2.840.113549.1.12.1.2"; - public const string pbeWithSHAAnd3KeyTripleDESCBC = "1.2.840.113549.1.12.1.3"; - public const string pbeWithSHAAnd2KeyTripleDESCBC = "1.2.840.113549.1.12.1.4"; - public const string pbeWithSHAAnd128BitRC2CBC = "1.2.840.113549.1.12.1.5"; - public const string pbeWithSHAAnd40BitRC2CBC = "1.2.840.113549.1.12.1.6"; - - // bags - public const string keyBag = "1.2.840.113549.1.12.10.1.1"; - public const string pkcs8ShroudedKeyBag = "1.2.840.113549.1.12.10.1.2"; - public const string certBag = "1.2.840.113549.1.12.10.1.3"; - public const string crlBag = "1.2.840.113549.1.12.10.1.4"; - public const string secretBag = "1.2.840.113549.1.12.10.1.5"; - public const string safeContentsBag = "1.2.840.113549.1.12.10.1.6"; - - // types - public const string x509Certificate = "1.2.840.113549.1.9.22.1"; - public const string sdsiCertificate = "1.2.840.113549.1.9.22.2"; - public const string x509Crl = "1.2.840.113549.1.9.23.1"; - - // Adapted from BouncyCastle PKCS12ParametersGenerator.java - public class DeriveBytes { - - public enum Purpose { - Key, - IV, - MAC - } - - static private byte[] keyDiversifier = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; - static private byte[] ivDiversifier = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }; - static private byte[] macDiversifier = { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }; - - private string _hashName; - private int _iterations; - private byte[] _password; - private byte[] _salt; - - public DeriveBytes () {} - - public string HashName { - get { return _hashName; } - set { _hashName = value; } - } - - public int IterationCount { - get { return _iterations; } - set { _iterations = value; } - } - - public byte[] Password { - get { return (byte[]) _password.Clone (); } - set { - if (value == null) - _password = new byte [0]; - else - _password = (byte[]) value.Clone (); - } - } - - public byte[] Salt { - get { return (byte[]) _salt.Clone (); } - set { - if (value != null) - _salt = (byte[]) value.Clone (); - else - _salt = null; - } - } - - private void Adjust (byte[] a, int aOff, byte[] b) - { - int x = (b[b.Length - 1] & 0xff) + (a [aOff + b.Length - 1] & 0xff) + 1; - - a [aOff + b.Length - 1] = (byte) x; - x >>= 8; - - for (int i = b.Length - 2; i >= 0; i--) { - x += (b [i] & 0xff) + (a [aOff + i] & 0xff); - a [aOff + i] = (byte) x; - x >>= 8; - } - } - - private byte[] Derive (byte[] diversifier, int n) - { - HashAlgorithm digest = HashAlgorithm.Create (_hashName); - int u = (digest.HashSize >> 3); // div 8 - int v = 64; - byte[] dKey = new byte [n]; - - byte[] S; - if ((_salt != null) && (_salt.Length != 0)) { - S = new byte[v * ((_salt.Length + v - 1) / v)]; - - for (int i = 0; i != S.Length; i++) { - S[i] = _salt[i % _salt.Length]; - } - } - else { - S = new byte[0]; - } - - byte[] P; - if ((_password != null) && (_password.Length != 0)) { - P = new byte[v * ((_password.Length + v - 1) / v)]; - - for (int i = 0; i != P.Length; i++) { - P[i] = _password[i % _password.Length]; - } - } - else { - P = new byte[0]; - } - - byte[] I = new byte [S.Length + P.Length]; - - Buffer.BlockCopy (S, 0, I, 0, S.Length); - Buffer.BlockCopy (P, 0, I, S.Length, P.Length); - - byte[] B = new byte[v]; - int c = (n + u - 1) / u; - - for (int i = 1; i <= c; i++) { - digest.TransformBlock (diversifier, 0, diversifier.Length, diversifier, 0); - digest.TransformFinalBlock (I, 0, I.Length); - byte[] A = digest.Hash; - digest.Initialize (); - for (int j = 1; j != _iterations; j++) { - A = digest.ComputeHash (A, 0, A.Length); - } - - for (int j = 0; j != B.Length; j++) { - B [j] = A [j % A.Length]; - } - - for (int j = 0; j != I.Length / v; j++) { - Adjust (I, j * v, B); - } - - if (i == c) { - Buffer.BlockCopy(A, 0, dKey, (i - 1) * u, dKey.Length - ((i - 1) * u)); - } - else { - Buffer.BlockCopy(A, 0, dKey, (i - 1) * u, A.Length); - } - } - - return dKey; - } - - public byte[] DeriveKey (int size) - { - return Derive (keyDiversifier, size); - } - - public byte[] DeriveIV (int size) - { - return Derive (ivDiversifier, size); - } - - public byte[] DeriveMAC (int size) - { - return Derive (macDiversifier, size); - } - } - - const int recommendedIterationCount = 2000; - - //private int _version; - private byte[] _password; - private ArrayList _keyBags; - private ArrayList _secretBags; - private X509CertificateCollection _certs; - private bool _keyBagsChanged; - private bool _secretBagsChanged; - private bool _certsChanged; - private int _iterations; - private ArrayList _safeBags; - private RandomNumberGenerator _rng; - - // constructors - - public PKCS12 () - { - _iterations = recommendedIterationCount; - _keyBags = new ArrayList (); - _secretBags = new ArrayList (); - _certs = new X509CertificateCollection (); - _keyBagsChanged = false; - _secretBagsChanged = false; - _certsChanged = false; - _safeBags = new ArrayList (); - } - - public PKCS12 (byte[] data) - : this () - { - Password = null; - Decode (data); - } - - /* - * PFX ::= SEQUENCE { - * version INTEGER {v3(3)}(v3,...), - * authSafe ContentInfo, - * macData MacData OPTIONAL - * } - * - * MacData ::= SEQUENCE { - * mac DigestInfo, - * macSalt OCTET STRING, - * iterations INTEGER DEFAULT 1 - * -- Note: The default is for historical reasons and its use is deprecated. A higher - * -- value, like 1024 is recommended. - * } - * - * SafeContents ::= SEQUENCE OF SafeBag - * - * SafeBag ::= SEQUENCE { - * bagId BAG-TYPE.&id ({PKCS12BagSet}), - * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), - * bagAttributes SET OF PKCS12Attribute OPTIONAL - * } - */ - public PKCS12 (byte[] data, string password) - : this () - { - Password = password; - Decode (data); - } - - public PKCS12 (byte[] data, byte[] password) - : this () - { - _password = password; - Decode (data); - } - - private void Decode (byte[] data) - { - ASN1 pfx = new ASN1 (data); - if (pfx.Tag != 0x30) - throw new ArgumentException ("invalid data"); - - ASN1 version = pfx [0]; - if (version.Tag != 0x02) - throw new ArgumentException ("invalid PFX version"); - //_version = version.Value [0]; - - PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (pfx [1]); - if (authSafe.ContentType != PKCS7.Oid.data) - throw new ArgumentException ("invalid authenticated safe"); - - // now that we know it's a PKCS#12 file, check the (optional) MAC - // before decoding anything else in the file - if (pfx.Count > 2) { - ASN1 macData = pfx [2]; - if (macData.Tag != 0x30) - throw new ArgumentException ("invalid MAC"); - - ASN1 mac = macData [0]; - if (mac.Tag != 0x30) - throw new ArgumentException ("invalid MAC"); - ASN1 macAlgorithm = mac [0]; - string macOid = ASN1Convert.ToOid (macAlgorithm [0]); - if (macOid != "1.3.14.3.2.26") - throw new ArgumentException ("unsupported HMAC"); - byte[] macValue = mac [1].Value; - - ASN1 macSalt = macData [1]; - if (macSalt.Tag != 0x04) - throw new ArgumentException ("missing MAC salt"); - - _iterations = 1; // default value - if (macData.Count > 2) { - ASN1 iters = macData [2]; - if (iters.Tag != 0x02) - throw new ArgumentException ("invalid MAC iteration"); - _iterations = ASN1Convert.ToInt32 (iters); - } - - byte[] authSafeData = authSafe.Content [0].Value; - byte[] calculatedMac = MAC (_password, macSalt.Value, _iterations, authSafeData); - if (!Compare (macValue, calculatedMac)) - throw new CryptographicException ("Invalid MAC - file may have been tampered!"); - } - - // we now returns to our original presentation - PFX - ASN1 authenticatedSafe = new ASN1 (authSafe.Content [0].Value); - for (int i=0; i < authenticatedSafe.Count; i++) { - PKCS7.ContentInfo ci = new PKCS7.ContentInfo (authenticatedSafe [i]); - switch (ci.ContentType) { - case PKCS7.Oid.data: - // unencrypted (by PKCS#12) - ASN1 safeContents = new ASN1 (ci.Content [0].Value); - for (int j=0; j < safeContents.Count; j++) { - ASN1 safeBag = safeContents [j]; - ReadSafeBag (safeBag); - } - break; - case PKCS7.Oid.encryptedData: - // password encrypted - PKCS7.EncryptedData ed = new PKCS7.EncryptedData (ci.Content [0]); - ASN1 decrypted = new ASN1 (Decrypt (ed)); - for (int j=0; j < decrypted.Count; j++) { - ASN1 safeBag = decrypted [j]; - ReadSafeBag (safeBag); - } - break; - case PKCS7.Oid.envelopedData: - // public key encrypted - throw new NotImplementedException ("public key encrypted"); - default: - throw new ArgumentException ("unknown authenticatedSafe"); - } - } - } - - ~PKCS12 () - { - if (_password != null) { - Array.Clear (_password, 0, _password.Length); - } - _password = null; - } - - // properties - - public string Password { - set { - if (value != null) { - if (value.Length > 0) { - int size = value.Length; - int nul = 0; - if (size < MaximumPasswordLength) { - // if not present, add space for a NULL (0x00) character - if (value[size - 1] != 0x00) - nul = 1; - } else { - size = MaximumPasswordLength; - } - _password = new byte[(size + nul) << 1]; // double for unicode - Encoding.BigEndianUnicode.GetBytes (value, 0, size, _password, 0); - } else { - // double-byte (Unicode) NULL (0x00) - see bug #79617 - _password = new byte[2]; - } - } else { - // no password - _password = null; - } - } - } - - public int IterationCount { - get { return _iterations; } - set { _iterations = value; } - } - - public ArrayList Keys { - get { - if (_keyBagsChanged) { - _keyBags.Clear (); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (keyBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p)); - break; - case 0x30: - _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey)); - break; - default: - break; - } - Array.Clear (privateKey, 0, privateKey.Length); - - } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); - byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p)); - break; - case 0x30: - _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey)); - break; - default: - break; - } - Array.Clear (privateKey, 0, privateKey.Length); - Array.Clear (decrypted, 0, decrypted.Length); - } - } - _keyBagsChanged = false; - } - return ArrayList.ReadOnly(_keyBags); - } - } - - public ArrayList Secrets { - get { - if (_secretBagsChanged) { - _secretBags.Clear (); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (secretBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - byte[] secret = bagValue.Value; - _secretBags.Add(secret); - } - } - _secretBagsChanged = false; - } - return ArrayList.ReadOnly(_secretBags); - } - } - - public X509CertificateCollection Certificates { - get { - if (_certsChanged) { - _certs.Clear (); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (certBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); - _certs.Add (new X509Certificate (cert.Content [0].Value)); - } - } - _certsChanged = false; - } - return _certs; - } - } - - internal RandomNumberGenerator RNG { - get { - if (_rng == null) - _rng = RandomNumberGenerator.Create (); - return _rng; - } - } - - // private methods - - private bool Compare (byte[] expected, byte[] actual) - { - bool compare = false; - if (expected.Length == actual.Length) { - for (int i=0; i < expected.Length; i++) { - if (expected [i] != actual [i]) - return false; - } - compare = true; - } - return compare; - } - - private SymmetricAlgorithm GetSymmetricAlgorithm (string algorithmOid, byte[] salt, int iterationCount) - { - string algorithm = null; - int keyLength = 8; // 64 bits (default) - int ivLength = 8; // 64 bits (default) - - PKCS12.DeriveBytes pd = new PKCS12.DeriveBytes (); - pd.Password = _password; - pd.Salt = salt; - pd.IterationCount = iterationCount; - - switch (algorithmOid) { - case PKCS5.pbeWithMD2AndDESCBC: // no unit test available - pd.HashName = "MD2"; - algorithm = "DES"; - break; - case PKCS5.pbeWithMD5AndDESCBC: // no unit test available - pd.HashName = "MD5"; - algorithm = "DES"; - break; - case PKCS5.pbeWithMD2AndRC2CBC: // no unit test available - // TODO - RC2-CBC-Parameter (PKCS5) - // if missing default to 32 bits !!! - pd.HashName = "MD2"; - algorithm = "RC2"; - keyLength = 4; // default - break; - case PKCS5.pbeWithMD5AndRC2CBC: // no unit test available - // TODO - RC2-CBC-Parameter (PKCS5) - // if missing default to 32 bits !!! - pd.HashName = "MD5"; - algorithm = "RC2"; - keyLength = 4; // default - break; - case PKCS5.pbeWithSHA1AndDESCBC: // no unit test available - pd.HashName = "SHA1"; - algorithm = "DES"; - break; - case PKCS5.pbeWithSHA1AndRC2CBC: // no unit test available - // TODO - RC2-CBC-Parameter (PKCS5) - // if missing default to 32 bits !!! - pd.HashName = "SHA1"; - algorithm = "RC2"; - keyLength = 4; // default - break; - case PKCS12.pbeWithSHAAnd128BitRC4: // no unit test available - pd.HashName = "SHA1"; - algorithm = "RC4"; - keyLength = 16; - ivLength = 0; // N/A - break; - case PKCS12.pbeWithSHAAnd40BitRC4: // no unit test available - pd.HashName = "SHA1"; - algorithm = "RC4"; - keyLength = 5; - ivLength = 0; // N/A - break; - case PKCS12.pbeWithSHAAnd3KeyTripleDESCBC: - pd.HashName = "SHA1"; - algorithm = "TripleDES"; - keyLength = 24; - break; - case PKCS12.pbeWithSHAAnd2KeyTripleDESCBC: // no unit test available - pd.HashName = "SHA1"; - algorithm = "TripleDES"; - keyLength = 16; - break; - case PKCS12.pbeWithSHAAnd128BitRC2CBC: // no unit test available - pd.HashName = "SHA1"; - algorithm = "RC2"; - keyLength = 16; - break; - case PKCS12.pbeWithSHAAnd40BitRC2CBC: - pd.HashName = "SHA1"; - algorithm = "RC2"; - keyLength = 5; - break; - default: - throw new NotSupportedException ("unknown oid " + algorithm); - } - - SymmetricAlgorithm sa = SymmetricAlgorithm.Create (algorithm); - sa.Key = pd.DeriveKey (keyLength); - // IV required only for block ciphers (not stream ciphers) - if (ivLength > 0) { - sa.IV = pd.DeriveIV (ivLength); - sa.Mode = CipherMode.CBC; - } - return sa; - } - - public byte[] Decrypt (string algorithmOid, byte[] salt, int iterationCount, byte[] encryptedData) - { - SymmetricAlgorithm sa = null; - byte[] result = null; - try { - sa = GetSymmetricAlgorithm (algorithmOid, salt, iterationCount); - ICryptoTransform ct = sa.CreateDecryptor (); - result = ct.TransformFinalBlock (encryptedData, 0, encryptedData.Length); - } - finally { - if (sa != null) - sa.Clear (); - } - return result; - } - - public byte[] Decrypt (PKCS7.EncryptedData ed) - { - return Decrypt (ed.EncryptionAlgorithm.ContentType, - ed.EncryptionAlgorithm.Content [0].Value, - ASN1Convert.ToInt32 (ed.EncryptionAlgorithm.Content [1]), - ed.EncryptedContent); - } - - public byte[] Encrypt (string algorithmOid, byte[] salt, int iterationCount, byte[] data) - { - byte[] result = null; - using (SymmetricAlgorithm sa = GetSymmetricAlgorithm (algorithmOid, salt, iterationCount)) { - ICryptoTransform ct = sa.CreateEncryptor (); - result = ct.TransformFinalBlock (data, 0, data.Length); - } - return result; - } - - private DSAParameters GetExistingParameters (out bool found) - { - foreach (X509Certificate cert in Certificates) { - // FIXME: that won't work if parts of the parameters are missing - if (cert.KeyAlgorithmParameters != null) { - DSA dsa = cert.DSA; - if (dsa != null) { - found = true; - return dsa.ExportParameters (false); - } - } - } - found = false; - return new DSAParameters (); - } - - private void AddPrivateKey (PKCS8.PrivateKeyInfo pki) - { - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - bool found; - DSAParameters p = GetExistingParameters (out found); - if (found) { - _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p)); - } - break; - case 0x30: - _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey)); - break; - default: - Array.Clear (privateKey, 0, privateKey.Length); - throw new CryptographicException ("Unknown private key format"); - } - Array.Clear (privateKey, 0, privateKey.Length); - } - - private void ReadSafeBag (ASN1 safeBag) - { - if (safeBag.Tag != 0x30) - throw new ArgumentException ("invalid safeBag"); - - ASN1 bagId = safeBag [0]; - if (bagId.Tag != 0x06) - throw new ArgumentException ("invalid safeBag id"); - - ASN1 bagValue = safeBag [1]; - string oid = ASN1Convert.ToOid (bagId); - switch (oid) { - case keyBag: - // NEED UNIT TEST - AddPrivateKey (new PKCS8.PrivateKeyInfo (bagValue.Value)); - break; - case pkcs8ShroudedKeyBag: - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); - byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); - AddPrivateKey (new PKCS8.PrivateKeyInfo (decrypted)); - Array.Clear (decrypted, 0, decrypted.Length); - break; - case certBag: - PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); - if (cert.ContentType != x509Certificate) - throw new NotSupportedException ("unsupport certificate type"); - X509Certificate x509 = new X509Certificate (cert.Content [0].Value); - _certs.Add (x509); - break; - case crlBag: - // TODO - break; - case secretBag: - byte[] secret = bagValue.Value; - _secretBags.Add(secret); - break; - case safeContentsBag: - // TODO - ? recurse ? - break; - default: - throw new ArgumentException ("unknown safeBag oid"); - } - - if (safeBag.Count > 2) { - ASN1 bagAttributes = safeBag [2]; - if (bagAttributes.Tag != 0x31) - throw new ArgumentException ("invalid safeBag attributes id"); - - for (int i = 0; i < bagAttributes.Count; i++) { - ASN1 pkcs12Attribute = bagAttributes[i]; - - if (pkcs12Attribute.Tag != 0x30) - throw new ArgumentException ("invalid PKCS12 attributes id"); - - ASN1 attrId = pkcs12Attribute [0]; - if (attrId.Tag != 0x06) - throw new ArgumentException ("invalid attribute id"); - - string attrOid = ASN1Convert.ToOid (attrId); - - ASN1 attrValues = pkcs12Attribute[1]; - for (int j = 0; j < attrValues.Count; j++) { - ASN1 attrValue = attrValues[j]; - - switch (attrOid) { - case PKCS9.friendlyName: - if (attrValue.Tag != 0x1e) - throw new ArgumentException ("invalid attribute value id"); - break; - case PKCS9.localKeyId: - if (attrValue.Tag != 0x04) - throw new ArgumentException ("invalid attribute value id"); - break; - default: - // Unknown OID -- don't check Tag - break; - } - } - } - } - - _safeBags.Add (new SafeBag(oid, safeBag)); - } - - private ASN1 Pkcs8ShroudedKeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes) - { - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (); - if (aa is RSA) { - pki.Algorithm = "1.2.840.113549.1.1.1"; - pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa); - } - else if (aa is DSA) { - pki.Algorithm = null; - pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa); - } - else - throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ()); - - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (); - epki.Algorithm = pbeWithSHAAnd3KeyTripleDESCBC; - epki.IterationCount = _iterations; - epki.EncryptedData = Encrypt (pbeWithSHAAnd3KeyTripleDESCBC, epki.Salt, _iterations, pki.GetBytes ()); - - ASN1 safeBag = new ASN1 (0x30); - safeBag.Add (ASN1Convert.FromOid (pkcs8ShroudedKeyBag)); - ASN1 bagValue = new ASN1 (0xA0); - bagValue.Add (new ASN1 (epki.GetBytes ())); - safeBag.Add (bagValue); - - if (attributes != null) { - ASN1 bagAttributes = new ASN1 (0x31); - IDictionaryEnumerator de = attributes.GetEnumerator (); - - while (de.MoveNext ()) { - string oid = (string)de.Key; - switch (oid) { - case PKCS9.friendlyName: - ArrayList names = (ArrayList)de.Value; - if (names.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] name in names) { - ASN1 attrValue = new ASN1 (0x1e); - attrValue.Value = name; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - case PKCS9.localKeyId: - ArrayList keys = (ArrayList)de.Value; - if (keys.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] key in keys) { - ASN1 attrValue = new ASN1 (0x04); - attrValue.Value = key; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - default: - break; - } - } - - if (bagAttributes.Count > 0) { - safeBag.Add (bagAttributes); - } - } - - return safeBag; - } - - private ASN1 KeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes) - { - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (); - if (aa is RSA) { - pki.Algorithm = "1.2.840.113549.1.1.1"; - pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa); - } - else if (aa is DSA) { - pki.Algorithm = null; - pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa); - } - else - throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ()); - - ASN1 safeBag = new ASN1 (0x30); - safeBag.Add (ASN1Convert.FromOid (keyBag)); - ASN1 bagValue = new ASN1 (0xA0); - bagValue.Add (new ASN1 (pki.GetBytes ())); - safeBag.Add (bagValue); - - if (attributes != null) { - ASN1 bagAttributes = new ASN1 (0x31); - IDictionaryEnumerator de = attributes.GetEnumerator (); - - while (de.MoveNext ()) { - string oid = (string)de.Key; - switch (oid) { - case PKCS9.friendlyName: - ArrayList names = (ArrayList)de.Value; - if (names.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] name in names) { - ASN1 attrValue = new ASN1 (0x1e); - attrValue.Value = name; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - case PKCS9.localKeyId: - ArrayList keys = (ArrayList)de.Value; - if (keys.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] key in keys) { - ASN1 attrValue = new ASN1 (0x04); - attrValue.Value = key; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - default: - break; - } - } - - if (bagAttributes.Count > 0) { - safeBag.Add (bagAttributes); - } - } - - return safeBag; - } - - private ASN1 SecretBagSafeBag (byte[] secret, IDictionary attributes) - { - ASN1 safeBag = new ASN1 (0x30); - safeBag.Add (ASN1Convert.FromOid (secretBag)); - ASN1 bagValue = new ASN1 (0x80, secret); - safeBag.Add (bagValue); - - if (attributes != null) { - ASN1 bagAttributes = new ASN1 (0x31); - IDictionaryEnumerator de = attributes.GetEnumerator (); - - while (de.MoveNext ()) { - string oid = (string)de.Key; - switch (oid) { - case PKCS9.friendlyName: - ArrayList names = (ArrayList)de.Value; - if (names.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] name in names) { - ASN1 attrValue = new ASN1 (0x1e); - attrValue.Value = name; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - case PKCS9.localKeyId: - ArrayList keys = (ArrayList)de.Value; - if (keys.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] key in keys) { - ASN1 attrValue = new ASN1 (0x04); - attrValue.Value = key; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - default: - break; - } - } - - if (bagAttributes.Count > 0) { - safeBag.Add (bagAttributes); - } - } - - return safeBag; - } - - private ASN1 CertificateSafeBag (X509Certificate x509, IDictionary attributes) - { - ASN1 encapsulatedCertificate = new ASN1 (0x04, x509.RawData); - - PKCS7.ContentInfo ci = new PKCS7.ContentInfo (); - ci.ContentType = x509Certificate; - ci.Content.Add (encapsulatedCertificate); - - ASN1 bagValue = new ASN1 (0xA0); - bagValue.Add (ci.ASN1); - - ASN1 safeBag = new ASN1 (0x30); - safeBag.Add (ASN1Convert.FromOid (certBag)); - safeBag.Add (bagValue); - - if (attributes != null) { - ASN1 bagAttributes = new ASN1 (0x31); - IDictionaryEnumerator de = attributes.GetEnumerator (); - - while (de.MoveNext ()) { - string oid = (string)de.Key; - switch (oid) { - case PKCS9.friendlyName: - ArrayList names = (ArrayList)de.Value; - if (names.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] name in names) { - ASN1 attrValue = new ASN1 (0x1e); - attrValue.Value = name; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - case PKCS9.localKeyId: - ArrayList keys = (ArrayList)de.Value; - if (keys.Count > 0) { - ASN1 pkcs12Attribute = new ASN1 (0x30); - pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); - ASN1 attrValues = new ASN1 (0x31); - foreach (byte[] key in keys) { - ASN1 attrValue = new ASN1 (0x04); - attrValue.Value = key; - attrValues.Add (attrValue); - } - pkcs12Attribute.Add (attrValues); - bagAttributes.Add (pkcs12Attribute); - } - break; - default: - break; - } - } - - if (bagAttributes.Count > 0) { - safeBag.Add (bagAttributes); - } - } - - return safeBag; - } - - private byte[] MAC (byte[] password, byte[] salt, int iterations, byte[] data) - { - PKCS12.DeriveBytes pd = new PKCS12.DeriveBytes (); - pd.HashName = "SHA1"; - pd.Password = password; - pd.Salt = salt; - pd.IterationCount = iterations; - - HMACSHA1 hmac = (HMACSHA1) HMACSHA1.Create (); - hmac.Key = pd.DeriveMAC (20); - return hmac.ComputeHash (data, 0, data.Length); - } - - /* - * SafeContents ::= SEQUENCE OF SafeBag - * - * SafeBag ::= SEQUENCE { - * bagId BAG-TYPE.&id ({PKCS12BagSet}), - * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), - * bagAttributes SET OF PKCS12Attribute OPTIONAL - * } - */ - public byte[] GetBytes () - { - // TODO (incomplete) - ASN1 safeBagSequence = new ASN1 (0x30); - - // Sync Safe Bag list since X509CertificateCollection may be updated - ArrayList scs = new ArrayList (); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (certBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); - scs.Add (new X509Certificate (cert.Content [0].Value)); - } - } - - ArrayList addcerts = new ArrayList (); - ArrayList removecerts = new ArrayList (); - - foreach (X509Certificate c in Certificates) { - bool found = false; - - foreach (X509Certificate lc in scs) { - if (Compare (c.RawData, lc.RawData)) { - found = true; - } - } - - if (!found) { - addcerts.Add (c); - } - } - foreach (X509Certificate c in scs) { - bool found = false; - - foreach (X509Certificate lc in Certificates) { - if (Compare (c.RawData, lc.RawData)) { - found = true; - } - } - - if (!found) { - removecerts.Add (c); - } - } - - foreach (X509Certificate c in removecerts) { - RemoveCertificate (c); - } - - foreach (X509Certificate c in addcerts) { - AddCertificate (c); - } - // Sync done - - if (_safeBags.Count > 0) { - ASN1 certsSafeBag = new ASN1 (0x30); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (certBag)) { - certsSafeBag.Add (sb.ASN1); - } - } - - if (certsSafeBag.Count > 0) { - PKCS7.ContentInfo contentInfo = EncryptedContentInfo (certsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC); - safeBagSequence.Add (contentInfo.ASN1); - } - } - - if (_safeBags.Count > 0) { - ASN1 safeContents = new ASN1 (0x30); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (keyBag) || - sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - safeContents.Add (sb.ASN1); - } - } - if (safeContents.Count > 0) { - ASN1 content = new ASN1 (0xA0); - content.Add (new ASN1 (0x04, safeContents.GetBytes ())); - - PKCS7.ContentInfo keyBag = new PKCS7.ContentInfo (PKCS7.Oid.data); - keyBag.Content = content; - safeBagSequence.Add (keyBag.ASN1); - } - } - - // Doing SecretBags separately in case we want to change their encryption independently. - if (_safeBags.Count > 0) { - ASN1 secretsSafeBag = new ASN1 (0x30); - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (secretBag)) { - secretsSafeBag.Add (sb.ASN1); - } - } - - if (secretsSafeBag.Count > 0) { - PKCS7.ContentInfo contentInfo = EncryptedContentInfo (secretsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC); - safeBagSequence.Add (contentInfo.ASN1); - } - } - - - ASN1 encapsulates = new ASN1 (0x04, safeBagSequence.GetBytes ()); - ASN1 ci = new ASN1 (0xA0); - ci.Add (encapsulates); - PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (PKCS7.Oid.data); - authSafe.Content = ci; - - ASN1 macData = new ASN1 (0x30); - if (_password != null) { - // only for password based encryption - byte[] salt = new byte [20]; - RNG.GetBytes (salt); - byte[] macValue = MAC (_password, salt, _iterations, authSafe.Content [0].Value); - ASN1 oidSeq = new ASN1 (0x30); - oidSeq.Add (ASN1Convert.FromOid ("1.3.14.3.2.26")); // SHA1 - oidSeq.Add (new ASN1 (0x05)); - - ASN1 mac = new ASN1 (0x30); - mac.Add (oidSeq); - mac.Add (new ASN1 (0x04, macValue)); - - macData.Add (mac); - macData.Add (new ASN1 (0x04, salt)); - macData.Add (ASN1Convert.FromInt32 (_iterations)); - } - - ASN1 version = new ASN1 (0x02, new byte [1] { 0x03 }); - - ASN1 pfx = new ASN1 (0x30); - pfx.Add (version); - pfx.Add (authSafe.ASN1); - if (macData.Count > 0) { - // only for password based encryption - pfx.Add (macData); - } - - return pfx.GetBytes (); - } - - // Creates an encrypted PKCS#7 ContentInfo with safeBags as its SafeContents. Used in GetBytes(), above. - private PKCS7.ContentInfo EncryptedContentInfo(ASN1 safeBags, string algorithmOid) - { - byte[] salt = new byte [8]; - RNG.GetBytes (salt); - - ASN1 seqParams = new ASN1 (0x30); - seqParams.Add (new ASN1 (0x04, salt)); - seqParams.Add (ASN1Convert.FromInt32 (_iterations)); - - ASN1 seqPbe = new ASN1 (0x30); - seqPbe.Add (ASN1Convert.FromOid (algorithmOid)); - seqPbe.Add (seqParams); - - byte[] encrypted = Encrypt (algorithmOid, salt, _iterations, safeBags.GetBytes ()); - ASN1 encryptedContent = new ASN1 (0x80, encrypted); - - ASN1 seq = new ASN1 (0x30); - seq.Add (ASN1Convert.FromOid (PKCS7.Oid.data)); - seq.Add (seqPbe); - seq.Add (encryptedContent); - - ASN1 version = new ASN1 (0x02, new byte [1] { 0x00 }); - ASN1 encData = new ASN1 (0x30); - encData.Add (version); - encData.Add (seq); - - ASN1 finalContent = new ASN1 (0xA0); - finalContent.Add (encData); - - PKCS7.ContentInfo bag = new PKCS7.ContentInfo (PKCS7.Oid.encryptedData); - bag.Content = finalContent; - return bag; - } - - public void AddCertificate (X509Certificate cert) - { - AddCertificate (cert, null); - } - - public void AddCertificate (X509Certificate cert, IDictionary attributes) - { - bool found = false; - - for (int i = 0; !found && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (certBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); - X509Certificate c = new X509Certificate (crt.Content [0].Value); - if (Compare (cert.RawData, c.RawData)) { - found = true; - } - } - } - - if (!found) { - _safeBags.Add (new SafeBag (certBag, CertificateSafeBag (cert, attributes))); - _certsChanged = true; - } - } - - public void RemoveCertificate (X509Certificate cert) - { - RemoveCertificate (cert, null); - } - - public void RemoveCertificate (X509Certificate cert, IDictionary attrs) - { - int certIndex = -1; - - for (int i = 0; certIndex == -1 && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (certBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); - X509Certificate c = new X509Certificate (crt.Content [0].Value); - if (Compare (cert.RawData, c.RawData)) { - if (attrs != null) { - if (safeBag.Count == 3) { - ASN1 bagAttributes = safeBag [2]; - int bagAttributesFound = 0; - for (int j = 0; j < bagAttributes.Count; j++) { - ASN1 pkcs12Attribute = bagAttributes [j]; - ASN1 attrId = pkcs12Attribute [0]; - string ao = ASN1Convert.ToOid (attrId); - ArrayList dattrValues = (ArrayList)attrs [ao]; - - if (dattrValues != null) { - ASN1 attrValues = pkcs12Attribute [1]; - - if (dattrValues.Count == attrValues.Count) { - int attrValuesFound = 0; - for (int k = 0; k < attrValues.Count; k++) { - ASN1 attrValue = attrValues [k]; - byte[] value = (byte[])dattrValues [k]; - - if (Compare (value, attrValue.Value)) { - attrValuesFound += 1; - } - } - if (attrValuesFound == attrValues.Count) { - bagAttributesFound += 1; - } - } - } - } - if (bagAttributesFound == bagAttributes.Count) { - certIndex = i; - } - } - } else { - certIndex = i; - } - } - } - } - - if (certIndex != -1) { - _safeBags.RemoveAt (certIndex); - _certsChanged = true; - } - } - - private bool CompareAsymmetricAlgorithm (AsymmetricAlgorithm a1, AsymmetricAlgorithm a2) - { - // fast path - if (a1.KeySize != a2.KeySize) - return false; - // compare public keys - if they match we can assume the private match too - return (a1.ToXmlString (false) == a2.ToXmlString (false)); - } - - public void AddPkcs8ShroudedKeyBag (AsymmetricAlgorithm aa) - { - AddPkcs8ShroudedKeyBag (aa, null); - } - - public void AddPkcs8ShroudedKeyBag (AsymmetricAlgorithm aa, IDictionary attributes) - { - bool found = false; - - for (int i = 0; !found && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - ASN1 bagValue = sb.ASN1 [1]; - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); - byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); - byte[] privateKey = pki.PrivateKey; - - AsymmetricAlgorithm saa = null; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - Array.Clear (decrypted, 0, decrypted.Length); - Array.Clear (privateKey, 0, privateKey.Length); - throw new CryptographicException ("Unknown private key format"); - } - - Array.Clear (decrypted, 0, decrypted.Length); - Array.Clear (privateKey, 0, privateKey.Length); - - if (CompareAsymmetricAlgorithm (aa , saa)) { - found = true; - } - } - } - - if (!found) { - _safeBags.Add (new SafeBag (pkcs8ShroudedKeyBag, Pkcs8ShroudedKeyBagSafeBag (aa, attributes))); - _keyBagsChanged = true; - } - } - - public void RemovePkcs8ShroudedKeyBag (AsymmetricAlgorithm aa) - { - int aaIndex = -1; - - for (int i = 0; aaIndex == -1 && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - ASN1 bagValue = sb.ASN1 [1]; - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); - byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); - byte[] privateKey = pki.PrivateKey; - - AsymmetricAlgorithm saa = null; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - Array.Clear (decrypted, 0, decrypted.Length); - Array.Clear (privateKey, 0, privateKey.Length); - throw new CryptographicException ("Unknown private key format"); - } - - Array.Clear (decrypted, 0, decrypted.Length); - Array.Clear (privateKey, 0, privateKey.Length); - - if (CompareAsymmetricAlgorithm (aa, saa)) { - aaIndex = i; - } - } - } - - if (aaIndex != -1) { - _safeBags.RemoveAt (aaIndex); - _keyBagsChanged = true; - } - } - - public void AddKeyBag (AsymmetricAlgorithm aa) - { - AddKeyBag (aa, null); - } - - public void AddKeyBag (AsymmetricAlgorithm aa, IDictionary attributes) - { - bool found = false; - - for (int i = 0; !found && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (keyBag)) { - ASN1 bagValue = sb.ASN1 [1]; - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); - byte[] privateKey = pki.PrivateKey; - - AsymmetricAlgorithm saa = null; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - Array.Clear (privateKey, 0, privateKey.Length); - throw new CryptographicException ("Unknown private key format"); - } - - Array.Clear (privateKey, 0, privateKey.Length); - - if (CompareAsymmetricAlgorithm (aa, saa)) { - found = true; - } - } - } - - if (!found) { - _safeBags.Add (new SafeBag (keyBag, KeyBagSafeBag (aa, attributes))); - _keyBagsChanged = true; - } - } - - public void RemoveKeyBag (AsymmetricAlgorithm aa) - { - int aaIndex = -1; - - for (int i = 0; aaIndex == -1 && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (keyBag)) { - ASN1 bagValue = sb.ASN1 [1]; - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); - byte[] privateKey = pki.PrivateKey; - - AsymmetricAlgorithm saa = null; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - Array.Clear (privateKey, 0, privateKey.Length); - throw new CryptographicException ("Unknown private key format"); - } - - Array.Clear (privateKey, 0, privateKey.Length); - - if (CompareAsymmetricAlgorithm (aa, saa)) { - aaIndex = i; - } - } - } - - if (aaIndex != -1) { - _safeBags.RemoveAt (aaIndex); - _keyBagsChanged = true; - } - } - - public void AddSecretBag (byte[] secret) - { - AddSecretBag (secret, null); - } - - public void AddSecretBag (byte[] secret, IDictionary attributes) - { - bool found = false; - - for (int i = 0; !found && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (secretBag)) { - ASN1 bagValue = sb.ASN1 [1]; - byte[] ssecret = bagValue.Value; - - if (Compare (secret, ssecret)) { - found = true; - } - } - } - - if (!found) { - _safeBags.Add (new SafeBag (secretBag, SecretBagSafeBag (secret, attributes))); - _secretBagsChanged = true; - } - } - - public void RemoveSecretBag (byte[] secret) - { - int sIndex = -1; - - for (int i = 0; sIndex == -1 && i < _safeBags.Count; i++) { - SafeBag sb = (SafeBag)_safeBags [i]; - - if (sb.BagOID.Equals (secretBag)) { - ASN1 bagValue = sb.ASN1 [1]; - byte[] ssecret = bagValue.Value; - - if (Compare (secret, ssecret)) { - sIndex = i; - } - } - } - - if (sIndex != -1) { - _safeBags.RemoveAt (sIndex); - _secretBagsChanged = true; - } - } - - public AsymmetricAlgorithm GetAsymmetricAlgorithm (IDictionary attrs) - { - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - ASN1 safeBag = sb.ASN1; - - if (safeBag.Count == 3) { - ASN1 bagAttributes = safeBag [2]; - - int bagAttributesFound = 0; - for (int i = 0; i < bagAttributes.Count; i++) { - ASN1 pkcs12Attribute = bagAttributes [i]; - ASN1 attrId = pkcs12Attribute [0]; - string ao = ASN1Convert.ToOid (attrId); - ArrayList dattrValues = (ArrayList)attrs [ao]; - - if (dattrValues != null) { - ASN1 attrValues = pkcs12Attribute [1]; - - if (dattrValues.Count == attrValues.Count) { - int attrValuesFound = 0; - for (int j = 0; j < attrValues.Count; j++) { - ASN1 attrValue = attrValues [j]; - byte[] value = (byte[])dattrValues [j]; - - if (Compare (value, attrValue.Value)) { - attrValuesFound += 1; - } - } - if (attrValuesFound == attrValues.Count) { - bagAttributesFound += 1; - } - } - } - } - if (bagAttributesFound == bagAttributes.Count) { - ASN1 bagValue = safeBag [1]; - AsymmetricAlgorithm aa = null; - if (sb.BagOID.Equals (keyBag)) { - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - aa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - aa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - break; - } - Array.Clear (privateKey, 0, privateKey.Length); - } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); - byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - aa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - aa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - break; - } - Array.Clear (privateKey, 0, privateKey.Length); - Array.Clear (decrypted, 0, decrypted.Length); - } - return aa; - } - } - } - } - - return null; - } - - public byte[] GetSecret (IDictionary attrs) - { - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (secretBag)) { - ASN1 safeBag = sb.ASN1; - - if (safeBag.Count == 3) { - ASN1 bagAttributes = safeBag [2]; - - int bagAttributesFound = 0; - for (int i = 0; i < bagAttributes.Count; i++) { - ASN1 pkcs12Attribute = bagAttributes [i]; - ASN1 attrId = pkcs12Attribute [0]; - string ao = ASN1Convert.ToOid (attrId); - ArrayList dattrValues = (ArrayList)attrs [ao]; - - if (dattrValues != null) { - ASN1 attrValues = pkcs12Attribute [1]; - - if (dattrValues.Count == attrValues.Count) { - int attrValuesFound = 0; - for (int j = 0; j < attrValues.Count; j++) { - ASN1 attrValue = attrValues [j]; - byte[] value = (byte[])dattrValues [j]; - - if (Compare (value, attrValue.Value)) { - attrValuesFound += 1; - } - } - if (attrValuesFound == attrValues.Count) { - bagAttributesFound += 1; - } - } - } - } - if (bagAttributesFound == bagAttributes.Count) { - ASN1 bagValue = safeBag [1]; - return bagValue.Value; - } - } - } - } - - return null; - } - - public X509Certificate GetCertificate (IDictionary attrs) - { - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (certBag)) { - ASN1 safeBag = sb.ASN1; - - if (safeBag.Count == 3) { - ASN1 bagAttributes = safeBag [2]; - - int bagAttributesFound = 0; - for (int i = 0; i < bagAttributes.Count; i++) { - ASN1 pkcs12Attribute = bagAttributes [i]; - ASN1 attrId = pkcs12Attribute [0]; - string ao = ASN1Convert.ToOid (attrId); - ArrayList dattrValues = (ArrayList)attrs [ao]; - - if (dattrValues != null) { - ASN1 attrValues = pkcs12Attribute [1]; - - if (dattrValues.Count == attrValues.Count) { - int attrValuesFound = 0; - for (int j = 0; j < attrValues.Count; j++) { - ASN1 attrValue = attrValues [j]; - byte[] value = (byte[])dattrValues [j]; - - if (Compare (value, attrValue.Value)) { - attrValuesFound += 1; - } - } - if (attrValuesFound == attrValues.Count) { - bagAttributesFound += 1; - } - } - } - } - if (bagAttributesFound == bagAttributes.Count) { - ASN1 bagValue = safeBag [1]; - PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); - return new X509Certificate (crt.Content [0].Value); - } - } - } - } - - return null; - } - - public IDictionary GetAttributes (AsymmetricAlgorithm aa) - { - IDictionary result = new Hashtable (); - - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - ASN1 safeBag = sb.ASN1; - - ASN1 bagValue = safeBag [1]; - AsymmetricAlgorithm saa = null; - if (sb.BagOID.Equals (keyBag)) { - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - break; - } - Array.Clear (privateKey, 0, privateKey.Length); - } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { - PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); - byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); - PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); - byte[] privateKey = pki.PrivateKey; - switch (privateKey [0]) { - case 0x02: - DSAParameters p = new DSAParameters (); // FIXME - saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); - break; - case 0x30: - saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); - break; - default: - break; - } - Array.Clear (privateKey, 0, privateKey.Length); - Array.Clear (decrypted, 0, decrypted.Length); - } - - if (saa != null && CompareAsymmetricAlgorithm (saa, aa)) { - if (safeBag.Count == 3) { - ASN1 bagAttributes = safeBag [2]; - - for (int i = 0; i < bagAttributes.Count; i++) { - ASN1 pkcs12Attribute = bagAttributes [i]; - ASN1 attrId = pkcs12Attribute [0]; - string aOid = ASN1Convert.ToOid (attrId); - ArrayList aValues = new ArrayList (); - - ASN1 attrValues = pkcs12Attribute [1]; - - for (int j = 0; j < attrValues.Count; j++) { - ASN1 attrValue = attrValues [j]; - aValues.Add (attrValue.Value); - } - result.Add (aOid, aValues); - } - } - } - } - } - - return result; - } - - public IDictionary GetAttributes (X509Certificate cert) - { - IDictionary result = new Hashtable (); - - foreach (SafeBag sb in _safeBags) { - if (sb.BagOID.Equals (certBag)) { - ASN1 safeBag = sb.ASN1; - ASN1 bagValue = safeBag [1]; - PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); - X509Certificate xc = new X509Certificate (crt.Content [0].Value); - - if (Compare (cert.RawData, xc.RawData)) { - if (safeBag.Count == 3) { - ASN1 bagAttributes = safeBag [2]; - - for (int i = 0; i < bagAttributes.Count; i++) { - ASN1 pkcs12Attribute = bagAttributes [i]; - ASN1 attrId = pkcs12Attribute [0]; - - string aOid = ASN1Convert.ToOid (attrId); - ArrayList aValues = new ArrayList (); - - ASN1 attrValues = pkcs12Attribute [1]; - - for (int j = 0; j < attrValues.Count; j++) { - ASN1 attrValue = attrValues [j]; - aValues.Add (attrValue.Value); - } - result.Add (aOid, aValues); - } - } - } - } - } - - return result; - } - - public void SaveToFile (string filename) - { - if (filename == null) - throw new ArgumentNullException ("filename"); - - using (FileStream fs = File.Create (filename)) { - byte[] data = GetBytes (); - fs.Write (data, 0, data.Length); - } - } - - public object Clone () - { - PKCS12 clone = null; - if (_password != null) { - clone = new PKCS12 (GetBytes (), Encoding.BigEndianUnicode.GetString (_password)); - } else { - clone = new PKCS12 (GetBytes ()); - } - clone.IterationCount = this.IterationCount; - - return clone; - } - - // static - - public const int CryptoApiPasswordLimit = 32; - - static private int password_max_length = Int32.MaxValue; - - // static properties - - // MS CryptoAPI limits the password to a maximum of 31 characters - // other implementations, like OpenSSL, have no such limitation. - // Setting a maximum value will truncate the password length to - // ensure compatibility with MS's PFXImportCertStore API. - static public int MaximumPasswordLength { - get { return password_max_length; } - set { - if (value < CryptoApiPasswordLimit) { - string msg = Locale.GetText ("Maximum password length cannot be less than {0}.", CryptoApiPasswordLimit); - throw new ArgumentOutOfRangeException (msg); - } - password_max_length = value; - } - } - - // static methods - - static private byte[] LoadFile (string filename) - { - byte[] data = null; - using (FileStream fs = File.OpenRead (filename)) { - data = new byte [fs.Length]; - fs.Read (data, 0, data.Length); - fs.Close (); - } - return data; - } - - static public PKCS12 LoadFromFile (string filename) - { - if (filename == null) - throw new ArgumentNullException ("filename"); - - return new PKCS12 (LoadFile (filename)); - } - - static public PKCS12 LoadFromFile (string filename, string password) - { - if (filename == null) - throw new ArgumentNullException ("filename"); - - return new PKCS12 (LoadFile (filename), password); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/TestAnchors.cs b/mcs/class/corlib/Mono.Security.X509/TestAnchors.cs deleted file mode 100644 index 2319f28109a..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/TestAnchors.cs +++ /dev/null @@ -1,137 +0,0 @@ -// -// TestAnchors.cs: Trust Anchors for development and debugging -// include test certificates for Microsoft (root agency) and Mono -// -// Author: -// Sebastien Pouliot (spouliot@motus.com) -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class TestAnchors : TrustAnchors { - - static byte[] rootagency = { - 0x30, 0x82, 0x01, 0xCA, 0x30, 0x82, 0x01, 0x74, 0xA0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x06, 0x37, 0x6C, 0x00, 0xAA, 0x00, 0x64, 0x8A, 0x11, - 0xCF, 0xB8, 0xD4, 0xAA, 0x5C, 0x35, 0xF4, 0x30, 0x0D, 0x06, 0x09, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x16, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0B, 0x52, - 0x6F, 0x6F, 0x74, 0x20, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x79, 0x30, 0x1E, - 0x17, 0x0D, 0x39, 0x36, 0x30, 0x35, 0x32, 0x38, 0x32, 0x32, 0x30, 0x32, - 0x35, 0x39, 0x5A, 0x17, 0x0D, 0x33, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, - 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x16, 0x31, 0x14, 0x30, 0x12, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0B, 0x52, 0x6F, 0x6F, 0x74, 0x20, - 0x41, 0x67, 0x65, 0x6E, 0x63, 0x79, 0x30, 0x5B, 0x30, 0x0D, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x4A, 0x00, 0x30, 0x47, 0x02, 0x40, 0x81, 0x55, 0x22, 0xB9, 0x8A, 0xA4, - 0x6F, 0xED, 0xD6, 0xE7, 0xD9, 0x66, 0x0F, 0x55, 0xBC, 0xD7, 0xCD, 0xD5, - 0xBC, 0x4E, 0x40, 0x02, 0x21, 0xA2, 0xB1, 0xF7, 0x87, 0x30, 0x85, 0x5E, - 0xD2, 0xF2, 0x44, 0xB9, 0xDC, 0x9B, 0x75, 0xB6, 0xFB, 0x46, 0x5F, 0x42, - 0xB6, 0x9D, 0x23, 0x36, 0x0B, 0xDE, 0x54, 0x0F, 0xCD, 0xBD, 0x1F, 0x99, - 0x2A, 0x10, 0x58, 0x11, 0xCB, 0x40, 0xCB, 0xB5, 0xA7, 0x41, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xA3, 0x81, 0x9E, 0x30, 0x81, 0x9B, 0x30, 0x50, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x04, 0x49, 0x13, 0x47, 0x46, 0x6F, 0x72, 0x20, - 0x54, 0x65, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x50, 0x75, 0x72, 0x70, - 0x6F, 0x73, 0x65, 0x73, 0x20, 0x4F, 0x6E, 0x6C, 0x79, 0x20, 0x53, 0x61, - 0x6D, 0x70, 0x6C, 0x65, 0x20, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, - 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x69, 0x6E, 0x67, - 0x20, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x61, 0x6C, 0x73, - 0x20, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x79, 0x30, 0x47, 0x06, 0x03, 0x55, - 0x1D, 0x01, 0x04, 0x40, 0x30, 0x3E, 0x80, 0x10, 0x12, 0xE4, 0x09, 0x2D, - 0x06, 0x1D, 0x1D, 0x4F, 0x00, 0x8D, 0x61, 0x21, 0xDC, 0x16, 0x64, 0x63, - 0xA1, 0x18, 0x30, 0x16, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x0B, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x41, 0x67, 0x65, 0x6E, - 0x63, 0x79, 0x82, 0x10, 0x06, 0x37, 0x6C, 0x00, 0xAA, 0x00, 0x64, 0x8A, - 0x11, 0xCF, 0xB8, 0xD4, 0xAA, 0x5C, 0x35, 0xF4, 0x30, 0x0D, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, - 0x41, 0x00, 0x2D, 0x2E, 0x3E, 0x7B, 0x89, 0x42, 0x89, 0x3F, 0xA8, 0x21, - 0x17, 0xFA, 0xF0, 0xF5, 0xC3, 0x95, 0xDB, 0x62, 0x69, 0x5B, 0xC9, 0xDC, - 0xC1, 0xB3, 0xFA, 0xF0, 0xC4, 0x6F, 0x6F, 0x64, 0x9A, 0xBD, 0xE7, 0x1B, - 0x25, 0x68, 0x72, 0x83, 0x67, 0xBD, 0x56, 0xB0, 0x8D, 0x01, 0xBD, 0x2A, - 0xF7, 0xCC, 0x4B, 0xBD, 0x87, 0xA5, 0xBA, 0x87, 0x20, 0x4C, 0x42, 0x11, - 0x41, 0xAD, 0x10, 0x17, 0x3B, 0x8C }; - - static byte[] monoTestRoot = { - 0x30, 0x82, 0x01, 0xC2, 0x30, 0x82, 0x01, 0x2B, 0xA0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x28, 0xF4, 0x76, 0x38, 0x91, 0x74, 0x0E, 0x48, 0x85, - 0xC7, 0x6E, 0x88, 0x4F, 0xE1, 0xB0, 0x69, 0x30, 0x0D, 0x06, 0x09, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x20, - 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x4D, - 0x6F, 0x6E, 0x6F, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, - 0x74, 0x20, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x79, 0x30, 0x1E, 0x17, 0x0D, - 0x30, 0x33, 0x30, 0x39, 0x30, 0x31, 0x31, 0x35, 0x35, 0x35, 0x34, 0x38, - 0x5A, 0x17, 0x0D, 0x33, 0x39, 0x31, 0x32, 0x33, 0x31, 0x31, 0x38, 0x35, - 0x39, 0x35, 0x39, 0x5A, 0x30, 0x20, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x15, 0x4D, 0x6F, 0x6E, 0x6F, 0x20, 0x54, 0x65, - 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x41, 0x67, 0x65, 0x6E, - 0x63, 0x79, 0x30, 0x81, 0x9E, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8C, 0x00, - 0x30, 0x81, 0x88, 0x02, 0x81, 0x80, 0xBF, 0xFE, 0x27, 0x00, 0xB0, 0x71, - 0x08, 0x4F, 0xBD, 0x26, 0x01, 0x02, 0xD0, 0xB9, 0xC3, 0x52, 0xF2, 0xA1, - 0xE9, 0xEF, 0x7A, 0x3F, 0x04, 0xE9, 0x37, 0x84, 0x63, 0xFA, 0xF5, 0xA7, - 0xA8, 0xA4, 0xFB, 0x20, 0x0A, 0x75, 0x88, 0xAF, 0xC9, 0x8E, 0xEA, 0xAF, - 0x02, 0x0E, 0x83, 0x43, 0x6B, 0xD3, 0x7E, 0xFD, 0x1D, 0x4E, 0x5A, 0x9F, - 0x7E, 0x61, 0xC7, 0xE7, 0x53, 0xB2, 0x8A, 0x8A, 0x6B, 0x71, 0x3E, 0x67, - 0xCF, 0x17, 0x12, 0x4E, 0xC6, 0x5B, 0xFF, 0xD8, 0xDC, 0x1D, 0x27, 0x06, - 0xD2, 0xCD, 0xFF, 0x15, 0x12, 0x16, 0x9D, 0x77, 0x8B, 0x93, 0xF7, 0xE0, - 0x9B, 0xB9, 0x92, 0x62, 0x18, 0xD4, 0x68, 0x73, 0x48, 0xD2, 0x6D, 0x7F, - 0x35, 0x34, 0xE4, 0xB6, 0x2A, 0x62, 0x72, 0x32, 0xB1, 0xA3, 0xBD, 0x61, - 0x18, 0x88, 0x3D, 0xAA, 0xE7, 0x02, 0x5A, 0x70, 0xEE, 0x9B, 0xE2, 0xAB, - 0x87, 0xF9, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0x8E, 0x08, 0xD7, 0x0F, 0x30, 0xB2, 0xFD, 0x3A, 0x5C, 0x94, - 0xA9, 0x56, 0xBE, 0x44, 0x77, 0xE3, 0xA3, 0x92, 0xBC, 0xB9, 0xE4, 0x95, - 0x68, 0xD4, 0xF4, 0xF9, 0x24, 0x4B, 0x2A, 0x79, 0x93, 0x57, 0x7E, 0x84, - 0x50, 0x3F, 0xA9, 0xC8, 0xDA, 0x9E, 0x08, 0x9C, 0x21, 0xE1, 0x10, 0xFC, - 0x1C, 0x5C, 0x4B, 0x60, 0x97, 0xBA, 0x55, 0xCB, 0x7C, 0xEA, 0xC3, 0x04, - 0x2F, 0x55, 0xBB, 0x16, 0x26, 0xCD, 0x87, 0x90, 0x30, 0x7F, 0xE0, 0xCF, - 0x24, 0x27, 0xB4, 0x3A, 0xD0, 0x9F, 0xC7, 0x55, 0xF8, 0x7C, 0xC9, 0xA0, - 0x72, 0xE4, 0x06, 0xF1, 0x4A, 0x5B, 0xBB, 0x71, 0x84, 0x8B, 0x76, 0x23, - 0x65, 0x1F, 0x1B, 0xEA, 0x96, 0x85, 0x13, 0x84, 0x0C, 0x8C, 0xCD, 0xDA, - 0x3D, 0x1F, 0xEB, 0xA9, 0xA7, 0xDF, 0xE0, 0xD1, 0xDC, 0x93, 0x21, 0x7A, - 0x10, 0xA7, 0x92, 0x63, 0x5D, 0xAB, 0xA2, 0x13, 0x37, 0xA4 }; - - static TestAnchors () - { - // add Microsoft Test Root for people who used MS makecert to create - // their Authenticode(tm) test certificates - coll.Add (new X509Certificate (rootagency)); - - // add Mono Test Root for people who used Mono makecert to create - // their Authenticode(tm) test certificates - coll.Add (new X509Certificate (monoTestRoot)); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/TrustAnchors.cs b/mcs/class/corlib/Mono.Security.X509/TrustAnchors.cs deleted file mode 100644 index 26832a43499..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/TrustAnchors.cs +++ /dev/null @@ -1,381 +0,0 @@ -// -// TrustAnchors.cs: "Official" default Trust Anchors for Mono -// -// Author: -// Sebastien Pouliot (spouliot@motus.com) -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class TrustAnchors : ITrustAnchors { - - static byte[] msroot = { - 0x30, 0x82, 0x04, 0x12, 0x30, 0x82, 0x02, 0xFA, 0xA0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x0F, 0x00, 0xC1, 0x00, 0x8B, 0x3C, 0x3C, 0x88, 0x11, 0xD1, - 0x3E, 0xF6, 0x63, 0xEC, 0xDF, 0x40, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x70, 0x31, - 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, 0x43, 0x6F, - 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, - 0x31, 0x39, 0x39, 0x37, 0x20, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, - 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x1E, 0x30, 0x1C, - 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, - 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x18, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, - 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, - 0x69, 0x74, 0x79, 0x30, 0x1E, 0x17, 0x0D, 0x39, 0x37, 0x30, 0x31, 0x31, - 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x30, - 0x31, 0x32, 0x33, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, - 0x70, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, - 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, - 0x29, 0x20, 0x31, 0x39, 0x39, 0x37, 0x20, 0x4D, 0x69, 0x63, 0x72, 0x6F, - 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x1E, - 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x15, 0x4D, 0x69, 0x63, - 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, - 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x18, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, - 0x66, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6F, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, - 0x01, 0x00, 0xA9, 0x02, 0xBD, 0xC1, 0x70, 0xE6, 0x3B, 0xF2, 0x4E, 0x1B, - 0x28, 0x9F, 0x97, 0x78, 0x5E, 0x30, 0xEA, 0xA2, 0xA9, 0x8D, 0x25, 0x5F, - 0xF8, 0xFE, 0x95, 0x4C, 0xA3, 0xB7, 0xFE, 0x9D, 0xA2, 0x20, 0x3E, 0x7C, - 0x51, 0xA2, 0x9B, 0xA2, 0x8F, 0x60, 0x32, 0x6B, 0xD1, 0x42, 0x64, 0x79, - 0xEE, 0xAC, 0x76, 0xC9, 0x54, 0xDA, 0xF2, 0xEB, 0x9C, 0x86, 0x1C, 0x8F, - 0x9F, 0x84, 0x66, 0xB3, 0xC5, 0x6B, 0x7A, 0x62, 0x23, 0xD6, 0x1D, 0x3C, - 0xDE, 0x0F, 0x01, 0x92, 0xE8, 0x96, 0xC4, 0xBF, 0x2D, 0x66, 0x9A, 0x9A, - 0x68, 0x26, 0x99, 0xD0, 0x3A, 0x2C, 0xBF, 0x0C, 0xB5, 0x58, 0x26, 0xC1, - 0x46, 0xE7, 0x0A, 0x3E, 0x38, 0x96, 0x2C, 0xA9, 0x28, 0x39, 0xA8, 0xEC, - 0x49, 0x83, 0x42, 0xE3, 0x84, 0x0F, 0xBB, 0x9A, 0x6C, 0x55, 0x61, 0xAC, - 0x82, 0x7C, 0xA1, 0x60, 0x2D, 0x77, 0x4C, 0xE9, 0x99, 0xB4, 0x64, 0x3B, - 0x9A, 0x50, 0x1C, 0x31, 0x08, 0x24, 0x14, 0x9F, 0xA9, 0xE7, 0x91, 0x2B, - 0x18, 0xE6, 0x3D, 0x98, 0x63, 0x14, 0x60, 0x58, 0x05, 0x65, 0x9F, 0x1D, - 0x37, 0x52, 0x87, 0xF7, 0xA7, 0xEF, 0x94, 0x02, 0xC6, 0x1B, 0xD3, 0xBF, - 0x55, 0x45, 0xB3, 0x89, 0x80, 0xBF, 0x3A, 0xEC, 0x54, 0x94, 0x4E, 0xAE, - 0xFD, 0xA7, 0x7A, 0x6D, 0x74, 0x4E, 0xAF, 0x18, 0xCC, 0x96, 0x09, 0x28, - 0x21, 0x00, 0x57, 0x90, 0x60, 0x69, 0x37, 0xBB, 0x4B, 0x12, 0x07, 0x3C, - 0x56, 0xFF, 0x5B, 0xFB, 0xA4, 0x66, 0x0A, 0x08, 0xA6, 0xD2, 0x81, 0x56, - 0x57, 0xEF, 0xB6, 0x3B, 0x5E, 0x16, 0x81, 0x77, 0x04, 0xDA, 0xF6, 0xBE, - 0xAE, 0x80, 0x95, 0xFE, 0xB0, 0xCD, 0x7F, 0xD6, 0xA7, 0x1A, 0x72, 0x5C, - 0x3C, 0xCA, 0xBC, 0xF0, 0x08, 0xA3, 0x22, 0x30, 0xB3, 0x06, 0x85, 0xC9, - 0xB3, 0x20, 0x77, 0x13, 0x85, 0xDF, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, - 0x81, 0xA8, 0x30, 0x81, 0xA5, 0x30, 0x81, 0xA2, 0x06, 0x03, 0x55, 0x1D, - 0x01, 0x04, 0x81, 0x9A, 0x30, 0x81, 0x97, 0x80, 0x10, 0x5B, 0xD0, 0x70, - 0xEF, 0x69, 0x72, 0x9E, 0x23, 0x51, 0x7E, 0x14, 0xB2, 0x4D, 0x8E, 0xFF, - 0xCB, 0xA1, 0x72, 0x30, 0x70, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, - 0x04, 0x0B, 0x13, 0x22, 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x37, 0x20, 0x4D, - 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, - 0x70, 0x2E, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, - 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, - 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x21, - 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x4D, 0x69, 0x63, - 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, - 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x82, 0x0F, 0x00, - 0xC1, 0x00, 0x8B, 0x3C, 0x3C, 0x88, 0x11, 0xD1, 0x3E, 0xF6, 0x63, 0xEC, - 0xDF, 0x40, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x95, 0xE8, - 0x0B, 0xC0, 0x8D, 0xF3, 0x97, 0x18, 0x35, 0xED, 0xB8, 0x01, 0x24, 0xD8, - 0x77, 0x11, 0xF3, 0x5C, 0x60, 0x32, 0x9F, 0x9E, 0x0B, 0xCB, 0x3E, 0x05, - 0x91, 0x88, 0x8F, 0xC9, 0x3A, 0xE6, 0x21, 0xF2, 0xF0, 0x57, 0x93, 0x2C, - 0xB5, 0xA0, 0x47, 0xC8, 0x62, 0xEF, 0xFC, 0xD7, 0xCC, 0x3B, 0x3B, 0x5A, - 0xA9, 0x36, 0x54, 0x69, 0xFE, 0x24, 0x6D, 0x3F, 0xC9, 0xCC, 0xAA, 0xDE, - 0x05, 0x7C, 0xDD, 0x31, 0x8D, 0x3D, 0x9F, 0x10, 0x70, 0x6A, 0xBB, 0xFE, - 0x12, 0x4F, 0x18, 0x69, 0xC0, 0xFC, 0xD0, 0x43, 0xE3, 0x11, 0x5A, 0x20, - 0x4F, 0xEA, 0x62, 0x7B, 0xAF, 0xAA, 0x19, 0xC8, 0x2B, 0x37, 0x25, 0x2D, - 0xBE, 0x65, 0xA1, 0x12, 0x8A, 0x25, 0x0F, 0x63, 0xA3, 0xF7, 0x54, 0x1C, - 0xF9, 0x21, 0xC9, 0xD6, 0x15, 0xF3, 0x52, 0xAC, 0x6E, 0x43, 0x32, 0x07, - 0xFD, 0x82, 0x17, 0xF8, 0xE5, 0x67, 0x6C, 0x0D, 0x51, 0xF6, 0xBD, 0xF1, - 0x52, 0xC7, 0xBD, 0xE7, 0xC4, 0x30, 0xFC, 0x20, 0x31, 0x09, 0x88, 0x1D, - 0x95, 0x29, 0x1A, 0x4D, 0xD5, 0x1D, 0x02, 0xA5, 0xF1, 0x80, 0xE0, 0x03, - 0xB4, 0x5B, 0xF4, 0xB1, 0xDD, 0xC8, 0x57, 0xEE, 0x65, 0x49, 0xC7, 0x52, - 0x54, 0xB6, 0xB4, 0x03, 0x28, 0x12, 0xFF, 0x90, 0xD6, 0xF0, 0x08, 0x8F, - 0x7E, 0xB8, 0x97, 0xC5, 0xAB, 0x37, 0x2C, 0xE4, 0x7A, 0xE4, 0xA8, 0x77, - 0xE3, 0x76, 0xA0, 0x00, 0xD0, 0x6A, 0x3F, 0xC1, 0xD2, 0x36, 0x8A, 0xE0, - 0x41, 0x12, 0xA8, 0x35, 0x6A, 0x1B, 0x6A, 0xDB, 0x35, 0xE1, 0xD4, 0x1C, - 0x04, 0xE4, 0xA8, 0x45, 0x04, 0xC8, 0x5A, 0x33, 0x38, 0x6E, 0x4D, 0x1C, - 0x0D, 0x62, 0xB7, 0x0A, 0xA2, 0x8C, 0xD3, 0xD5, 0x54, 0x3F, 0x46, 0xCD, - 0x1C, 0x55, 0xA6, 0x70, 0xDB, 0x12, 0x3A, 0x87, 0x93, 0x75, 0x9F, 0xA7, - 0xD2, 0xA0 }; - - static byte[] verisign = { - 0x30, 0x82, 0x02, 0x40, 0x30, 0x82, 0x01, 0xA9, 0x02, 0x10, 0x03, 0xC7, - 0x8F, 0x37, 0xDB, 0x92, 0x28, 0xDF, 0x3C, 0xBB, 0x1A, 0xAD, 0x82, 0xFA, - 0x67, 0x10, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0F, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, - 0x65, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, - 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, - 0x6E, 0x63, 0x2E, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0B, - 0x13, 0x2A, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, - 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x53, 0x6F, - 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, - 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, - 0x39, 0x36, 0x30, 0x34, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x5A, 0x17, 0x0D, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33, 0x35, - 0x39, 0x35, 0x39, 0x5A, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, - 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, - 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0E, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, - 0x63, 0x2E, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, - 0x2A, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x6F, - 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x53, 0x6F, 0x66, - 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x73, - 0x68, 0x65, 0x72, 0x73, 0x20, 0x43, 0x41, 0x30, 0x81, 0x9F, 0x30, 0x0D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xC3, 0xD3, 0x69, 0x65, 0x52, 0x01, 0x94, 0x54, 0xAB, 0x28, 0xC6, 0x62, - 0x18, 0xB3, 0x54, 0x55, 0xC5, 0x44, 0x87, 0x45, 0x4A, 0x3B, 0xC2, 0x7E, - 0xD8, 0xD3, 0xD7, 0xC8, 0x80, 0x86, 0x8D, 0xD8, 0x0C, 0xF1, 0x16, 0x9C, - 0xCC, 0x6B, 0xA9, 0x29, 0xB2, 0x8F, 0x76, 0x73, 0x92, 0xC8, 0xC5, 0x62, - 0xA6, 0x3C, 0xED, 0x1E, 0x05, 0x75, 0xF0, 0x13, 0x00, 0x6C, 0x14, 0x4D, - 0xD4, 0x98, 0x90, 0x07, 0xBE, 0x69, 0x73, 0x81, 0xB8, 0x62, 0x4E, 0x31, - 0x1E, 0xD1, 0xFC, 0xC9, 0x0C, 0xEB, 0x7D, 0x90, 0xBF, 0xAE, 0xB4, 0x47, - 0x51, 0xEC, 0x6F, 0xCE, 0x64, 0x35, 0x02, 0xD6, 0x7D, 0x67, 0x05, 0x77, - 0xE2, 0x8F, 0xD9, 0x51, 0xD7, 0xFB, 0x97, 0x19, 0xBC, 0x3E, 0xD7, 0x77, - 0x81, 0xC6, 0x43, 0xDD, 0xF2, 0xDD, 0xDF, 0xCA, 0xA3, 0x83, 0x8B, 0xCB, - 0x41, 0xC1, 0x3D, 0x22, 0x48, 0x48, 0xA6, 0x19, 0x02, 0x03, 0x01, 0x00, - 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x01, 0x02, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xB5, 0xBC, 0xB0, 0x75, - 0x6A, 0x89, 0xA2, 0x86, 0xBD, 0x64, 0x78, 0xC3, 0xA7, 0x32, 0x75, 0x72, - 0x11, 0xAA, 0x26, 0x02, 0x17, 0x60, 0x30, 0x4C, 0xE3, 0x48, 0x34, 0x19, - 0xB9, 0x52, 0x4A, 0x51, 0x18, 0x80, 0xFE, 0x53, 0x2D, 0x7B, 0xD5, 0x31, - 0x8C, 0xC5, 0x65, 0x99, 0x41, 0x41, 0x2F, 0xF2, 0xAE, 0x63, 0x7A, 0xE8, - 0x73, 0x99, 0x15, 0x90, 0x1A, 0x1F, 0x7A, 0x8B, 0x41, 0xD0, 0x8E, 0x3A, - 0xD0, 0xCD, 0x38, 0x34, 0x44, 0xD0, 0x75, 0xF8, 0xEA, 0x71, 0xC4, 0x81, - 0x19, 0x38, 0x17, 0x35, 0x4A, 0xAE, 0xC5, 0x3E, 0x32, 0xE6, 0x21, 0xB8, - 0x05, 0xC0, 0x93, 0xE1, 0xC7, 0x38, 0x5C, 0xD8, 0xF7, 0x93, 0x38, 0x64, - 0x90, 0xED, 0x54, 0xCE, 0xCA, 0xD3, 0xD3, 0xD0, 0x5F, 0xEF, 0x04, 0x9B, - 0xDE, 0x02, 0x82, 0xDD, 0x88, 0x29, 0xB1, 0xC3, 0x4F, 0xA5, 0xCD, 0x71, - 0x64, 0x31, 0x3C, 0x3C }; - - static byte[] verisign_ts_root = { - 0x30, 0x82, 0x02, 0xBC, 0x30, 0x82, 0x02, 0x25, 0x02, 0x10, 0x4A, 0x19, - 0xD2, 0x38, 0x8C, 0x82, 0x59, 0x1C, 0xA5, 0x5D, 0x73, 0x5F, 0x15, 0x5D, - 0xDC, 0xA3, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x81, 0x9E, 0x31, 0x1F, 0x30, 0x1D, - 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, - 0x69, 0x67, 0x6E, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, - 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, - 0x04, 0x0B, 0x13, 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, - 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, - 0x55, 0x04, 0x0B, 0x13, 0x23, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6D, 0x70, - 0x69, 0x6E, 0x67, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, - 0x52, 0x6F, 0x6F, 0x74, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, - 0x0B, 0x13, 0x2B, 0x4E, 0x4F, 0x20, 0x4C, 0x49, 0x41, 0x42, 0x49, 0x4C, - 0x49, 0x54, 0x59, 0x20, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, - 0x2C, 0x20, 0x28, 0x63, 0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x30, 0x1E, - 0x17, 0x0D, 0x39, 0x37, 0x30, 0x35, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, - 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0x9E, 0x31, 0x1F, 0x30, - 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6E, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, - 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, - 0x55, 0x04, 0x0B, 0x13, 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x2C, 0x30, 0x2A, 0x06, - 0x03, 0x55, 0x04, 0x0B, 0x13, 0x23, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, - 0x67, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6D, - 0x70, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, - 0x04, 0x0B, 0x13, 0x2B, 0x4E, 0x4F, 0x20, 0x4C, 0x49, 0x41, 0x42, 0x49, - 0x4C, 0x49, 0x54, 0x59, 0x20, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, - 0x44, 0x2C, 0x20, 0x28, 0x63, 0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, - 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x30, - 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, - 0x02, 0x81, 0x81, 0x00, 0xD3, 0x2E, 0x20, 0xF0, 0x68, 0x7C, 0x2C, 0x2D, - 0x2E, 0x81, 0x1C, 0xB1, 0x06, 0xB2, 0xA7, 0x0B, 0xB7, 0x11, 0x0D, 0x57, - 0xDA, 0x53, 0xD8, 0x75, 0xE3, 0xC9, 0x33, 0x2A, 0xB2, 0xD4, 0xF6, 0x09, - 0x5B, 0x34, 0xF3, 0xE9, 0x90, 0xFE, 0x09, 0x0C, 0xD0, 0xDB, 0x1B, 0x5A, - 0xB9, 0xCD, 0xE7, 0xF6, 0x88, 0xB1, 0x9D, 0xC0, 0x87, 0x25, 0xEB, 0x7D, - 0x58, 0x10, 0x73, 0x6A, 0x78, 0xCB, 0x71, 0x15, 0xFD, 0xC6, 0x58, 0xF6, - 0x29, 0xAB, 0x58, 0x5E, 0x96, 0x04, 0xFD, 0x2D, 0x62, 0x11, 0x58, 0x81, - 0x1C, 0xCA, 0x71, 0x94, 0xD5, 0x22, 0x58, 0x2F, 0xD5, 0xCC, 0x14, 0x05, - 0x84, 0x36, 0xBA, 0x94, 0xAA, 0xB4, 0x4D, 0x4A, 0xE9, 0xEE, 0x3B, 0x22, - 0xAD, 0x56, 0x99, 0x7E, 0x21, 0x9C, 0x6C, 0x86, 0xC0, 0x4A, 0x47, 0x97, - 0x6A, 0xB4, 0xA6, 0x36, 0xD5, 0xFC, 0x09, 0x2D, 0xD3, 0xB4, 0x39, 0x9B, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0x61, 0x55, 0x0E, 0x3E, 0x7B, 0xC7, 0x92, 0x12, 0x7E, 0x11, 0x10, 0x8E, - 0x22, 0xCC, 0xD4, 0xB3, 0x13, 0x2B, 0x5B, 0xE8, 0x44, 0xE4, 0x0B, 0x78, - 0x9E, 0xA4, 0x7E, 0xF3, 0xA7, 0x07, 0x72, 0x1E, 0xE2, 0x59, 0xEF, 0xCC, - 0x84, 0xE3, 0x89, 0x94, 0x4C, 0xDB, 0x4E, 0x61, 0xEF, 0xB3, 0xA4, 0xFB, - 0x46, 0x3D, 0x50, 0x34, 0x0B, 0x9F, 0x70, 0x56, 0xF6, 0x8E, 0x2A, 0x7F, - 0x17, 0xCE, 0xE5, 0x63, 0xBF, 0x79, 0x69, 0x07, 0x73, 0x2E, 0xB0, 0x95, - 0x28, 0x8A, 0xF5, 0xED, 0xAA, 0xA9, 0xD2, 0x5D, 0xCD, 0x0A, 0xCA, 0x10, - 0x09, 0x8F, 0xCE, 0xB3, 0xAF, 0x28, 0x96, 0xC4, 0x79, 0x29, 0x84, 0x92, - 0xDC, 0xFF, 0xBA, 0x67, 0x42, 0x48, 0xA6, 0x90, 0x10, 0xE4, 0xBF, 0x61, - 0xF8, 0x9C, 0x53, 0xE5, 0x93, 0xD1, 0x73, 0x3F, 0xF8, 0xFD, 0x9D, 0x4F, - 0x84, 0xAC, 0x55, 0xD1, 0xFD, 0x11, 0x63, 0x63 }; - - // old verisign code signing certificate (96-99) using MD2 - // still valid because of the timestamps - static byte[] oldverisign = { - 0x30, 0x82, 0x02, 0x35, 0x30, 0x82, 0x01, 0x9E, 0x02, 0x05, 0x02, 0xB4, - 0x00, 0x00, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0F, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6E, 0x74, 0x65, 0x72, - 0x6E, 0x65, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, - 0x13, 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, - 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, - 0x0B, 0x13, 0x2A, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, - 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x53, - 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, - 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43, 0x41, 0x30, 0x1E, 0x17, - 0x0D, 0x39, 0x36, 0x30, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, 0x35, 0x35, - 0x39, 0x5A, 0x17, 0x0D, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x30, 0x39, - 0x33, 0x35, 0x35, 0x38, 0x5A, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0F, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, - 0x65, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, - 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, - 0x6E, 0x63, 0x2E, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0B, - 0x13, 0x2A, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, - 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x53, 0x6F, - 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, - 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43, 0x41, 0x30, 0x81, 0x9F, 0x30, - 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, - 0x00, 0xC3, 0xD3, 0x69, 0x65, 0x52, 0x01, 0x94, 0x54, 0xAB, 0x28, 0xC6, - 0x62, 0x18, 0xB3, 0x54, 0x55, 0xC5, 0x44, 0x87, 0x45, 0x4A, 0x3B, 0xC2, - 0x7E, 0xD8, 0xD3, 0xD7, 0xC8, 0x80, 0x86, 0x8D, 0xD8, 0x0C, 0xF1, 0x16, - 0x9C, 0xCC, 0x6B, 0xA9, 0x29, 0xB2, 0x8F, 0x76, 0x73, 0x92, 0xC8, 0xC5, - 0x62, 0xA6, 0x3C, 0xED, 0x1E, 0x05, 0x75, 0xF0, 0x13, 0x00, 0x6C, 0x14, - 0x4D, 0xD4, 0x98, 0x90, 0x07, 0xBE, 0x69, 0x73, 0x81, 0xB8, 0x62, 0x4E, - 0x31, 0x1E, 0xD1, 0xFC, 0xC9, 0x0C, 0xEB, 0x7D, 0x90, 0xBF, 0xAE, 0xB4, - 0x47, 0x51, 0xEC, 0x6F, 0xCE, 0x64, 0x35, 0x02, 0xD6, 0x7D, 0x67, 0x05, - 0x77, 0xE2, 0x8F, 0xD9, 0x51, 0xD7, 0xFB, 0x97, 0x19, 0xBC, 0x3E, 0xD7, - 0x77, 0x81, 0xC6, 0x43, 0xDD, 0xF2, 0xDD, 0xDF, 0xCA, 0xA3, 0x83, 0x8B, - 0xCB, 0x41, 0xC1, 0x3D, 0x22, 0x48, 0x48, 0xA6, 0x19, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x01, 0x02, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x31, 0xBB, 0x30, - 0xC5, 0x6F, 0xA7, 0xBE, 0x23, 0x26, 0x6D, 0xA5, 0x99, 0x76, 0x68, 0xC5, - 0x2A, 0x03, 0x28, 0x4B, 0xF3, 0x89, 0xB0, 0x99, 0x03, 0x32, 0x5B, 0x94, - 0xA1, 0x7B, 0xC1, 0xC8, 0x19, 0xD7, 0xF4, 0x95, 0x6C, 0xAC, 0x73, 0x24, - 0x0A, 0xCB, 0x44, 0x05, 0x7D, 0x78, 0xEE, 0xFA, 0xF6, 0xA7, 0x9F, 0x87, - 0xA4, 0x7F, 0xE8, 0xF3, 0x4B, 0x4F, 0x32, 0x30, 0x30, 0x15, 0x08, 0x17, - 0x01, 0xB2, 0x80, 0xFC, 0xA1, 0xD9, 0x24, 0x87, 0xA5, 0x00, 0x5F, 0xCD, - 0xDD, 0x29, 0xC8, 0xA1, 0xA5, 0xCA, 0x58, 0x75, 0x39, 0x60, 0x45, 0x1F, - 0xDE, 0x8D, 0xD6, 0x57, 0x08, 0xD3, 0xC0, 0x1B, 0x81, 0xC2, 0xD9, 0xE2, - 0x00, 0x8C, 0xEC, 0x0A, 0x91, 0x02, 0xC6, 0x9D, 0x36, 0x74, 0x9A, 0x83, - 0x6B, 0xEF, 0x7C, 0x8C, 0xD2, 0xA5, 0x2A, 0x6A, 0xC9, 0x7E, 0xDB, 0xA9, - 0xBD, 0x2B, 0x22, 0xFF, 0x1C }; - - static byte[] thawte = { - 0x30, 0x82, 0x03, 0x13, 0x30, 0x82, 0x02, 0x7C, 0xA0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x81, 0xC4, 0x31, 0x0B, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5A, 0x41, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0C, 0x57, 0x65, - 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x43, 0x61, 0x70, 0x65, 0x31, 0x12, - 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x61, 0x70, - 0x65, 0x20, 0x54, 0x6F, 0x77, 0x6E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, - 0x55, 0x04, 0x0A, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, - 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x63, - 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1F, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, - 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, - 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x31, 0x26, - 0x30, 0x24, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, - 0x01, 0x16, 0x17, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2D, 0x63, 0x65, - 0x72, 0x74, 0x73, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2E, 0x63, - 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x39, 0x36, 0x30, 0x38, 0x30, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x30, 0x31, - 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, - 0xC4, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x5A, 0x41, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0C, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x43, 0x61, 0x70, - 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, - 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6F, 0x77, 0x6E, 0x31, 0x1D, 0x30, - 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77, - 0x74, 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, - 0x67, 0x20, 0x63, 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, - 0x0B, 0x13, 0x1F, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x54, 0x68, 0x61, - 0x77, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, - 0x41, 0x31, 0x26, 0x30, 0x24, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x09, 0x01, 0x16, 0x17, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2D, 0x63, 0x65, 0x72, 0x74, 0x73, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, - 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xD3, 0xA4, - 0x50, 0x6E, 0xC8, 0xFF, 0x56, 0x6B, 0xE6, 0xCF, 0x5D, 0xB6, 0xEA, 0x0C, - 0x68, 0x75, 0x47, 0xA2, 0xAA, 0xC2, 0xDA, 0x84, 0x25, 0xFC, 0xA8, 0xF4, - 0x47, 0x51, 0xDA, 0x85, 0xB5, 0x20, 0x74, 0x94, 0x86, 0x1E, 0x0F, 0x75, - 0xC9, 0xE9, 0x08, 0x61, 0xF5, 0x06, 0x6D, 0x30, 0x6E, 0x15, 0x19, 0x02, - 0xE9, 0x52, 0xC0, 0x62, 0xDB, 0x4D, 0x99, 0x9E, 0xE2, 0x6A, 0x0C, 0x44, - 0x38, 0xCD, 0xFE, 0xBE, 0xE3, 0x64, 0x09, 0x70, 0xC5, 0xFE, 0xB1, 0x6B, - 0x29, 0xB6, 0x2F, 0x49, 0xC8, 0x3B, 0xD4, 0x27, 0x04, 0x25, 0x10, 0x97, - 0x2F, 0xE7, 0x90, 0x6D, 0xC0, 0x28, 0x42, 0x99, 0xD7, 0x4C, 0x43, 0xDE, - 0xC3, 0xF5, 0x21, 0x6D, 0x54, 0x9F, 0x5D, 0xC3, 0x58, 0xE1, 0xC0, 0xE4, - 0xD9, 0x5B, 0xB0, 0xB8, 0xDC, 0xB4, 0x7B, 0xDF, 0x36, 0x3A, 0xC2, 0xB5, - 0x66, 0x22, 0x12, 0xD6, 0x87, 0x0D, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, - 0x13, 0x30, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, - 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, - 0x81, 0x81, 0x00, 0x07, 0xFA, 0x4C, 0x69, 0x5C, 0xFB, 0x95, 0xCC, 0x46, - 0xEE, 0x85, 0x83, 0x4D, 0x21, 0x30, 0x8E, 0xCA, 0xD9, 0xA8, 0x6F, 0x49, - 0x1A, 0xE6, 0xDA, 0x51, 0xE3, 0x60, 0x70, 0x6C, 0x84, 0x61, 0x11, 0xA1, - 0x1A, 0xC8, 0x48, 0x3E, 0x59, 0x43, 0x7D, 0x4F, 0x95, 0x3D, 0xA1, 0x8B, - 0xB7, 0x0B, 0x62, 0x98, 0x7A, 0x75, 0x8A, 0xDD, 0x88, 0x4E, 0x4E, 0x9E, - 0x40, 0xDB, 0xA8, 0xCC, 0x32, 0x74, 0xB9, 0x6F, 0x0D, 0xC6, 0xE3, 0xB3, - 0x44, 0x0B, 0xD9, 0x8A, 0x6F, 0x9A, 0x29, 0x9B, 0x99, 0x18, 0x28, 0x3B, - 0xD1, 0xE3, 0x40, 0x28, 0x9A, 0x5A, 0x3C, 0xD5, 0xB5, 0xE7, 0x20, 0x1B, - 0x8B, 0xCA, 0xA4, 0xAB, 0x8D, 0xE9, 0x51, 0xD9, 0xE2, 0x4C, 0x2C, 0x59, - 0xA9, 0xDA, 0xB9, 0xB2, 0x75, 0x1B, 0xF6, 0x42, 0xF2, 0xEF, 0xC7, 0xF2, - 0x18, 0xF9, 0x89, 0xBC, 0xA3, 0xFF, 0x8A, 0x23, 0x2E, 0x70, 0x47 }; - - static internal X509CertificateCollection coll; - - static TrustAnchors () - { - coll = new X509CertificateCollection (); - coll.Add (new X509Certificate (msroot)); - coll.Add (new X509Certificate (verisign)); - coll.Add (new X509Certificate (verisign_ts_root)); - coll.Add (new X509Certificate (thawte)); - } - - public X509CertificateCollection Anchors { - get { return coll; } - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X501Name.cs b/mcs/class/corlib/Mono.Security.X509/X501Name.cs deleted file mode 100644 index 8343e5fb557..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X501Name.cs +++ /dev/null @@ -1,400 +0,0 @@ -// -// X501Name.cs: X.501 Distinguished Names stuff -// -// Author: -// Sebastien Pouliot -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Text; - -using Mono.Security; -using Mono.Security.Cryptography; - -namespace Mono.Security.X509 { - - // References: - // 1. Information technology - Open Systems Interconnection - The Directory: Models - // http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.501-200102-I - // 2. RFC2253: Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names - // http://www.ietf.org/rfc/rfc2253.txt - - /* - * Name ::= CHOICE { RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - * - * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue - */ -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class X501 { - - static byte[] countryName = { 0x55, 0x04, 0x06 }; - static byte[] organizationName = { 0x55, 0x04, 0x0A }; - static byte[] organizationalUnitName = { 0x55, 0x04, 0x0B }; - static byte[] commonName = { 0x55, 0x04, 0x03 }; - static byte[] localityName = { 0x55, 0x04, 0x07 }; - static byte[] stateOrProvinceName = { 0x55, 0x04, 0x08 }; - static byte[] streetAddress = { 0x55, 0x04, 0x09 }; - //static byte[] serialNumber = { 0x55, 0x04, 0x05 }; - static byte[] domainComponent = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 }; - static byte[] userid = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 }; - static byte[] email = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 }; - static byte[] dnQualifier = { 0x55, 0x04, 0x2E }; - static byte[] title = { 0x55, 0x04, 0x0C }; - static byte[] surname = { 0x55, 0x04, 0x04 }; - static byte[] givenName = { 0x55, 0x04, 0x2A }; - static byte[] initial = { 0x55, 0x04, 0x2B }; - - private X501 () - { - } - - static public string ToString (ASN1 seq) - { - StringBuilder sb = new StringBuilder (); - for (int i = 0; i < seq.Count; i++) { - ASN1 entry = seq [i]; - AppendEntry (sb, entry, true); - - // separator (not on last iteration) - if (i < seq.Count - 1) - sb.Append (", "); - } - return sb.ToString (); - } - - static public string ToString (ASN1 seq, bool reversed, string separator, bool quotes) - { - StringBuilder sb = new StringBuilder (); - - if (reversed) { - for (int i = seq.Count - 1; i >= 0; i--) { - ASN1 entry = seq [i]; - AppendEntry (sb, entry, quotes); - - // separator (not on last iteration) - if (i > 0) - sb.Append (separator); - } - } else { - for (int i = 0; i < seq.Count; i++) { - ASN1 entry = seq [i]; - AppendEntry (sb, entry, quotes); - - // separator (not on last iteration) - if (i < seq.Count - 1) - sb.Append (separator); - } - } - return sb.ToString (); - } - - static private void AppendEntry (StringBuilder sb, ASN1 entry, bool quotes) - { - // multiple entries are valid - for (int k = 0; k < entry.Count; k++) { - ASN1 pair = entry [k]; - ASN1 s = pair [1]; - if (s == null) - continue; - - ASN1 poid = pair [0]; - if (poid == null) - continue; - - if (poid.CompareValue (countryName)) - sb.Append ("C="); - else if (poid.CompareValue (organizationName)) - sb.Append ("O="); - else if (poid.CompareValue (organizationalUnitName)) - sb.Append ("OU="); - else if (poid.CompareValue (commonName)) - sb.Append ("CN="); - else if (poid.CompareValue (localityName)) - sb.Append ("L="); - else if (poid.CompareValue (stateOrProvinceName)) - sb.Append ("S="); // NOTE: RFC2253 uses ST= - else if (poid.CompareValue (streetAddress)) - sb.Append ("STREET="); - else if (poid.CompareValue (domainComponent)) - sb.Append ("DC="); - else if (poid.CompareValue (userid)) - sb.Append ("UID="); - else if (poid.CompareValue (email)) - sb.Append ("E="); // NOTE: Not part of RFC2253 - else if (poid.CompareValue (dnQualifier)) - sb.Append ("dnQualifier="); - else if (poid.CompareValue (title)) - sb.Append ("T="); - else if (poid.CompareValue (surname)) - sb.Append ("SN="); - else if (poid.CompareValue (givenName)) - sb.Append ("G="); - else if (poid.CompareValue (initial)) - sb.Append ("I="); - else { - // unknown OID - sb.Append ("OID."); // NOTE: Not present as RFC2253 - sb.Append (ASN1Convert.ToOid (poid)); - sb.Append ("="); - } - - string sValue = null; - // 16bits or 8bits string ? TODO not complete (+special chars!) - if (s.Tag == 0x1E) { - // BMPSTRING - StringBuilder sb2 = new StringBuilder (); - for (int j = 1; j < s.Value.Length; j += 2) - sb2.Append ((char)s.Value[j]); - sValue = sb2.ToString (); - } else { - if (s.Tag == 0x14) - sValue = Encoding.UTF7.GetString (s.Value); - else - sValue = Encoding.UTF8.GetString (s.Value); - // in some cases we must quote (") the value - // Note: this doesn't seems to conform to RFC2253 - char[] specials = { ',', '+', '"', '\\', '<', '>', ';' }; - if (quotes) { - if ((sValue.IndexOfAny (specials, 0, sValue.Length) > 0) || - sValue.StartsWith (" ") || (sValue.EndsWith (" "))) - sValue = "\"" + sValue + "\""; - } - } - - sb.Append (sValue); - - // separator (not on last iteration) - if (k < entry.Count - 1) - sb.Append (", "); - } - } - - static private X520.AttributeTypeAndValue GetAttributeFromOid (string attributeType) - { - string s = attributeType.ToUpper (CultureInfo.InvariantCulture).Trim (); - switch (s) { - case "C": - return new X520.CountryName (); - case "O": - return new X520.OrganizationName (); - case "OU": - return new X520.OrganizationalUnitName (); - case "CN": - return new X520.CommonName (); - case "L": - return new X520.LocalityName (); - case "S": // Microsoft - case "ST": // RFC2253 - return new X520.StateOrProvinceName (); - case "E": // NOTE: Not part of RFC2253 - return new X520.EmailAddress (); - case "DC": // RFC2247 - return new X520.DomainComponent (); - case "UID": // RFC1274 - return new X520.UserId (); - case "DNQUALIFIER": - return new X520.DnQualifier (); - case "T": - return new X520.Title (); - case "SN": - return new X520.Surname (); - case "G": - return new X520.GivenName (); - case "I": - return new X520.Initial (); - default: - if (s.StartsWith ("OID.")) { - // MUST support it but it OID may be without it - return new X520.Oid (s.Substring (4)); - } else { - if (IsOid (s)) - return new X520.Oid (s); - else - return null; - } - } - } - - static private bool IsOid (string oid) - { - try { - ASN1 asn = ASN1Convert.FromOid (oid); - return (asn.Tag == 0x06); - } - catch { - return false; - } - } - - // no quote processing - static private X520.AttributeTypeAndValue ReadAttribute (string value, ref int pos) - { - while ((value[pos] == ' ') && (pos < value.Length)) - pos++; - - // get '=' position in substring - int equal = value.IndexOf ('=', pos); - if (equal == -1) { - string msg = Locale.GetText ("No attribute found."); - throw new FormatException (msg); - } - - string s = value.Substring (pos, equal - pos); - X520.AttributeTypeAndValue atv = GetAttributeFromOid (s); - if (atv == null) { - string msg = Locale.GetText ("Unknown attribute '{0}'."); - throw new FormatException (String.Format (msg, s)); - } - pos = equal + 1; // skip the '=' - return atv; - } - - static private bool IsHex (char c) - { - if (Char.IsDigit (c)) - return true; - char up = Char.ToUpper (c, CultureInfo.InvariantCulture); - return ((up >= 'A') && (up <= 'F')); - } - - static string ReadHex (string value, ref int pos) - { - StringBuilder sb = new StringBuilder (); - // it is (at least an) 8 bits char - sb.Append (value[pos++]); - sb.Append (value[pos]); - // look ahead for a 16 bits char - if ((pos < value.Length - 4) && (value[pos+1] == '\\') && IsHex (value[pos+2])) { - pos += 2; // pass last char and skip \ - sb.Append (value[pos++]); - sb.Append (value[pos]); - } - byte[] data = CryptoConvert.FromHex (sb.ToString ()); - return Encoding.UTF8.GetString (data); - } - - static private int ReadEscaped (StringBuilder sb, string value, int pos) - { - switch (value[pos]) { - case '\\': - case '"': - case '=': - case ';': - case '<': - case '>': - case '+': - case '#': - case ',': - sb.Append (value[pos]); - return pos; - default: - if (pos >= value.Length - 2) { - string msg = Locale.GetText ("Malformed escaped value '{0}'."); - throw new FormatException (string.Format (msg, value.Substring (pos))); - } - // it's either a 8 bits or 16 bits char - sb.Append (ReadHex (value, ref pos)); - return pos; - } - } - - static private int ReadQuoted (StringBuilder sb, string value, int pos) - { - int original = pos; - while (pos <= value.Length) { - switch (value[pos]) { - case '"': - return pos; - case '\\': - return ReadEscaped (sb, value, pos); - default: - sb.Append (value[pos]); - pos++; - break; - } - } - string msg = Locale.GetText ("Malformed quoted value '{0}'."); - throw new FormatException (string.Format (msg, value.Substring (original))); - } - - static private string ReadValue (string value, ref int pos) - { - int original = pos; - StringBuilder sb = new StringBuilder (); - while (pos < value.Length) { - switch (value [pos]) { - case '\\': - pos = ReadEscaped (sb, value, ++pos); - break; - case '"': - pos = ReadQuoted (sb, value, ++pos); - break; - case '=': - case ';': - case '<': - case '>': - string msg = Locale.GetText ("Malformed value '{0}' contains '{1}' outside quotes."); - throw new FormatException (string.Format (msg, value.Substring (original), value[pos])); - case '+': - case '#': - throw new NotImplementedException (); - case ',': - pos++; - return sb.ToString (); - default: - sb.Append (value[pos]); - break; - } - pos++; - } - return sb.ToString (); - } - - static public ASN1 FromString (string rdn) - { - if (rdn == null) - throw new ArgumentNullException ("rdn"); - - int pos = 0; - ASN1 asn1 = new ASN1 (0x30); - while (pos < rdn.Length) { - X520.AttributeTypeAndValue atv = ReadAttribute (rdn, ref pos); - atv.Value = ReadValue (rdn, ref pos); - - ASN1 sequence = new ASN1 (0x31); - sequence.Add (atv.GetASN1 ()); - asn1.Add (sequence); - } - return asn1; - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509CRL.cs b/mcs/class/corlib/Mono.Security.X509/X509CRL.cs deleted file mode 100644 index ca338453f4c..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509CRL.cs +++ /dev/null @@ -1,424 +0,0 @@ -// -// X509CRL.cs: Handles X.509 certificates revocation lists. -// -// Author: -// Sebastien Pouliot -// -// Copyright (C) 2004,2006 Novell Inc. (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.Globalization; -using System.IO; -using System.Security.Cryptography; - -using Mono.Security.X509.Extensions; - -namespace Mono.Security.X509 { - /* - * CertificateList ::= SEQUENCE { - * tbsCertList TBSCertList, - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING - * } - * - * TBSCertList ::= SEQUENCE { - * version Version OPTIONAL, - * -- if present, MUST be v2 - * signature AlgorithmIdentifier, - * issuer Name, - * thisUpdate Time, - * nextUpdate Time OPTIONAL, - * revokedCertificates SEQUENCE OF SEQUENCE { - * userCertificate CertificateSerialNumber, - * revocationDate Time, - * crlEntryExtensions Extensions OPTIONAL - * -- if present, MUST be v2 - * } OPTIONAL, - * crlExtensions [0] Extensions OPTIONAL } - * -- if present, MUST be v2 - */ -#if INSIDE_CORLIB - internal -#else - public -#endif - class X509Crl { - - public class X509CrlEntry { - - private byte[] sn; - private DateTime revocationDate; - private X509ExtensionCollection extensions; - - internal X509CrlEntry (byte[] serialNumber, DateTime revocationDate, X509ExtensionCollection extensions) - { - sn = serialNumber; - this.revocationDate = revocationDate; - if (extensions == null) - this.extensions = new X509ExtensionCollection (); - else - this.extensions = extensions; - } - - internal X509CrlEntry (ASN1 entry) - { - sn = entry [0].Value; - Array.Reverse (sn); - revocationDate = ASN1Convert.ToDateTime (entry [1]); - extensions = new X509ExtensionCollection (entry [2]); - } - - public byte[] SerialNumber { - get { return (byte[]) sn.Clone (); } - } - - public DateTime RevocationDate { - get { return revocationDate; } - } - - public X509ExtensionCollection Extensions { - get { return extensions; } - } - - public byte[] GetBytes () - { - ASN1 sequence = new ASN1 (0x30); - sequence.Add (new ASN1 (0x02, sn)); - sequence.Add (ASN1Convert.FromDateTime (revocationDate)); - if (extensions.Count > 0) - sequence.Add (new ASN1 (extensions.GetBytes ())); - return sequence.GetBytes (); - } - } - - private string issuer; - private byte version; - private DateTime thisUpdate; - private DateTime nextUpdate; - private ArrayList entries; - private string signatureOID; - private byte[] signature; - private X509ExtensionCollection extensions; - private byte[] encoded; - private byte[] hash_value; - - public X509Crl (byte[] crl) - { - if (crl == null) - throw new ArgumentNullException ("crl"); - encoded = (byte[]) crl.Clone (); - Parse (encoded); - } - - private void Parse (byte[] crl) - { - string e = "Input data cannot be coded as a valid CRL."; - try { - // CertificateList ::= SEQUENCE { - ASN1 encodedCRL = new ASN1 (encoded); - if ((encodedCRL.Tag != 0x30) || (encodedCRL.Count != 3)) - throw new CryptographicException (e); - - // CertificateList / TBSCertList, - ASN1 toBeSigned = encodedCRL [0]; - if ((toBeSigned.Tag != 0x30) || (toBeSigned.Count < 3)) - throw new CryptographicException (e); - - int n = 0; - // CertificateList / TBSCertList / Version OPTIONAL, -- if present, MUST be v2 - if (toBeSigned [n].Tag == 0x02) { - version = (byte) (toBeSigned [n++].Value [0] + 1); - } - else - version = 1; // DEFAULT - // CertificateList / TBSCertList / AlgorithmIdentifier, - signatureOID = ASN1Convert.ToOid (toBeSigned [n++][0]); - // CertificateList / TBSCertList / Name, - issuer = X501.ToString (toBeSigned [n++]); - // CertificateList / TBSCertList / Time, - thisUpdate = ASN1Convert.ToDateTime (toBeSigned [n++]); - // CertificateList / TBSCertList / Time OPTIONAL, - ASN1 next = toBeSigned [n++]; - if ((next.Tag == 0x17) || (next.Tag == 0x18)) { - nextUpdate = ASN1Convert.ToDateTime (next); - next = toBeSigned [n++]; - } - // CertificateList / TBSCertList / revokedCertificates SEQUENCE OF SEQUENCE { - entries = new ArrayList (); - // this is OPTIONAL so it may not be present if no entries exists - if ((next != null) && (next.Tag == 0x30)) { - ASN1 revokedCertificates = next; - for (int i=0; i < revokedCertificates.Count; i++) { - entries.Add (new X509CrlEntry (revokedCertificates [i])); - } - } else { - n--; - } - // CertificateList / TBSCertList / crlExtensions [0] Extensions OPTIONAL } - ASN1 extns = toBeSigned [n]; - if ((extns != null) && (extns.Tag == 0xA0) && (extns.Count == 1)) - extensions = new X509ExtensionCollection (extns [0]); - else - extensions = new X509ExtensionCollection (null); // result in a read only object - // CertificateList / AlgorithmIdentifier - string signatureAlgorithm = ASN1Convert.ToOid (encodedCRL [1][0]); - if (signatureOID != signatureAlgorithm) - throw new CryptographicException (e + " [Non-matching signature algorithms in CRL]"); - - // CertificateList / BIT STRING - byte[] bitstring = encodedCRL [2].Value; - // first byte contains unused bits in first byte - signature = new byte [bitstring.Length - 1]; - Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length); - } - catch { - throw new CryptographicException (e); - } - } - - public ArrayList Entries { - get { return ArrayList.ReadOnly (entries); } - } - - public X509CrlEntry this [int index] { - get { return (X509CrlEntry) entries [index]; } - } - - public X509CrlEntry this [byte[] serialNumber] { - get { return GetCrlEntry (serialNumber); } - } - - public X509ExtensionCollection Extensions { - get { return extensions; } - } - - public byte[] Hash { - get { - if (hash_value == null) { - ASN1 encodedCRL = new ASN1 (encoded); - byte[] toBeSigned = encodedCRL [0].GetBytes (); - HashAlgorithm ha = HashAlgorithm.Create (GetHashName ()); - hash_value = ha.ComputeHash (toBeSigned); - } - return hash_value; - } - } - - public string IssuerName { - get { return issuer; } - } - - public DateTime NextUpdate { - get { return nextUpdate; } - } - - public DateTime ThisUpdate { - get { return thisUpdate; } - } - - public string SignatureAlgorithm { - get { return signatureOID; } - } - - public byte[] Signature { - get { - if (signature == null) - return null; - return (byte[]) signature.Clone (); - } - } - - public byte[] RawData { - get { return (byte[]) encoded.Clone (); } - } - - public byte Version { - get { return version; } - } - - public bool IsCurrent { - get { return WasCurrent (DateTime.Now); } - } - - public bool WasCurrent (DateTime instant) - { - if (nextUpdate == DateTime.MinValue) - return (instant >= thisUpdate); - else - return ((instant >= thisUpdate) && (instant <= nextUpdate)); - } - - public byte[] GetBytes () - { - return (byte[]) encoded.Clone (); - } - - private bool Compare (byte[] array1, byte[] array2) - { - if ((array1 == null) && (array2 == null)) - return true; - if ((array1 == null) || (array2 == null)) - return false; - if (array1.Length != array2.Length) - return false; - for (int i=0; i < array1.Length; i++) { - if (array1 [i] != array2 [i]) - return false; - } - return true; - } - - public X509CrlEntry GetCrlEntry (X509Certificate x509) - { - if (x509 == null) - throw new ArgumentNullException ("x509"); - - return GetCrlEntry (x509.SerialNumber); - } - - public X509CrlEntry GetCrlEntry (byte[] serialNumber) - { - if (serialNumber == null) - throw new ArgumentNullException ("serialNumber"); - - for (int i=0; i < entries.Count; i++) { - X509CrlEntry entry = (X509CrlEntry) entries [i]; - if (Compare (serialNumber, entry.SerialNumber)) - return entry; - } - return null; - } - - public bool VerifySignature (X509Certificate x509) - { - if (x509 == null) - throw new ArgumentNullException ("x509"); - - // 1. x509 certificate must be a CA certificate (unknown for v1 or v2 certs) - if (x509.Version >= 3) { - // 1.1. Check for "cRLSign" bit in KeyUsage extension - X509Extension ext = x509.Extensions ["2.5.29.15"]; - if (ext != null) { - KeyUsageExtension keyUsage = new KeyUsageExtension (ext); - if (!keyUsage.Support (KeyUsages.cRLSign)) - return false; - } - // 1.2. Check for ca = true in BasicConstraint - ext = x509.Extensions ["2.5.29.19"]; - if (ext != null) { - BasicConstraintsExtension basicConstraints = new BasicConstraintsExtension (ext); - if (!basicConstraints.CertificateAuthority) - return false; - } - } - // 2. CRL issuer must match CA subject name - if (issuer != x509.SubjectName) - return false; - // 3. Check the CRL signature with the CA certificate public key - switch (signatureOID) { - case "1.2.840.10040.4.3": - return VerifySignature (x509.DSA); - default: - return VerifySignature (x509.RSA); - } - } - - private string GetHashName () - { - switch (signatureOID) { - // MD2 with RSA encryption - case "1.2.840.113549.1.1.2": - // maybe someone installed MD2 ? - return "MD2"; - // MD5 with RSA encryption - case "1.2.840.113549.1.1.4": - return "MD5"; - // SHA-1 with DSA - case "1.2.840.10040.4.3": - // SHA-1 with RSA Encryption - case "1.2.840.113549.1.1.5": - return "SHA1"; - default: - throw new CryptographicException ("Unsupported hash algorithm: " + signatureOID); - } - } - - internal bool VerifySignature (DSA dsa) - { - if (signatureOID != "1.2.840.10040.4.3") - throw new CryptographicException ("Unsupported hash algorithm: " + signatureOID); - DSASignatureDeformatter v = new DSASignatureDeformatter (dsa); - // only SHA-1 is supported - v.SetHashAlgorithm ("SHA1"); - ASN1 sign = new ASN1 (signature); - if ((sign == null) || (sign.Count != 2)) - return false; - // parts may be less than 20 bytes (i.e. first bytes were 0x00) - byte[] part1 = sign [0].Value; - byte[] part2 = sign [1].Value; - byte[] sig = new byte [40]; - // parts may be less than 20 bytes (i.e. first bytes were 0x00) - // parts may be more than 20 bytes (i.e. first byte > 0x80, negative) - int s1 = System.Math.Max (0, part1.Length - 20); - int e1 = System.Math.Max (0, 20 - part1.Length); - Buffer.BlockCopy (part1, s1, sig, e1, part1.Length - s1); - int s2 = System.Math.Max (0, part2.Length - 20); - int e2 = System.Math.Max (20, 40 - part2.Length); - Buffer.BlockCopy (part2, s2, sig, e2, part2.Length - s2); - return v.VerifySignature (Hash, sig); - } - - internal bool VerifySignature (RSA rsa) - { - RSAPKCS1SignatureDeformatter v = new RSAPKCS1SignatureDeformatter (rsa); - v.SetHashAlgorithm (GetHashName ()); - return v.VerifySignature (Hash, signature); - } - - public bool VerifySignature (AsymmetricAlgorithm aa) - { - if (aa == null) - throw new ArgumentNullException ("aa"); - - // only validate the signature (in case we don't have the CA certificate) - if (aa is RSA) - return VerifySignature (aa as RSA); - else if (aa is DSA) - return VerifySignature (aa as DSA); - else - throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ()); - } - - static public X509Crl CreateFromFile (string filename) - { - byte[] crl = null; - using (FileStream fs = File.Open (filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { - crl = new byte [fs.Length]; - fs.Read (crl, 0, crl.Length); - fs.Close (); - } - return new X509Crl (crl); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs b/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs deleted file mode 100644 index 5131e99d525..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs +++ /dev/null @@ -1,583 +0,0 @@ -// -// X509Certificates.cs: Handles X.509 certificates. -// -// Author: -// Sebastien Pouliot -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Runtime.Serialization; -using System.Security.Cryptography; -using SSCX = System.Security.Cryptography.X509Certificates; -using System.Security.Permissions; -using System.Text; - -using Mono.Security.Cryptography; - -namespace Mono.Security.X509 { - - // References: - // a. Internet X.509 Public Key Infrastructure Certificate and CRL Profile - // http://www.ietf.org/rfc/rfc3280.txt - // b. ITU ASN.1 standards (free download) - // http://www.itu.int/ITU-T/studygroups/com17/languages/ - -#if INSIDE_CORLIB - internal class X509Certificate : ISerializable { -#else - public class X509Certificate : ISerializable { -#endif - const string encoding_error = "Input data cannot be coded as a valid certificate."; - - private ASN1 decoder; - - private byte[] m_encodedcert; - private DateTime m_from; - private DateTime m_until; - private ASN1 issuer; - private string m_issuername; - private string m_keyalgo; - private byte[] m_keyalgoparams; - private ASN1 subject; - private string m_subject; - private byte[] m_publickey; - private byte[] signature; - private string m_signaturealgo; - private byte[] m_signaturealgoparams; - private byte[] certhash; - private RSA _rsa; - private DSA _dsa; - - // from http://www.ietf.org/rfc/rfc2459.txt - // - //Certificate ::= SEQUENCE { - // tbsCertificate TBSCertificate, - // signatureAlgorithm AlgorithmIdentifier, - // signature BIT STRING } - // - //TBSCertificate ::= SEQUENCE { - // version [0] Version DEFAULT v1, - // serialNumber CertificateSerialNumber, - // signature AlgorithmIdentifier, - // issuer Name, - // validity Validity, - // subject Name, - // subjectPublicKeyInfo SubjectPublicKeyInfo, - // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - // -- If present, version shall be v2 or v3 - // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - // -- If present, version shall be v2 or v3 - // extensions [3] Extensions OPTIONAL - // -- If present, version shall be v3 -- } - private int version; - private byte[] serialnumber; - - private byte[] issuerUniqueID; - private byte[] subjectUniqueID; - private X509ExtensionCollection extensions; - - // that's were the real job is! - private void Parse (byte[] data) - { - try { - decoder = new ASN1 (data); - // Certificate - if (decoder.Tag != 0x30) - throw new CryptographicException (encoding_error); - // Certificate / TBSCertificate - if (decoder [0].Tag != 0x30) - throw new CryptographicException (encoding_error); - - ASN1 tbsCertificate = decoder [0]; - - int tbs = 0; - // Certificate / TBSCertificate / Version - ASN1 v = decoder [0][tbs]; - version = 1; // DEFAULT v1 - if ((v.Tag == 0xA0) && (v.Count > 0)) { - // version (optional) is present only in v2+ certs - version += v [0].Value [0]; // zero based - tbs++; - } - - // Certificate / TBSCertificate / CertificateSerialNumber - ASN1 sn = decoder [0][tbs++]; - if (sn.Tag != 0x02) - throw new CryptographicException (encoding_error); - serialnumber = sn.Value; - Array.Reverse (serialnumber, 0, serialnumber.Length); - - // Certificate / TBSCertificate / AlgorithmIdentifier - tbs++; - // ASN1 signatureAlgo = tbsCertificate.Element (tbs++, 0x30); - - issuer = tbsCertificate.Element (tbs++, 0x30); - m_issuername = X501.ToString (issuer); - - ASN1 validity = tbsCertificate.Element (tbs++, 0x30); - ASN1 notBefore = validity [0]; - m_from = ASN1Convert.ToDateTime (notBefore); - ASN1 notAfter = validity [1]; - m_until = ASN1Convert.ToDateTime (notAfter); - - subject = tbsCertificate.Element (tbs++, 0x30); - m_subject = X501.ToString (subject); - - ASN1 subjectPublicKeyInfo = tbsCertificate.Element (tbs++, 0x30); - - ASN1 algorithm = subjectPublicKeyInfo.Element (0, 0x30); - ASN1 algo = algorithm.Element (0, 0x06); - m_keyalgo = ASN1Convert.ToOid (algo); - // parameters ANY DEFINED BY algorithm OPTIONAL - // so we dont ask for a specific (Element) type and return DER - ASN1 parameters = algorithm [1]; - m_keyalgoparams = ((algorithm.Count > 1) ? parameters.GetBytes () : null); - - ASN1 subjectPublicKey = subjectPublicKeyInfo.Element (1, 0x03); - // we must drop th first byte (which is the number of unused bits - // in the BITSTRING) - int n = subjectPublicKey.Length - 1; - m_publickey = new byte [n]; - Buffer.BlockCopy (subjectPublicKey.Value, 1, m_publickey, 0, n); - - // signature processing - byte[] bitstring = decoder [2].Value; - // first byte contains unused bits in first byte - signature = new byte [bitstring.Length - 1]; - Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length); - - algorithm = decoder [1]; - algo = algorithm.Element (0, 0x06); - m_signaturealgo = ASN1Convert.ToOid (algo); - parameters = algorithm [1]; - if (parameters != null) - m_signaturealgoparams = parameters.GetBytes (); - else - m_signaturealgoparams = null; - - // Certificate / TBSCertificate / issuerUniqueID - ASN1 issuerUID = tbsCertificate.Element (tbs, 0x81); - if (issuerUID != null) { - tbs++; - issuerUniqueID = issuerUID.Value; - } - - // Certificate / TBSCertificate / subjectUniqueID - ASN1 subjectUID = tbsCertificate.Element (tbs, 0x82); - if (subjectUID != null) { - tbs++; - subjectUniqueID = subjectUID.Value; - } - - // Certificate / TBSCertificate / Extensions - ASN1 extns = tbsCertificate.Element (tbs, 0xA3); - if ((extns != null) && (extns.Count == 1)) - extensions = new X509ExtensionCollection (extns [0]); - else - extensions = new X509ExtensionCollection (null); - - // keep a copy of the original data - m_encodedcert = (byte[]) data.Clone (); - } - catch (Exception ex) { - throw new CryptographicException (encoding_error, ex); - } - } - - // constructors - - public X509Certificate (byte[] data) - { - if (data != null) { - // does it looks like PEM ? - if ((data.Length > 0) && (data [0] != 0x30)) { - try { - data = PEM ("CERTIFICATE", data); - } - catch (Exception ex) { - throw new CryptographicException (encoding_error, ex); - } - } - Parse (data); - } - } - - private byte[] GetUnsignedBigInteger (byte[] integer) - { - if (integer [0] == 0x00) { - // this first byte is added so we're sure it's an unsigned integer - // however we can't feed it into RSAParameters or DSAParameters - int length = integer.Length - 1; - byte[] uinteger = new byte [length]; - Buffer.BlockCopy (integer, 1, uinteger, 0, length); - return uinteger; - } - else - return integer; - } - - // public methods - - public DSA DSA { - get { - if (m_keyalgoparams == null) - throw new CryptographicException ("Missing key algorithm parameters."); - - if (_dsa == null) { - DSAParameters dsaParams = new DSAParameters (); - // for DSA m_publickey contains 1 ASN.1 integer - Y - ASN1 pubkey = new ASN1 (m_publickey); - if ((pubkey == null) || (pubkey.Tag != 0x02)) - return null; - dsaParams.Y = GetUnsignedBigInteger (pubkey.Value); - - ASN1 param = new ASN1 (m_keyalgoparams); - if ((param == null) || (param.Tag != 0x30) || (param.Count < 3)) - return null; - if ((param [0].Tag != 0x02) || (param [1].Tag != 0x02) || (param [2].Tag != 0x02)) - return null; - dsaParams.P = GetUnsignedBigInteger (param [0].Value); - dsaParams.Q = GetUnsignedBigInteger (param [1].Value); - dsaParams.G = GetUnsignedBigInteger (param [2].Value); - - // BUG: MS BCL 1.0 can't import a key which - // isn't the same size as the one present in - // the container. - _dsa = (DSA) new DSACryptoServiceProvider (dsaParams.Y.Length << 3); - _dsa.ImportParameters (dsaParams); - } - return _dsa; - } - - set { - _dsa = value; - if (value != null) - _rsa = null; - } - } - - public X509ExtensionCollection Extensions { - get { return extensions; } - } - - public byte[] Hash { - get { - if (certhash == null) { - HashAlgorithm hash = null; - switch (m_signaturealgo) { - case "1.2.840.113549.1.1.2": // MD2 with RSA encryption - // maybe someone installed MD2 ? -#if INSIDE_CORLIB - hash = HashAlgorithm.Create ("MD2"); -#else - hash = Mono.Security.Cryptography.MD2.Create (); -#endif - break; - case "1.2.840.113549.1.1.4": // MD5 with RSA encryption - hash = MD5.Create (); - break; - case "1.2.840.113549.1.1.5": // SHA-1 with RSA Encryption - case "1.3.14.3.2.29": // SHA1 with RSA signature - case "1.2.840.10040.4.3": // SHA1-1 with DSA - hash = SHA1.Create (); - break; - default: - return null; - } - if ((decoder == null) || (decoder.Count < 1)) - return null; - byte[] toBeSigned = decoder [0].GetBytes (); - certhash = hash.ComputeHash (toBeSigned, 0, toBeSigned.Length); - } - return (byte[]) certhash.Clone (); - } - } - - public virtual string IssuerName { - get { return m_issuername; } - } - - public virtual string KeyAlgorithm { - get { return m_keyalgo; } - } - - public virtual byte[] KeyAlgorithmParameters { - get { - if (m_keyalgoparams == null) - return null; - return (byte[]) m_keyalgoparams.Clone (); - } - set { m_keyalgoparams = value; } - } - - public virtual byte[] PublicKey { - get { - if (m_publickey == null) - return null; - return (byte[]) m_publickey.Clone (); - } - } - - public virtual RSA RSA { - get { - if (_rsa == null) { - RSAParameters rsaParams = new RSAParameters (); - // for RSA m_publickey contains 2 ASN.1 integers - // the modulus and the public exponent - ASN1 pubkey = new ASN1 (m_publickey); - ASN1 modulus = pubkey [0]; - if ((modulus == null) || (modulus.Tag != 0x02)) - return null; - ASN1 exponent = pubkey [1]; - if (exponent.Tag != 0x02) - return null; - - rsaParams.Modulus = GetUnsignedBigInteger (modulus.Value); - rsaParams.Exponent = exponent.Value; - - // BUG: MS BCL 1.0 can't import a key which - // isn't the same size as the one present in - // the container. - int keySize = (rsaParams.Modulus.Length << 3); - _rsa = (RSA) new RSACryptoServiceProvider (keySize); - _rsa.ImportParameters (rsaParams); - } - return _rsa; - } - - set { - if (value != null) - _dsa = null; - _rsa = value; - } - } - - public virtual byte[] RawData { - get { - if (m_encodedcert == null) - return null; - return (byte[]) m_encodedcert.Clone (); - } - } - - public virtual byte[] SerialNumber { - get { - if (serialnumber == null) - return null; - return (byte[]) serialnumber.Clone (); - } - } - - public virtual byte[] Signature { - get { - if (signature == null) - return null; - - switch (m_signaturealgo) { - case "1.2.840.113549.1.1.2": // MD2 with RSA encryption - case "1.2.840.113549.1.1.4": // MD5 with RSA encryption - case "1.2.840.113549.1.1.5": // SHA-1 with RSA Encryption - case "1.3.14.3.2.29": // SHA1 with RSA signature - return (byte[]) signature.Clone (); - - case "1.2.840.10040.4.3": // SHA-1 with DSA - ASN1 sign = new ASN1 (signature); - if ((sign == null) || (sign.Count != 2)) - return null; - byte[] part1 = sign [0].Value; - byte[] part2 = sign [1].Value; - byte[] sig = new byte [40]; - // parts may be less than 20 bytes (i.e. first bytes were 0x00) - // parts may be more than 20 bytes (i.e. first byte > 0x80, negative) - int s1 = System.Math.Max (0, part1.Length - 20); - int e1 = System.Math.Max (0, 20 - part1.Length); - Buffer.BlockCopy (part1, s1, sig, e1, part1.Length - s1); - int s2 = System.Math.Max (0, part2.Length - 20); - int e2 = System.Math.Max (20, 40 - part2.Length); - Buffer.BlockCopy (part2, s2, sig, e2, part2.Length - s2); - return sig; - - default: - throw new CryptographicException ("Unsupported hash algorithm: " + m_signaturealgo); - } - } - } - - public virtual string SignatureAlgorithm { - get { return m_signaturealgo; } - } - - public virtual byte[] SignatureAlgorithmParameters { - get { - if (m_signaturealgoparams == null) - return m_signaturealgoparams; - return (byte[]) m_signaturealgoparams.Clone (); - } - } - - public virtual string SubjectName { - get { return m_subject; } - } - - public virtual DateTime ValidFrom { - get { return m_from; } - } - - public virtual DateTime ValidUntil { - get { return m_until; } - } - - public int Version { - get { return version; } - } - - public bool IsCurrent { - get { return WasCurrent (DateTime.UtcNow); } - } - - public bool WasCurrent (DateTime instant) - { - return ((instant > ValidFrom) && (instant <= ValidUntil)); - } - - // uncommon v2 "extension" - public byte[] IssuerUniqueIdentifier { - get { - if (issuerUniqueID == null) - return null; - return (byte[]) issuerUniqueID.Clone (); - } - } - - // uncommon v2 "extension" - public byte[] SubjectUniqueIdentifier { - get { - if (subjectUniqueID == null) - return null; - return (byte[]) subjectUniqueID.Clone (); - } - } - - internal bool VerifySignature (DSA dsa) - { - // signatureOID is check by both this.Hash and this.Signature - DSASignatureDeformatter v = new DSASignatureDeformatter (dsa); - // only SHA-1 is supported - v.SetHashAlgorithm ("SHA1"); - return v.VerifySignature (this.Hash, this.Signature); - } - - internal string GetHashNameFromOID (string oid) - { - switch (oid) { - // MD2 with RSA encryption - case "1.2.840.113549.1.1.2": - // maybe someone installed MD2 ? - return "MD2"; - // MD5 with RSA encryption - case "1.2.840.113549.1.1.4": - return "MD5"; - // SHA-1 with RSA Encryption - case "1.2.840.113549.1.1.5": - case "1.3.14.3.2.29": - return "SHA1"; - default: - return null; - } - } - - internal bool VerifySignature (RSA rsa) - { - RSAPKCS1SignatureDeformatter v = new RSAPKCS1SignatureDeformatter (rsa); - string hashName = GetHashNameFromOID (m_signaturealgo); - if (hashName == null) - throw new CryptographicException ("Unsupported hash algorithm: " + m_signaturealgo); - - v.SetHashAlgorithm (hashName); - return v.VerifySignature (this.Hash, this.Signature); - } - - public bool VerifySignature (AsymmetricAlgorithm aa) - { - if (aa == null) - throw new ArgumentNullException ("aa"); - - if (aa is RSA) - return VerifySignature (aa as RSA); - else if (aa is DSA) - return VerifySignature (aa as DSA); - else - throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ()); - } - - public bool CheckSignature (byte[] hash, string hashAlgorithm, byte[] signature) - { - RSACryptoServiceProvider r = (RSACryptoServiceProvider) RSA; - return r.VerifyHash (hash, hashAlgorithm, signature); - } - - public bool IsSelfSigned { - get { - if (m_issuername == m_subject) - return VerifySignature (RSA); - else - return false; - } - } - - public ASN1 GetIssuerName () - { - return issuer; - } - - public ASN1 GetSubjectName () - { - return subject; - } - - protected X509Certificate (SerializationInfo info, StreamingContext context) - { - Parse ((byte[]) info.GetValue ("raw", typeof (byte[]))); - } - - [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)] - public virtual void GetObjectData (SerializationInfo info, StreamingContext context) - { - info.AddValue ("raw", m_encodedcert); - // note: we NEVER serialize the private key - } - - static byte[] PEM (string type, byte[] data) - { - string pem = Encoding.ASCII.GetString (data); - string header = String.Format ("-----BEGIN {0}-----", type); - string footer = String.Format ("-----END {0}-----", type); - int start = pem.IndexOf (header) + header.Length; - int end = pem.IndexOf (footer, start); - string base64 = pem.Substring (start, (end - start)); - return Convert.FromBase64String (base64); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509CertificateCollection.cs b/mcs/class/corlib/Mono.Security.X509/X509CertificateCollection.cs deleted file mode 100644 index 1b7b8405dcc..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509CertificateCollection.cs +++ /dev/null @@ -1,207 +0,0 @@ -// -// Based on System.Security.Cryptography.X509Certificates.X509CertificateCollection -// in System assembly -// -// Authors: -// Lawrence Pit (loz@cable.a2000.nl) -// Sebastien Pouliot -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; - -namespace Mono.Security.X509 { - - [Serializable] -#if INSIDE_CORLIB - internal -#else - public -#endif - class X509CertificateCollection : CollectionBase, IEnumerable { - - public X509CertificateCollection () - { - } - - public X509CertificateCollection (X509Certificate [] value) - { - AddRange (value); - } - - public X509CertificateCollection (X509CertificateCollection value) - { - AddRange (value); - } - - // Properties - - public X509Certificate this [int index] { - get { return (X509Certificate) InnerList [index]; } - set { InnerList [index] = value; } - } - - // Methods - - public int Add (X509Certificate value) - { - if (value == null) - throw new ArgumentNullException ("value"); - - return InnerList.Add (value); - } - - public void AddRange (X509Certificate [] value) - { - if (value == null) - throw new ArgumentNullException ("value"); - - for (int i = 0; i < value.Length; i++) - InnerList.Add (value [i]); - } - - public void AddRange (X509CertificateCollection value) - { - if (value == null) - throw new ArgumentNullException ("value"); - - for (int i = 0; i < value.InnerList.Count; i++) - InnerList.Add (value [i]); - } - - public bool Contains (X509Certificate value) - { - return (IndexOf (value) != -1); - } - - public void CopyTo (X509Certificate[] array, int index) - { - InnerList.CopyTo (array, index); - } - - public new X509CertificateEnumerator GetEnumerator () - { - return new X509CertificateEnumerator (this); - } - - IEnumerator IEnumerable.GetEnumerator () - { - return InnerList.GetEnumerator (); - } - - public override int GetHashCode () - { - return InnerList.GetHashCode (); - } - - public int IndexOf (X509Certificate value) - { - if (value == null) - throw new ArgumentNullException ("value"); - - byte[] hash = value.Hash; - for (int i=0; i < InnerList.Count; i++) { - X509Certificate x509 = (X509Certificate) InnerList [i]; - if (Compare (x509.Hash, hash)) - return i; - } - return -1; - } - - public void Insert (int index, X509Certificate value) - { - InnerList.Insert (index, value); - } - - public void Remove (X509Certificate value) - { - InnerList.Remove (value); - } - - // private stuff - - private bool Compare (byte[] array1, byte[] array2) - { - if ((array1 == null) && (array2 == null)) - return true; - if ((array1 == null) || (array2 == null)) - return false; - if (array1.Length != array2.Length) - return false; - for (int i=0; i < array1.Length; i++) { - if (array1 [i] != array2 [i]) - return false; - } - return true; - } - - // Inner Class - - public class X509CertificateEnumerator : IEnumerator { - - private IEnumerator enumerator; - - // Constructors - - public X509CertificateEnumerator (X509CertificateCollection mappings) - { - enumerator = ((IEnumerable) mappings).GetEnumerator (); - } - - // Properties - - public X509Certificate Current { - get { return (X509Certificate) enumerator.Current; } - } - - object IEnumerator.Current { - get { return enumerator.Current; } - } - - // Methods - - bool IEnumerator.MoveNext () - { - return enumerator.MoveNext (); - } - - void IEnumerator.Reset () - { - enumerator.Reset (); - } - - public bool MoveNext () - { - return enumerator.MoveNext (); - } - - public void Reset () - { - enumerator.Reset (); - } - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509Chain.cs b/mcs/class/corlib/Mono.Security.X509/X509Chain.cs deleted file mode 100644 index 6edd5feac45..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509Chain.cs +++ /dev/null @@ -1,285 +0,0 @@ -// -// X509Chain.cs: X.509 Certificate Path -// This is a VERY simplified and minimal version -// used for -// Authenticode support -// TLS/SSL support -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Security; -using System.Security.Permissions; - -#if !INSIDE_CORLIB -using System.Net; -#endif - -using Mono.Security.X509.Extensions; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class X509Chain { - - private X509CertificateCollection roots; - private X509CertificateCollection certs; - private X509Certificate _root; - - private X509CertificateCollection _chain; - private X509ChainStatusFlags _status; - - // constructors - - public X509Chain () - { - certs = new X509CertificateCollection (); - } - - // get a pre-builded chain - public X509Chain (X509CertificateCollection chain) : this () - { - _chain = new X509CertificateCollection (); - _chain.AddRange (chain); - } - - // properties - - public X509CertificateCollection Chain { - get { return _chain; } - } - - // the root of the specified certificate (may not be trusted!) - public X509Certificate Root { - get { return _root; } - } - - public X509ChainStatusFlags Status { - get { return _status; } - } - - public X509CertificateCollection TrustAnchors { - get { - if (roots == null) { - roots = new X509CertificateCollection (); - roots.AddRange (X509StoreManager.TrustedRootCertificates); - return roots; - } - return roots; - } - [SecurityPermission (SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPolicy)] - set { roots = value; } - } - - // methods - - public void LoadCertificate (X509Certificate x509) - { - certs.Add (x509); - } - - public void LoadCertificates (X509CertificateCollection collection) - { - certs.AddRange (collection); - } - - public X509Certificate FindByIssuerName (string issuerName) - { - foreach (X509Certificate x in certs) { - if (x.IssuerName == issuerName) - return x; - } - return null; - } - - public bool Build (X509Certificate leaf) - { - _status = X509ChainStatusFlags.NoError; - if (_chain == null) { - // chain not supplied - we must build it ourselve - _chain = new X509CertificateCollection (); - X509Certificate x = leaf; - X509Certificate tmp = x; - while ((x != null) && (!x.IsSelfSigned)) { - tmp = x; // last valid - _chain.Add (x); - x = FindCertificateParent (x); - } - // find a trusted root - _root = FindCertificateRoot (tmp); - } - else { - // chain supplied - still have to check signatures! - int last = _chain.Count; - if (last > 0) { - if (IsParent (leaf, _chain [0])) { - int i = 1; - for (; i < last; i++) { - if (!IsParent (_chain [i-1], _chain [i])) - break; - } - if (i == last) - _root = FindCertificateRoot (_chain [last - 1]); - } - } - else { - // is the leaf a root ? (trusted or untrusted) - _root = FindCertificateRoot (leaf); - } - } - - // validate the chain - if ((_chain != null) && (_status == X509ChainStatusFlags.NoError)) { - foreach (X509Certificate x in _chain) { - // validate dates for each certificate in the chain - // note: we DO NOT check for nested date/time - if (!IsValid (x)) { - return false; - } - } - // check leaf - if (!IsValid (leaf)) { - // switch status code if the failure is expiration - if (_status == X509ChainStatusFlags.NotTimeNested) - _status = X509ChainStatusFlags.NotTimeValid; - return false; - } - // check root - if ((_root != null) && !IsValid (_root)) { - return false; - } - } - return (_status == X509ChainStatusFlags.NoError); - } - - // - - public void Reset () - { - _status = X509ChainStatusFlags.NoError; - roots = null; // this force a reload - certs.Clear (); - if (_chain != null) - _chain.Clear (); - } - - // private stuff - - private bool IsValid (X509Certificate cert) - { - if (!cert.IsCurrent) { - // FIXME: nesting isn't very well implemented - _status = X509ChainStatusFlags.NotTimeNested; - return false; - } - - // TODO - we should check for CRITICAL but unknown extensions - // X509ChainStatusFlags.InvalidExtension -#if !INSIDE_CORLIB - if (ServicePointManager.CheckCertificateRevocationList) { - // TODO - check revocation (CRL, OCSP ...) - // X509ChainStatusFlags.RevocationStatusUnknown - // X509ChainStatusFlags.Revoked - } -#endif - return true; - } - - private X509Certificate FindCertificateParent (X509Certificate child) - { - foreach (X509Certificate potentialParent in certs) { - if (IsParent (child, potentialParent)) - return potentialParent; - } - return null; - } - - private X509Certificate FindCertificateRoot (X509Certificate potentialRoot) - { - if (potentialRoot == null) { - _status = X509ChainStatusFlags.PartialChain; - return null; - } - - // if the trusted root is in the chain - if (IsTrusted (potentialRoot)) { - return potentialRoot; - } - - // if the root isn't in the chain - foreach (X509Certificate root in TrustAnchors) { - if (IsParent (potentialRoot, root)) { - return root; - } - } - - // is it a (untrusted) root ? - if (potentialRoot.IsSelfSigned) { - _status = X509ChainStatusFlags.UntrustedRoot; - return potentialRoot; - } - - _status = X509ChainStatusFlags.PartialChain; - return null; - } - - private bool IsTrusted (X509Certificate potentialTrusted) - { - return TrustAnchors.Contains (potentialTrusted); - } - - private bool IsParent (X509Certificate child, X509Certificate parent) - { - if (child.IssuerName != parent.SubjectName) - return false; - - // parent MUST have the Basic Constraint CA=true (except for trusted roots) - // see why at http://www.microsoft.com/technet/security/bulletin/MS02-050.asp - if ((parent.Version > 2) && (!IsTrusted (parent))) { - // TODO: we do not support pathLenConstraint - X509Extension ext = parent.Extensions ["2.5.29.19"]; - if (ext != null) { - BasicConstraintsExtension bc = new BasicConstraintsExtension (ext); - if (!bc.CertificateAuthority) - _status = X509ChainStatusFlags.InvalidBasicConstraints; - } - else - _status = X509ChainStatusFlags.InvalidBasicConstraints; - } - - if (!child.VerifySignature (parent.RSA)) { - _status = X509ChainStatusFlags.NotSignatureValid; - return false; - } - return true; - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509ChainStatusFlags.cs b/mcs/class/corlib/Mono.Security.X509/X509ChainStatusFlags.cs deleted file mode 100644 index f72660c8b01..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509ChainStatusFlags.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// X509ChainStatusFlags.cs: X.509 Chain Status -// -// Author: -// Sebastien Pouliot -// -// (C) 2004 Novell (http://www.novell.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Security.X509 { - - // definitions from Fx 1.2 - // commented flags aren't implemented in X509Chain - - [Serializable] - [Flags] -#if INSIDE_CORLIB - internal -#else - public -#endif - enum X509ChainStatusFlags { -// CtlNotSignatureValid = 262144, -// CtlNotTimeValid = 131072, -// CtlNotValidForUsage = 524288, -// Cyclic = 128, -// HasExcludedNameConstraint = 32768, -// HasNotDefinedNameConstraint = 8192, -// HasNotPermittedNameConstraint = 16384, -// HasNotSupportedNameConstraint = 4096, - InvalidBasicConstraints = 1024, -// InvalidExtension = 256, -// InvalidNameConstraints = 2048, -// InvalidPolicyConstraints = 512, - NoError = 0, -// NoIssuanceChainPolicy = 33554432, - NotSignatureValid = 8, - NotTimeNested = 2, - NotTimeValid = 1, -// NotValidForUsage = 16, -// OfflineRevocation = 16777216, - PartialChain = 65536, -// RevocationStatusUnknown = 64, -// Revoked = 4, - UntrustedRoot = 32 - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509Extension.cs b/mcs/class/corlib/Mono.Security.X509/X509Extension.cs deleted file mode 100644 index 637e74b48cd..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509Extension.cs +++ /dev/null @@ -1,214 +0,0 @@ -// -// X509Extension.cs: Base class for all X.509 extensions. -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Text; - -using Mono.Security; - -namespace Mono.Security.X509 { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING - * } - */ -#if INSIDE_CORLIB - internal -#else - public -#endif - class X509Extension { - - protected string extnOid; - protected bool extnCritical; - protected ASN1 extnValue; - - protected X509Extension () - { - extnCritical = false; - } - - public X509Extension (ASN1 asn1) - { - if ((asn1.Tag != 0x30) || (asn1.Count < 2)) - throw new ArgumentException (Locale.GetText ("Invalid X.509 extension.")); - if (asn1[0].Tag != 0x06) - throw new ArgumentException (Locale.GetText ("Invalid X.509 extension.")); - - extnOid = ASN1Convert.ToOid (asn1[0]); - extnCritical = ((asn1[1].Tag == 0x01) && (asn1[1].Value[0] == 0xFF)); - // last element is an octet string which may need to be decoded - extnValue = asn1 [asn1.Count - 1]; - if ((extnValue.Tag == 0x04) && (extnValue.Length > 0) && (extnValue.Count == 0)) { - try { - ASN1 encapsulated = new ASN1 (extnValue.Value); - extnValue.Value = null; - extnValue.Add (encapsulated); - } - catch { - // data isn't ASN.1 - } - } - Decode (); - } - - public X509Extension (X509Extension extension) - { - if (extension == null) - throw new ArgumentNullException ("extension"); - if ((extension.Value == null) || (extension.Value.Tag != 0x04) || (extension.Value.Count != 1)) - throw new ArgumentException (Locale.GetText ("Invalid X.509 extension.")); - - extnOid = extension.Oid; - extnCritical = extension.Critical; - extnValue = extension.Value; - Decode (); - } - - // encode the extension *into* an OCTET STRING - protected virtual void Decode () - { - } - - // decode the extension from *inside* an OCTET STRING - protected virtual void Encode () - { - } - - public ASN1 ASN1 { - get { - ASN1 extension = new ASN1 (0x30); - extension.Add (ASN1Convert.FromOid (extnOid)); - if (extnCritical) - extension.Add (new ASN1 (0x01, new byte [1] { 0xFF })); - Encode (); - extension.Add (extnValue); - return extension; - } - } - - public string Oid { - get { return extnOid; } - } - - public bool Critical { - get { return extnCritical; } - set { extnCritical = value; } - } - - // this gets overrided with more meaningful names - public virtual string Name { - get { return extnOid; } - } - - public ASN1 Value { - get { - if (extnValue == null) { - Encode (); - } - return extnValue; - } - } - - public override bool Equals (object obj) - { - if (obj == null) - return false; - - X509Extension ex = (obj as X509Extension); - if (ex == null) - return false; - - if (extnCritical != ex.extnCritical) - return false; - if (extnOid != ex.extnOid) - return false; - if (extnValue.Length != ex.extnValue.Length) - return false; - - for (int i=0; i < extnValue.Length; i++) { - if (extnValue [i] != ex.extnValue [i]) - return false; - } - return true; - } - - public byte[] GetBytes () - { - return ASN1.GetBytes (); - } - - public override int GetHashCode () - { - // OID should be unique in a collection of extensions - return extnOid.GetHashCode (); - } - - private void WriteLine (StringBuilder sb, int n, int pos) - { - byte[] value = extnValue.Value; - int p = pos; - for (int j=0; j < 8; j++) { - if (j < n) { - sb.Append (value [p++].ToString ("X2", CultureInfo.InvariantCulture)); - sb.Append (" "); - } - else - sb.Append (" "); - } - sb.Append (" "); - p = pos; - for (int j=0; j < n; j++) { - byte b = value [p++]; - if (b < 0x20) - sb.Append ("."); - else - sb.Append (Convert.ToChar (b)); - } - sb.Append (Environment.NewLine); - } - - public override string ToString () - { - StringBuilder sb = new StringBuilder (); - int div = (extnValue.Length >> 3); - int rem = (extnValue.Length - (div << 3)); - int x = 0; - for (int i=0; i < div; i++) { - WriteLine (sb, 8, x); - x += 8; - } - WriteLine (sb, rem, x); - return sb.ToString (); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509Extensions.cs b/mcs/class/corlib/Mono.Security.X509/X509Extensions.cs deleted file mode 100644 index da2de3c0d09..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509Extensions.cs +++ /dev/null @@ -1,203 +0,0 @@ -// -// X509Extensions.cs: Handles X.509 extensions. -// -// Author: -// Sebastien Pouliot -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// (C) 2004 Novell (http://www.novell.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; - -using Mono.Security; - -namespace Mono.Security.X509 { - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - * - * Note: 1..MAX -> There shouldn't be 0 Extensions in the ASN1 structure - */ -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class X509ExtensionCollection : CollectionBase, IEnumerable { - - private bool readOnly; - - public X509ExtensionCollection () : base () - { - } - - public X509ExtensionCollection (ASN1 asn1) : this () - { - readOnly = true; - if (asn1 == null) - return; - if (asn1.Tag != 0x30) - throw new Exception ("Invalid extensions format"); - for (int i=0; i < asn1.Count; i++) { - X509Extension extension = new X509Extension (asn1 [i]); - InnerList.Add (extension); - } - } - - public int Add (X509Extension extension) - { - if (extension == null) - throw new ArgumentNullException ("extension"); - if (readOnly) - throw new NotSupportedException ("Extensions are read only"); - - return InnerList.Add (extension); - } - - public void AddRange (X509Extension[] extension) - { - if (extension == null) - throw new ArgumentNullException ("extension"); - if (readOnly) - throw new NotSupportedException ("Extensions are read only"); - - for (int i = 0; i < extension.Length; i++) - InnerList.Add (extension [i]); - } - - public void AddRange (X509ExtensionCollection collection) - { - if (collection == null) - throw new ArgumentNullException ("collection"); - if (readOnly) - throw new NotSupportedException ("Extensions are read only"); - - for (int i = 0; i < collection.InnerList.Count; i++) - InnerList.Add (collection [i]); - } - - public bool Contains (X509Extension extension) - { - return (IndexOf (extension) != -1); - } - - public bool Contains (string oid) - { - return (IndexOf (oid) != -1); - } - - public void CopyTo (X509Extension[] extensions, int index) - { - if (extensions == null) - throw new ArgumentNullException ("extensions"); - - InnerList.CopyTo (extensions, index); - } - - public int IndexOf (X509Extension extension) - { - if (extension == null) - throw new ArgumentNullException ("extension"); - - for (int i=0; i < InnerList.Count; i++) { - X509Extension ex = (X509Extension) InnerList [i]; - if (ex.Equals (extension)) - return i; - } - return -1; - } - - public int IndexOf (string oid) - { - if (oid == null) - throw new ArgumentNullException ("oid"); - - for (int i=0; i < InnerList.Count; i++) { - X509Extension ex = (X509Extension) InnerList [i]; - if (ex.Oid == oid) - return i; - } - return -1; - } - - public void Insert (int index, X509Extension extension) - { - if (extension == null) - throw new ArgumentNullException ("extension"); - - InnerList.Insert (index, extension); - } - - public void Remove (X509Extension extension) - { - if (extension == null) - throw new ArgumentNullException ("extension"); - - InnerList.Remove (extension); - } - - public void Remove (string oid) - { - if (oid == null) - throw new ArgumentNullException ("oid"); - - int index = IndexOf (oid); - if (index != -1) - InnerList.RemoveAt (index); - } - - IEnumerator IEnumerable.GetEnumerator () - { - return InnerList.GetEnumerator (); - } - - public X509Extension this [int index] { - get { return (X509Extension) InnerList [index]; } - } - - public X509Extension this [string oid] { - get { - int index = IndexOf (oid); - if (index == -1) - return null; - return (X509Extension) InnerList [index]; - } - } - - public byte[] GetBytes () - { - if (InnerList.Count < 1) - return null; - ASN1 sequence = new ASN1 (0x30); - for (int i=0; i < InnerList.Count; i++) { - X509Extension x = (X509Extension) InnerList [i]; - sequence.Add (x.ASN1); - } - return sequence.GetBytes (); - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509Store.cs b/mcs/class/corlib/Mono.Security.X509/X509Store.cs deleted file mode 100644 index c4bb4b99afc..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509Store.cs +++ /dev/null @@ -1,355 +0,0 @@ -// -// X509Store.cs: Handles a X.509 certificates/CRLs store -// -// Author: -// Sebastien Pouliot -// Pablo Ruiz -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// (C) 2010 Pablo Ruiz. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.Globalization; -using System.IO; -using System.Text; -using System.Security.Cryptography; - -using Mono.Security.Cryptography; -using Mono.Security.X509.Extensions; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class X509Store { - - private string _storePath; - private X509CertificateCollection _certificates; - private ArrayList _crls; - private bool _crl; - private string _name; - - internal X509Store (string path, bool crl) - { - _storePath = path; - _crl = crl; - } - - // properties - - public X509CertificateCollection Certificates { - get { - if (_certificates == null) { - _certificates = BuildCertificatesCollection (_storePath); - } - return _certificates; - } - } - - public ArrayList Crls { - get { - // CRL aren't applicable to all stores - // but returning null is a little rude - if (!_crl) { - _crls = new ArrayList (); - } - if (_crls == null) { - _crls = BuildCrlsCollection (_storePath); - } - return _crls; - } - } - - public string Name { - get { - if (_name == null) { - int n = _storePath.LastIndexOf (Path.DirectorySeparatorChar); - _name = _storePath.Substring (n+1); - } - return _name; - } - } - - // methods - - public void Clear () - { - if (_certificates != null) - _certificates.Clear (); - _certificates = null; - if (_crls != null) - _crls.Clear (); - _crls = null; - } - - public void Import (X509Certificate certificate) - { - CheckStore (_storePath, true); - - string filename = Path.Combine (_storePath, GetUniqueName (certificate)); - if (!File.Exists (filename)) { - using (FileStream fs = File.Create (filename)) { - byte[] data = certificate.RawData; - fs.Write (data, 0, data.Length); - fs.Close (); - } - } -#if !NET_2_1 - // Try to save privateKey if available.. - CspParameters cspParams = new CspParameters (); - cspParams.KeyContainerName = CryptoConvert.ToHex (certificate.Hash); - - // Right now this seems to be the best way to know if we should use LM store.. ;) - if (_storePath.StartsWith (X509StoreManager.LocalMachinePath)) - cspParams.Flags = CspProviderFlags.UseMachineKeyStore; - - ImportPrivateKey (certificate, cspParams); -#endif - } - - public void Import (X509Crl crl) - { - CheckStore (_storePath, true); - - string filename = Path.Combine (_storePath, GetUniqueName (crl)); - if (!File.Exists (filename)) { - using (FileStream fs = File.Create (filename)) { - byte[] data = crl.RawData; - fs.Write (data, 0, data.Length); - } - } - } - - public void Remove (X509Certificate certificate) - { - string filename = Path.Combine (_storePath, GetUniqueName (certificate)); - if (File.Exists (filename)) { - File.Delete (filename); - } - } - - public void Remove (X509Crl crl) - { - string filename = Path.Combine (_storePath, GetUniqueName (crl)); - if (File.Exists (filename)) { - File.Delete (filename); - } - } - - // private stuff - - private string GetUniqueName (X509Certificate certificate) - { - string method; - byte[] name = GetUniqueName (certificate.Extensions); - if (name == null) { - method = "tbp"; // thumbprint - name = certificate.Hash; - } else { - method = "ski"; - } - return GetUniqueName (method, name, ".cer"); - } - - private string GetUniqueName (X509Crl crl) - { - string method; - byte[] name = GetUniqueName (crl.Extensions); - if (name == null) { - method = "tbp"; // thumbprint - name = crl.Hash; - } else { - method = "ski"; - } - return GetUniqueName (method, name, ".crl"); - } - - private byte[] GetUniqueName (X509ExtensionCollection extensions) - { - // We prefer Subject Key Identifier as the unique name - // as it will provide faster lookups - X509Extension ext = extensions ["2.5.29.14"]; - if (ext == null) - return null; - - SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension (ext); - return ski.Identifier; - } - - private string GetUniqueName (string method, byte[] name, string fileExtension) - { - StringBuilder sb = new StringBuilder (method); - - sb.Append ("-"); - foreach (byte b in name) { - sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture)); - } - sb.Append (fileExtension); - - return sb.ToString (); - } - - private byte[] Load (string filename) - { - byte[] data = null; - using (FileStream fs = File.OpenRead (filename)) { - data = new byte [fs.Length]; - fs.Read (data, 0, data.Length); - fs.Close (); - } - return data; - } - - private X509Certificate LoadCertificate (string filename) - { - byte[] data = Load (filename); - X509Certificate cert = new X509Certificate (data); -#if !NET_2_1 - // If privateKey it's available, load it too.. - CspParameters cspParams = new CspParameters (); - cspParams.KeyContainerName = CryptoConvert.ToHex (cert.Hash); - if (_storePath.StartsWith (X509StoreManager.LocalMachinePath)) - cspParams.Flags = CspProviderFlags.UseMachineKeyStore; - KeyPairPersistence kpp = new KeyPairPersistence (cspParams); - - if (!kpp.Load ()) - return cert; - - if (cert.RSA != null) - cert.RSA = new RSACryptoServiceProvider (cspParams); - else if (cert.DSA != null) - cert.DSA = new DSACryptoServiceProvider (cspParams); -#endif - return cert; - } - - private X509Crl LoadCrl (string filename) - { - byte[] data = Load (filename); - X509Crl crl = new X509Crl (data); - return crl; - } - - private bool CheckStore (string path, bool throwException) - { - try { - if (Directory.Exists (path)) - return true; - Directory.CreateDirectory (path); - return Directory.Exists (path); - } - catch { - if (throwException) - throw; - return false; - } - } - - private X509CertificateCollection BuildCertificatesCollection (string storeName) - { - X509CertificateCollection coll = new X509CertificateCollection (); - string path = Path.Combine (_storePath, storeName); - if (!CheckStore (path, false)) - return coll; // empty collection - - string[] files = Directory.GetFiles (path, "*.cer"); - if ((files != null) && (files.Length > 0)) { - foreach (string file in files) { - try { - X509Certificate cert = LoadCertificate (file); - coll.Add (cert); - } - catch { - // in case someone is dumb enough - // (like me) to include a base64 - // encoded certs (or other junk - // into the store). - } - } - } - return coll; - } - - private ArrayList BuildCrlsCollection (string storeName) - { - ArrayList list = new ArrayList (); - string path = Path.Combine (_storePath, storeName); - if (!CheckStore (path, false)) - return list; // empty list - - string[] files = Directory.GetFiles (path, "*.crl"); - if ((files != null) && (files.Length > 0)) { - foreach (string file in files) { - try { - X509Crl crl = LoadCrl (file); - list.Add (crl); - } - catch { - // junk catcher - } - } - } - return list; - } -#if !NET_2_1 - private void ImportPrivateKey (X509Certificate certificate, CspParameters cspParams) - { - RSACryptoServiceProvider rsaCsp = certificate.RSA as RSACryptoServiceProvider; - if (rsaCsp != null) { - if (rsaCsp.PublicOnly) - return; - - RSACryptoServiceProvider csp = new RSACryptoServiceProvider(cspParams); - csp.ImportParameters(rsaCsp.ExportParameters(true)); - csp.PersistKeyInCsp = true; - return; - } - - RSAManaged rsaMng = certificate.RSA as RSAManaged; - if (rsaMng != null) { - if (rsaMng.PublicOnly) - return; - - RSACryptoServiceProvider csp = new RSACryptoServiceProvider(cspParams); - csp.ImportParameters(rsaMng.ExportParameters(true)); - csp.PersistKeyInCsp = true; - return; - } - - DSACryptoServiceProvider dsaCsp = certificate.DSA as DSACryptoServiceProvider; - if (dsaCsp != null) { - if (dsaCsp.PublicOnly) - return; - - DSACryptoServiceProvider csp = new DSACryptoServiceProvider(cspParams); - csp.ImportParameters(dsaCsp.ExportParameters(true)); - csp.PersistKeyInCsp = true; - } - } -#endif - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509StoreManager.cs b/mcs/class/corlib/Mono.Security.X509/X509StoreManager.cs deleted file mode 100644 index db735834acd..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509StoreManager.cs +++ /dev/null @@ -1,146 +0,0 @@ -// -// X509StoreManager.cs: X.509 store manager. -// -// Author: -// Sebastien Pouliot -// -// (C) 2004 Novell (http://www.novell.com) -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.IO; - -using Mono.Security.X509.Extensions; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class X509StoreManager { - - static private string _userPath; - static private string _localMachinePath; - static private X509Stores _userStore; - static private X509Stores _machineStore; - - private X509StoreManager () - { - } - - internal static string CurrentUserPath { - get { - if (_userPath == null) { - _userPath = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - ".mono"); - _userPath = Path.Combine(_userPath, "certs"); - } - return _userPath; - } - } - - internal static string LocalMachinePath { - get { - if (_localMachinePath == null) { - _localMachinePath = Path.Combine ( - Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData), - ".mono"); - _localMachinePath = Path.Combine (_localMachinePath, "certs"); - } - return _localMachinePath; - } - } - - static public X509Stores CurrentUser { - get { - if (_userStore == null) - _userStore = new X509Stores(CurrentUserPath); - - return _userStore; - } - } - - static public X509Stores LocalMachine { - get { - if (_machineStore == null) - _machineStore = new X509Stores (LocalMachinePath); - - return _machineStore; - } - } - - // Merged stores collections - // we need to look at both the user and the machine (entreprise) - // certificates/CRLs when building/validating a chain - - static public X509CertificateCollection IntermediateCACertificates { - get { - X509CertificateCollection intermediateCerts = new X509CertificateCollection (); - intermediateCerts.AddRange (CurrentUser.IntermediateCA.Certificates); - intermediateCerts.AddRange (LocalMachine.IntermediateCA.Certificates); - return intermediateCerts; - } - } - - static public ArrayList IntermediateCACrls { - get { - ArrayList intermediateCRLs = new ArrayList (); - intermediateCRLs.AddRange (CurrentUser.IntermediateCA.Crls); - intermediateCRLs.AddRange (LocalMachine.IntermediateCA.Crls); - return intermediateCRLs; - } - } - - static public X509CertificateCollection TrustedRootCertificates { - get { - X509CertificateCollection trustedCerts = new X509CertificateCollection (); - trustedCerts.AddRange (CurrentUser.TrustedRoot.Certificates); - trustedCerts.AddRange (LocalMachine.TrustedRoot.Certificates); - return trustedCerts; - } - } - - static public ArrayList TrustedRootCACrls { - get { - ArrayList trustedCRLs = new ArrayList (); - trustedCRLs.AddRange (CurrentUser.TrustedRoot.Crls); - trustedCRLs.AddRange (LocalMachine.TrustedRoot.Crls); - return trustedCRLs; - } - } - - static public X509CertificateCollection UntrustedCertificates { - get { - X509CertificateCollection untrustedCerts = new X509CertificateCollection (); - untrustedCerts.AddRange (CurrentUser.Untrusted.Certificates); - untrustedCerts.AddRange (LocalMachine.Untrusted.Certificates); - return untrustedCerts; - } - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X509Stores.cs b/mcs/class/corlib/Mono.Security.X509/X509Stores.cs deleted file mode 100644 index bfe7451b5de..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X509Stores.cs +++ /dev/null @@ -1,158 +0,0 @@ -// -// X509Stores.cs: Handles X.509 certificates/CRLs stores group. -// -// Author: -// Sebastien Pouliot -// -// (C) 2004 Novell (http://www.novell.com) -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.IO; - -using Mono.Security.X509.Extensions; - -namespace Mono.Security.X509 { - -#if INSIDE_CORLIB - internal -#else - public -#endif - class X509Stores { - - private string _storePath; - private X509Store _personal; - private X509Store _other; - private X509Store _intermediate; - private X509Store _trusted; - private X509Store _untrusted; - - internal X509Stores (string path) - { - _storePath = path; - } - - // properties - - public X509Store Personal { - get { - if (_personal == null) { - string path = Path.Combine (_storePath, Names.Personal); - _personal = new X509Store (path, false); - } - return _personal; - } - } - - public X509Store OtherPeople { - get { - if (_other == null) { - string path = Path.Combine (_storePath, Names.OtherPeople); - _other = new X509Store (path, false); - } - return _other; - } - } - - public X509Store IntermediateCA { - get { - if (_intermediate == null) { - string path = Path.Combine (_storePath, Names.IntermediateCA); - _intermediate = new X509Store (path, true); - } - return _intermediate; - } - } - - public X509Store TrustedRoot { - get { - if (_trusted == null) { - string path = Path.Combine (_storePath, Names.TrustedRoot); - _trusted = new X509Store (path, true); - } - return _trusted; - } - } - - public X509Store Untrusted { - get { - if (_untrusted == null) { - string path = Path.Combine (_storePath, Names.Untrusted); - _untrusted = new X509Store (path, false); - } - return _untrusted; - } - } - - // methods - - public void Clear () - { - // this will force a reload of all stores - if (_personal != null) - _personal.Clear (); - _personal = null; - if (_other != null) - _other.Clear (); - _other = null; - if (_intermediate != null) - _intermediate.Clear (); - _intermediate = null; - if (_trusted != null) - _trusted.Clear (); - _trusted = null; - if (_untrusted != null) - _untrusted.Clear (); - _untrusted = null; - } - - public X509Store Open (string storeName, bool create) - { - if (storeName == null) - throw new ArgumentNullException ("storeName"); - - string path = Path.Combine (_storePath, storeName); - if (!create && !Directory.Exists (path)) - return null; - - return new X509Store (path, true); - } - - // names - - public class Names { - - // do not translate - public const string Personal = "My"; - public const string OtherPeople = "AddressBook"; - public const string IntermediateCA = "CA"; - public const string TrustedRoot = "Trust"; - public const string Untrusted = "Disallowed"; - - public Names () {} - } - } -} diff --git a/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs b/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs deleted file mode 100644 index b8506aab791..00000000000 --- a/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs +++ /dev/null @@ -1,353 +0,0 @@ -// -// X520.cs: X.520 related stuff (attributes, RDN) -// -// Author: -// Sebastien Pouliot -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Text; - -using Mono.Security; - -namespace Mono.Security.X509 { - - // References: - // 1. Information technology - Open Systems Interconnection - The Directory: Selected attribute types - // http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.520 - // 2. Internet X.509 Public Key Infrastructure Certificate and CRL Profile - // http://www.ietf.org/rfc/rfc3280.txt - // 3. A Summary of the X.500(96) User Schema for use with LDAPv3 - // http://www.faqs.org/rfcs/rfc2256.html - // 4. RFC 2247 - Using Domains in LDAP/X.500 Distinguished Names - // http://www.faqs.org/rfcs/rfc2247.html - - /* - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue - * } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - */ -#if INSIDE_CORLIB - internal -#else - public -#endif - class X520 { - - public abstract class AttributeTypeAndValue { - private string oid; - private string attrValue; - private int upperBound; - private byte encoding; - - protected AttributeTypeAndValue (string oid, int upperBound) - { - this.oid = oid; - this.upperBound = upperBound; - this.encoding = 0xFF; - } - - protected AttributeTypeAndValue (string oid, int upperBound, byte encoding) - { - this.oid = oid; - this.upperBound = upperBound; - this.encoding = encoding; - } - - public string Value { - get { return attrValue; } - set { - if ((attrValue != null) && (attrValue.Length > upperBound)) { - string msg = Locale.GetText ("Value length bigger than upperbound ({0})."); - throw new FormatException (String.Format (msg, upperBound)); - } - attrValue = value; - } - } - - public ASN1 ASN1 { - get { return GetASN1 (); } - } - - internal ASN1 GetASN1 (byte encoding) - { - byte encode = encoding; - if (encode == 0xFF) - encode = SelectBestEncoding (); - - ASN1 asn1 = new ASN1 (0x30); - asn1.Add (ASN1Convert.FromOid (oid)); - switch (encode) { - case 0x13: - // PRINTABLESTRING - asn1.Add (new ASN1 (0x13, Encoding.ASCII.GetBytes (attrValue))); - break; - case 0x16: - // IA5STRING - asn1.Add (new ASN1 (0x16, Encoding.ASCII.GetBytes (attrValue))); - break; - case 0x1E: - // BMPSTRING - asn1.Add (new ASN1 (0x1E, Encoding.BigEndianUnicode.GetBytes (attrValue))); - break; - } - return asn1; - } - - internal ASN1 GetASN1 () - { - return GetASN1 (encoding); - } - - public byte[] GetBytes (byte encoding) - { - return GetASN1 (encoding) .GetBytes (); - } - - public byte[] GetBytes () - { - return GetASN1 () .GetBytes (); - } - - private byte SelectBestEncoding () - { - foreach (char c in attrValue) { - switch (c) { - case '@': - case '_': - return 0x1E; // BMPSTRING - default: - if (c > 127) - return 0x1E; // BMPSTRING - break; - } - } - return 0x13; // PRINTABLESTRING - } - } - - public class Name : AttributeTypeAndValue { - - public Name () : base ("2.5.4.41", 32768) - { - } - } - - public class CommonName : AttributeTypeAndValue { - - public CommonName () : base ("2.5.4.3", 64) - { - } - } - - // RFC2256, Section 5.6 - public class SerialNumber : AttributeTypeAndValue { - - // max length 64 bytes, Printable String only - public SerialNumber () - : base ("2.5.4.5", 64, 0x13) - { - } - } - - public class LocalityName : AttributeTypeAndValue { - - public LocalityName () : base ("2.5.4.7", 128) - { - } - } - - public class StateOrProvinceName : AttributeTypeAndValue { - - public StateOrProvinceName () : base ("2.5.4.8", 128) - { - } - } - - public class OrganizationName : AttributeTypeAndValue { - - public OrganizationName () : base ("2.5.4.10", 64) - { - } - } - - public class OrganizationalUnitName : AttributeTypeAndValue { - - public OrganizationalUnitName () : base ("2.5.4.11", 64) - { - } - } - - // NOTE: Not part of RFC2253 - public class EmailAddress : AttributeTypeAndValue { - - public EmailAddress () : base ("1.2.840.113549.1.9.1", 128, 0x16) - { - } - } - - // RFC2247, Section 4 - public class DomainComponent : AttributeTypeAndValue { - - // no maximum length defined - public DomainComponent () - : base ("0.9.2342.19200300.100.1.25", Int32.MaxValue, 0x16) - { - } - } - - // RFC1274, Section 9.3.1 - public class UserId : AttributeTypeAndValue { - - public UserId () - : base ("0.9.2342.19200300.100.1.1", 256) - { - } - } - - public class Oid : AttributeTypeAndValue { - - public Oid (string oid) - : base (oid, Int32.MaxValue) - { - } - } - - /* -- Naming attributes of type X520Title - * id-at-title AttributeType ::= { id-at 12 } - * - * X520Title ::= CHOICE { - * teletexString TeletexString (SIZE (1..ub-title)), - * printableString PrintableString (SIZE (1..ub-title)), - * universalString UniversalString (SIZE (1..ub-title)), - * utf8String UTF8String (SIZE (1..ub-title)), - * bmpString BMPString (SIZE (1..ub-title)) - * } - */ - public class Title : AttributeTypeAndValue { - - public Title () : base ("2.5.4.12", 64) - { - } - } - - public class CountryName : AttributeTypeAndValue { - - // (0x13) PRINTABLESTRING - public CountryName () : base ("2.5.4.6", 2, 0x13) - { - } - } - - public class DnQualifier : AttributeTypeAndValue { - - // (0x13) PRINTABLESTRING - public DnQualifier () : base ("2.5.4.46", 2, 0x13) - { - } - } - - public class Surname : AttributeTypeAndValue { - - public Surname () : base ("2.5.4.4", 32768) - { - } - } - - public class GivenName : AttributeTypeAndValue { - - public GivenName () : base ("2.5.4.42", 16) - { - } - } - - public class Initial : AttributeTypeAndValue { - - public Initial () : base ("2.5.4.43", 5) - { - } - } - - } - - /* From RFC3280 - * -- specifications of Upper Bounds MUST be regarded as mandatory - * -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter - * - * -- Upper Bounds - * - * ub-name INTEGER ::= 32768 - * ub-common-name INTEGER ::= 64 - * ub-locality-name INTEGER ::= 128 - * ub-state-name INTEGER ::= 128 - * ub-organization-name INTEGER ::= 64 - * ub-organizational-unit-name INTEGER ::= 64 - * ub-title INTEGER ::= 64 - * ub-serial-number INTEGER ::= 64 - * ub-match INTEGER ::= 128 - * ub-emailaddress-length INTEGER ::= 128 - * ub-common-name-length INTEGER ::= 64 - * ub-country-name-alpha-length INTEGER ::= 2 - * ub-country-name-numeric-length INTEGER ::= 3 - * ub-domain-defined-attributes INTEGER ::= 4 - * ub-domain-defined-attribute-type-length INTEGER ::= 8 - * ub-domain-defined-attribute-value-length INTEGER ::= 128 - * ub-domain-name-length INTEGER ::= 16 - * ub-extension-attributes INTEGER ::= 256 - * ub-e163-4-number-length INTEGER ::= 15 - * ub-e163-4-sub-address-length INTEGER ::= 40 - * ub-generation-qualifier-length INTEGER ::= 3 - * ub-given-name-length INTEGER ::= 16 - * ub-initials-length INTEGER ::= 5 - * ub-integer-options INTEGER ::= 256 - * ub-numeric-user-id-length INTEGER ::= 32 - * ub-organization-name-length INTEGER ::= 64 - * ub-organizational-unit-name-length INTEGER ::= 32 - * ub-organizational-units INTEGER ::= 4 - * ub-pds-name-length INTEGER ::= 16 - * ub-pds-parameter-length INTEGER ::= 30 - * ub-pds-physical-address-lines INTEGER ::= 6 - * ub-postal-code-length INTEGER ::= 16 - * ub-pseudonym INTEGER ::= 128 - * ub-surname-length INTEGER ::= 40 - * ub-terminal-id-length INTEGER ::= 24 - * ub-unformatted-address-length INTEGER ::= 180 - * ub-x121-address-length INTEGER ::= 16 - * - * -- Note - upper bounds on string types, such as TeletexString, are - * -- measured in characters. Excepting PrintableString or IA5String, a - * -- significantly greater number of octets will be required to hold - * -- such a value. As a minimum, 16 octets, or twice the specified - * -- upper bound, whichever is the larger, should be allowed for - * -- TeletexString. For UTF8String or UniversalString at least four - * -- times the upper bound should be allowed. - */ -} diff --git a/mcs/class/corlib/Mono.Security/ASN1.cs b/mcs/class/corlib/Mono.Security/ASN1.cs deleted file mode 100644 index 2d656706764..00000000000 --- a/mcs/class/corlib/Mono.Security/ASN1.cs +++ /dev/null @@ -1,343 +0,0 @@ -// -// ASN1.cs: Abstract Syntax Notation 1 - micro-parser and generator -// -// Authors: -// Sebastien Pouliot -// Jesper Pedersen -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// (C) 2004 IT+ A/S (http://www.itplus.dk) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.IO; -using System.Text; - -namespace Mono.Security { - - // References: - // a. ITU ASN.1 standards (free download) - // http://www.itu.int/ITU-T/studygroups/com17/languages/ -#if INSIDE_CORLIB - internal -#else - public -#endif - class ASN1 { - - private byte m_nTag; - private byte[] m_aValue; - private ArrayList elist; - - public ASN1 () : this (0x00, null) {} - - public ASN1 (byte tag) : this (tag, null) {} - - public ASN1 (byte tag, byte[] data) - { - m_nTag = tag; - m_aValue = data; - } - - public ASN1 (byte[] data) - { - m_nTag = data [0]; - - int nLenLength = 0; - int nLength = data [1]; - - if (nLength > 0x80) { - // composed length - nLenLength = nLength - 0x80; - nLength = 0; - for (int i = 0; i < nLenLength; i++) { - nLength *= 256; - nLength += data [i + 2]; - } - } - else if (nLength == 0x80) { - // undefined length encoding - throw new NotSupportedException ("Undefined length encoding."); - } - - m_aValue = new byte [nLength]; - Buffer.BlockCopy (data, (2 + nLenLength), m_aValue, 0, nLength); - - if ((m_nTag & 0x20) == 0x20) { - int nStart = (2 + nLenLength); - Decode (data, ref nStart, data.Length); - } - } - - public int Count { - get { - if (elist == null) - return 0; - return elist.Count; - } - } - - public byte Tag { - get { return m_nTag; } - } - - public int Length { - get { - if (m_aValue != null) - return m_aValue.Length; - else - return 0; - } - } - - public byte[] Value { - get { - if (m_aValue == null) - GetBytes (); - return (byte[]) m_aValue.Clone (); - } - set { - if (value != null) - m_aValue = (byte[]) value.Clone (); - } - } - - private bool CompareArray (byte[] array1, byte[] array2) - { - bool bResult = (array1.Length == array2.Length); - if (bResult) { - for (int i = 0; i < array1.Length; i++) { - if (array1[i] != array2[i]) - return false; - } - } - return bResult; - } - - public bool Equals (byte[] asn1) - { - return CompareArray (this.GetBytes (), asn1); - } - - public bool CompareValue (byte[] value) - { - return CompareArray (m_aValue, value); - } - - public ASN1 Add (ASN1 asn1) - { - if (asn1 != null) { - if (elist == null) - elist = new ArrayList (); - elist.Add (asn1); - } - return asn1; - } - - public virtual byte[] GetBytes () - { - byte[] val = null; - - if (Count > 0) { - int esize = 0; - ArrayList al = new ArrayList (); - foreach (ASN1 a in elist) { - byte[] item = a.GetBytes (); - al.Add (item); - esize += item.Length; - } - val = new byte [esize]; - int pos = 0; - for (int i=0; i < elist.Count; i++) { - byte[] item = (byte[]) al[i]; - Buffer.BlockCopy (item, 0, val, pos, item.Length); - pos += item.Length; - } - } else if (m_aValue != null) { - val = m_aValue; - } - - byte[] der; - int nLengthLen = 0; - - if (val != null) { - int nLength = val.Length; - // special for length > 127 - if (nLength > 127) { - if (nLength <= Byte.MaxValue) { - der = new byte [3 + nLength]; - Buffer.BlockCopy (val, 0, der, 3, nLength); - nLengthLen = 0x81; - der[2] = (byte)(nLength); - } - else if (nLength <= UInt16.MaxValue) { - der = new byte [4 + nLength]; - Buffer.BlockCopy (val, 0, der, 4, nLength); - nLengthLen = 0x82; - der[2] = (byte)(nLength >> 8); - der[3] = (byte)(nLength); - } - else if (nLength <= 0xFFFFFF) { - // 24 bits - der = new byte [5 + nLength]; - Buffer.BlockCopy (val, 0, der, 5, nLength); - nLengthLen = 0x83; - der [2] = (byte)(nLength >> 16); - der [3] = (byte)(nLength >> 8); - der [4] = (byte)(nLength); - } - else { - // max (Length is an integer) 32 bits - der = new byte [6 + nLength]; - Buffer.BlockCopy (val, 0, der, 6, nLength); - nLengthLen = 0x84; - der [2] = (byte)(nLength >> 24); - der [3] = (byte)(nLength >> 16); - der [4] = (byte)(nLength >> 8); - der [5] = (byte)(nLength); - } - } - else { - // basic case (no encoding) - der = new byte [2 + nLength]; - Buffer.BlockCopy (val, 0, der, 2, nLength); - nLengthLen = nLength; - } - if (m_aValue == null) - m_aValue = val; - } - else - der = new byte[2]; - - der[0] = m_nTag; - der[1] = (byte)nLengthLen; - - return der; - } - - // Note: Recursive - protected void Decode (byte[] asn1, ref int anPos, int anLength) - { - byte nTag; - int nLength; - byte[] aValue; - - // minimum is 2 bytes (tag + length of 0) - while (anPos < anLength - 1) { - DecodeTLV (asn1, ref anPos, out nTag, out nLength, out aValue); - // sometimes we get trailing 0 - if (nTag == 0) - continue; - - ASN1 elm = Add (new ASN1 (nTag, aValue)); - - if ((nTag & 0x20) == 0x20) { - int nConstructedPos = anPos; - elm.Decode (asn1, ref nConstructedPos, nConstructedPos + nLength); - } - anPos += nLength; // value length - } - } - - // TLV : Tag - Length - Value - protected void DecodeTLV (byte[] asn1, ref int pos, out byte tag, out int length, out byte[] content) - { - tag = asn1 [pos++]; - length = asn1 [pos++]; - - // special case where L contains the Length of the Length + 0x80 - if ((length & 0x80) == 0x80) { - int nLengthLen = length & 0x7F; - length = 0; - for (int i = 0; i < nLengthLen; i++) - length = length * 256 + asn1 [pos++]; - } - - content = new byte [length]; - Buffer.BlockCopy (asn1, pos, content, 0, length); - } - - public ASN1 this [int index] { - get { - try { - if ((elist == null) || (index >= elist.Count)) - return null; - return (ASN1) elist [index]; - } - catch (ArgumentOutOfRangeException) { - return null; - } - } - } - - public ASN1 Element (int index, byte anTag) - { - try { - if ((elist == null) || (index >= elist.Count)) - return null; - - ASN1 elm = (ASN1) elist [index]; - if (elm.Tag == anTag) - return elm; - else - return null; - } - catch (ArgumentOutOfRangeException) { - return null; - } - } - - public override string ToString() - { - StringBuilder hexLine = new StringBuilder (); - - // Add tag - hexLine.AppendFormat ("Tag: {0} {1}", m_nTag.ToString ("X2"), Environment.NewLine); - - // Add length - hexLine.AppendFormat ("Length: {0} {1}", Value.Length, Environment.NewLine); - - // Add value - hexLine.Append ("Value: "); - hexLine.Append (Environment.NewLine); - for (int i = 0; i < Value.Length; i++) { - hexLine.AppendFormat ("{0} ", Value [i].ToString ("X2")); - if ((i+1) % 16 == 0) - hexLine.AppendFormat (Environment.NewLine); - } - return hexLine.ToString (); - } - - public void SaveToFile (string filename) - { - if (filename == null) - throw new ArgumentNullException ("filename"); - - using (FileStream fs = File.Create (filename)) { - byte[] data = GetBytes (); - fs.Write (data, 0, data.Length); - } - } - } -} diff --git a/mcs/class/corlib/Mono.Security/ASN1Convert.cs b/mcs/class/corlib/Mono.Security/ASN1Convert.cs deleted file mode 100644 index 3a1cf930183..00000000000 --- a/mcs/class/corlib/Mono.Security/ASN1Convert.cs +++ /dev/null @@ -1,212 +0,0 @@ -// -// ASN1Convert.cs: Abstract Syntax Notation 1 convertion routines -// -// Authors: -// Sebastien Pouliot -// Jesper Pedersen -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// (C) 2004 IT+ A/S (http://www.itplus.dk) -// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.Globalization; -using System.Security.Cryptography; -using System.Text; - -namespace Mono.Security { - - // References: - // a. ITU ASN.1 standards (free download) - // http://www.itu.int/ITU-T/studygroups/com17/languages/ - -#if INSIDE_CORLIB - internal -#else - public -#endif - static class ASN1Convert { - // RFC3280, section 4.2.1.5 - // CAs conforming to this profile MUST always encode certificate - // validity dates through the year 2049 as UTCTime; certificate validity - // dates in 2050 or later MUST be encoded as GeneralizedTime. - - // Under 1.x this API requires a Local datetime to be provided - // Under 2.0 it will also accept a Utc datetime - static public ASN1 FromDateTime (DateTime dt) - { - if (dt.Year < 2050) { - // UTCTIME - return new ASN1 (0x17, Encoding.ASCII.GetBytes ( - dt.ToUniversalTime ().ToString ("yyMMddHHmmss", - CultureInfo.InvariantCulture) + "Z")); - } - else { - // GENERALIZEDTIME - return new ASN1 (0x18, Encoding.ASCII.GetBytes ( - dt.ToUniversalTime ().ToString ("yyyyMMddHHmmss", - CultureInfo.InvariantCulture) + "Z")); - } - } - - static public ASN1 FromInt32 (Int32 value) - { - byte[] integer = BitConverterLE.GetBytes (value); - Array.Reverse (integer); - int x = 0; - while ((x < integer.Length) && (integer [x] == 0x00)) - x++; - ASN1 asn1 = new ASN1 (0x02); - switch (x) { - case 0: - asn1.Value = integer; - break; - case 4: - asn1.Value = new byte [1]; - break; - default: - byte[] smallerInt = new byte [4 - x]; - Buffer.BlockCopy (integer, x, smallerInt, 0, smallerInt.Length); - asn1.Value = smallerInt; - break; - } - return asn1; - } - - static public ASN1 FromOid (string oid) - { - if (oid == null) - throw new ArgumentNullException ("oid"); - - return new ASN1 (CryptoConfig.EncodeOID (oid)); - } - - static public ASN1 FromUnsignedBigInteger (byte[] big) - { - if (big == null) - throw new ArgumentNullException ("big"); - - // check for numbers that could be interpreted as negative (first bit) - if (big [0] >= 0x80) { - // in thie cas we add a new, empty, byte (position 0) so we're - // sure this will always be interpreted an unsigned integer. - // However we can't feed it into RSAParameters or DSAParameters - int length = big.Length + 1; - byte[] uinteger = new byte [length]; - Buffer.BlockCopy (big, 0, uinteger, 1, length - 1); - big = uinteger; - } - return new ASN1 (0x02, big); - } - - static public int ToInt32 (ASN1 asn1) - { - if (asn1 == null) - throw new ArgumentNullException ("asn1"); - if (asn1.Tag != 0x02) - throw new FormatException ("Only integer can be converted"); - - int x = 0; - for (int i=0; i < asn1.Value.Length; i++) - x = (x << 8) + asn1.Value [i]; - return x; - } - - // Convert a binary encoded OID to human readable string representation of - // an OID (IETF style). Based on DUMPASN1.C from Peter Gutmann. - static public string ToOid (ASN1 asn1) - { - if (asn1 == null) - throw new ArgumentNullException ("asn1"); - - byte[] aOID = asn1.Value; - StringBuilder sb = new StringBuilder (); - // Pick apart the OID - byte x = (byte) (aOID[0] / 40); - byte y = (byte) (aOID[0] % 40); - if (x > 2) { - // Handle special case for large y if x = 2 - y += (byte) ((x - 2) * 40); - x = 2; - } - sb.Append (x.ToString (CultureInfo.InvariantCulture)); - sb.Append ("."); - sb.Append (y.ToString (CultureInfo.InvariantCulture)); - ulong val = 0; - for (x = 1; x < aOID.Length; x++) { - val = ((val << 7) | ((byte) (aOID [x] & 0x7F))); - if ( !((aOID [x] & 0x80) == 0x80)) { - sb.Append ("."); - sb.Append (val.ToString (CultureInfo.InvariantCulture)); - val = 0; - } - } - return sb.ToString (); - } - - static public DateTime ToDateTime (ASN1 time) - { - if (time == null) - throw new ArgumentNullException ("time"); - - string t = Encoding.ASCII.GetString (time.Value); - // to support both UTCTime and GeneralizedTime (and not so common format) - string mask = null; - int year; - switch (t.Length) { - case 11: - // illegal format, still it's supported for compatibility - mask = "yyMMddHHmmZ"; - break; - case 13: - // RFC3280: 4.1.2.5.1 UTCTime - year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture); - // Where YY is greater than or equal to 50, the - // year SHALL be interpreted as 19YY; and - // Where YY is less than 50, the year SHALL be - // interpreted as 20YY. - if (year >= 50) - t = "19" + t; - else - t = "20" + t; - mask = "yyyyMMddHHmmssZ"; - break; - case 15: - mask = "yyyyMMddHHmmssZ"; // GeneralizedTime - break; - case 17: - // another illegal format (990630000000+1000), again supported for compatibility - year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture); - string century = (year >= 50) ? "19" : "20"; - // ASN.1 (see ITU X.680 section 43.3) deals with offset differently than .NET - char sign = (t[12] == '+') ? '-' : '+'; - t = String.Format ("{0}{1}{2}{3}{4}:{5}{6}", century, t.Substring (0, 12), sign, - t[13], t[14], t[15], t[16]); - mask = "yyyyMMddHHmmsszzz"; - break; - } - return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); - } - } -} diff --git a/mcs/class/corlib/Mono.Security/BitConverterLE.cs b/mcs/class/corlib/Mono.Security/BitConverterLE.cs deleted file mode 100644 index ad3b5050da9..00000000000 --- a/mcs/class/corlib/Mono.Security/BitConverterLE.cs +++ /dev/null @@ -1,241 +0,0 @@ -// -// Mono.Security.BitConverterLE.cs -// Like System.BitConverter but always little endian -// -// Author: -// Bernie Solomon -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Security -{ - internal sealed class BitConverterLE - { - private BitConverterLE () - { - } - - unsafe private static byte[] GetUShortBytes (byte *bytes) - { - if (BitConverter.IsLittleEndian) - return new byte [] { bytes [0], bytes [1] }; - else - return new byte [] { bytes [1], bytes [0] }; - } - - unsafe private static byte[] GetUIntBytes (byte *bytes) - { - if (BitConverter.IsLittleEndian) - return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3] }; - else - return new byte [] { bytes [3], bytes [2], bytes [1], bytes [0] }; - } - - unsafe private static byte[] GetULongBytes (byte *bytes) - { - if (BitConverter.IsLittleEndian) - return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3], - bytes [4], bytes [5], bytes [6], bytes [7] }; - else - return new byte [] { bytes [7], bytes [6], bytes [5], bytes [4], - bytes [3], bytes [2], bytes [1], bytes [0] }; - } - - unsafe internal static byte[] GetBytes (bool value) - { - return new byte [] { value ? (byte)1 : (byte)0 }; - } - - unsafe internal static byte[] GetBytes (char value) - { - return GetUShortBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (short value) - { - return GetUShortBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (int value) - { - return GetUIntBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (long value) - { - return GetULongBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (ushort value) - { - return GetUShortBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (uint value) - { - return GetUIntBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (ulong value) - { - return GetULongBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (float value) - { - return GetUIntBytes ((byte *) &value); - } - - unsafe internal static byte[] GetBytes (double value) - { - return GetULongBytes ((byte *) &value); - } - - unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex) - { - if (BitConverter.IsLittleEndian) { - dst [0] = src [startIndex]; - dst [1] = src [startIndex + 1]; - } else { - dst [0] = src [startIndex + 1]; - dst [1] = src [startIndex]; - } - } - - unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex) - { - if (BitConverter.IsLittleEndian) { - dst [0] = src [startIndex]; - dst [1] = src [startIndex + 1]; - dst [2] = src [startIndex + 2]; - dst [3] = src [startIndex + 3]; - } else { - dst [0] = src [startIndex + 3]; - dst [1] = src [startIndex + 2]; - dst [2] = src [startIndex + 1]; - dst [3] = src [startIndex]; - } - } - - unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex) - { - if (BitConverter.IsLittleEndian) { - for (int i = 0; i < 8; ++i) - dst [i] = src [startIndex + i]; - } else { - for (int i = 0; i < 8; ++i) - dst [i] = src [startIndex + (7 - i)]; - } - } - - unsafe internal static bool ToBoolean (byte[] value, int startIndex) - { - return value [startIndex] != 0; - } - - unsafe internal static char ToChar (byte[] value, int startIndex) - { - char ret; - - UShortFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static short ToInt16 (byte[] value, int startIndex) - { - short ret; - - UShortFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static int ToInt32 (byte[] value, int startIndex) - { - int ret; - - UIntFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static long ToInt64 (byte[] value, int startIndex) - { - long ret; - - ULongFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static ushort ToUInt16 (byte[] value, int startIndex) - { - ushort ret; - - UShortFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static uint ToUInt32 (byte[] value, int startIndex) - { - uint ret; - - UIntFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static ulong ToUInt64 (byte[] value, int startIndex) - { - ulong ret; - - ULongFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static float ToSingle (byte[] value, int startIndex) - { - float ret; - - UIntFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - - unsafe internal static double ToDouble (byte[] value, int startIndex) - { - double ret; - - ULongFromBytes ((byte *) &ret, value, startIndex); - - return ret; - } - } -} diff --git a/mcs/class/corlib/Mono.Security/ChangeLog b/mcs/class/corlib/Mono.Security/ChangeLog deleted file mode 100644 index 97d44bda4ee..00000000000 --- a/mcs/class/corlib/Mono.Security/ChangeLog +++ /dev/null @@ -1,194 +0,0 @@ -2010-05-10 Sebastien Pouliot - - * ASN1.cs: Keep it public for Moonlight. Other types in other - assemblies needs it and the linker will eventually internalize - everything. - -2010-03-24 Sebastien Pouliot - - * ASN1Convert.cs: Specify CultureInfo.InvariantCulture (instead of - null) to avoid crash on Windows. Patch by Yoni Shalom. - -2010-03-16 Jb Evain - - * StrongName.cs: use MOONLIGHT symbol to disambiguate - MonoTouch and Moonlight code. - -2009-09-22 Sebastien Pouliot - - * StrongName.cs: Moonlight NET_2_1 cannot depend on machine.config - * StrongNameManager_2_1.cs: Minimal version for NET_2_1 - -2009-04-30 Sebastien Pouliot - - * StrongName.cs: Adapt to work with only RSAManaged when built - for NET_2_1, i.e. remove use of RSACryptoServiceProvider - -2008-09-12 Sebastien Pouliot - - * ASN1.cs: Use File.Create instead of OpenWrite to make sure nothing - else if left at the end of the file. - -2008-04-25 Sebastien Pouliot - - * StrongName.cs: New test cases to verify signatures from streams. - Patch from Dave Hillier - -2008-03-10 Stephane Delcroix - - * Uri.cs: port the changes I did in System.Uri in r97844. - -2007-03-11 Zoltan Varga - - * ASN1Convert.cs: Fix a warning. - -2007-02-12 Sebastien Pouliot - - * ASN1Convert.cs: Add support for decoding ASN.1 dates with an UTC - offset (e.g. 990630000000+1000) as some certificates use this format. - -2007-01-05 Sebastien Pouliot - - * ASN1Convert.cs: Added comment to FromDateTime to specify that, under - 1.x, the DateTime must be a local (not UTC) date time. Fixed ToDateTime - to return a DateTimeKind.Utc DateTime under 2.0. - -2006-08-17 Sebastien Pouliot - - * StrongName.cs: Fix the (very unlikely) case where an MD5 public key - token is requested (part of the spec, never seen in the wild). - -2006-06-14 Sebastien Pouliot - - * ASN1.cs: Switch condition not to use the cached data if there is a - collection being used. Skip extra 0 at the end of the byte[] buffer. - -2006-01-04 Sebastien Pouliot - - * ASN1Convert.cs: Fix convertion of integer 0 to ASN.1. - -2005-11-07 Sebastien Pouliot - - * StrongName.cs: Synch with Mono.Security.dll to get support for - strongname keypairs different from 1024 bits. - -2005-10-06 Sebastien Pouliot - - * ASN1Convert.cs: Better handle big integer than cannot be interpreted - as a negative number (don't extend). Fix bug #75778. - -2004-12-15 Sebastien Pouliot - - * ASN1.cs: Fixed warning for unused variable. - -2004-10-29 Sebastien Pouliot - - * ASN1.cs: Throw an NotSupportedException when "undefined length - encoding" is used (#68903 but it's not a fix ;-). Fixed GetBytes to - encode structures bigger than 64k (fix #68907). Simplified ToString - and added Length to help debugging. - * PKCS7.cs: Added a flag to avoid resigning a structure (which was - duplicating some attributes). - -2004-09-16 Sebastien Pouliot - - * ASN1.cs: Fixed warning (l4) for unused variable. - * PKCS7.cs: Fixed warning (l4) for unused variable. - * Uri.cs: Fixed warning (l4) for unused variables. Remove sealed from - class to reduce number of warnings. - -2004-08-30 Sebastien Pouliot - - * Uri.cs: Copied from System.dll assembly and started adaptation for - it's reuse inside the security classes (CAS). - -2004-06-08 Sebastien Pouliot - - * StrongName.cs: Added corlib specific code to load configuration - from machine.config to allow public key token remapping to work - with (for example) gacutil. - * StrongNameManager.cs: Now load configuration from machine.config. - -2004-05-19 Sebastien Pouliot - - * PKCS7.cs: In sync with Mono.Security.dll version. - -2004-05-18 Sebastien Pouliot - - * ASN1Convert.cs: In sync with Mono.Security.dll version. - * StrongName.cs: In sync with Mono.Security.dll version. - -2004-05-03 Sebastien Pouliot - - * ASN1.cs: Fixed NullReferenceException in xmldsig standalone tests. - -2004-04-28 Sebastien Pouliot - - * ASN1.cs: In sync with Mono.Security.dll version. - * ASN1Convert.cs: In sync with Mono.Security.dll version. - * PKCS7.cs: In sync with Mono.Security.dll version. - * StrongName.cs: In sync with Mono.Security.dll version. - -2004-04-20 Sebastien Pouliot - - * ASN1.cs: Added SaveToFile for easier debugging. Patch from - Jesper Pedersen. - * StrongName.cs: Removed compilation warning (unused variable). - -2004-04-08 Bernie Solomon - - * BitConverterLE.cs: added which always does - little endian conversion - * StrongName.cs: Use BitConverterLE - * ASN1Convert.cs: Use BitConverterLE - -2004-04-06 Sebastien Pouliot - - * StrongName.cs: Added support for ECMA "key" to StringName(byte[]) - constructor. - -2004-03-31 Sebastien Pouliot - - * StrongName.cs: Update to include new static method that can be - called from the runtime to validate strongname signatures. - Refactored the existing class to reduce code duplication. - * StrongNameManager.cs: New. This class keeps the configuration - required to map a public key token to an alternative public key - (e.g. ECMA public key token -> Mono public key) and to skip - strongname validation for specific assemblies/token/users. - -2004-03-24 Sebastien Pouliot - - * StrongName.cs: Added CanSign property for AssemblyBuilder. Current - Fx design requires an exception to know if the private key is present - in an RSA instance. In some case (inside corlib) we can do without... - -2004-03-23 Sebastien Pouliot - - * StrongName.cs: Added exceptions for null or invalid keys. - -2004-03-17 Sebastien Pouliot - - * ASN1.cs: Class synched with Mono.Security. - * ASN1Convert.cs: Class synched with Mono.Security. - -2003-10-18 Sebastien Pouliot - - * StrongName.cs: Added from Mono.Security assembly for StrongName - support in AssemblyBuilder. - -2003-10-12 Sebastien Pouliot - - * PKCS7.cs: Added from Mono.Security assembly for Authenticode - support in X509Certificate.CreateFromSignedFile - -2003-03-15 Sebastien Pouliot - - * ASN1.cs: Improved version. - * ASN1Convert.cs: New. Helper class to convert between .NET - types and ASN.1 structures. - -2003-02-08 Sebastien Pouliot - - * ASN1.cs: Renamed namespace to match new location. - diff --git a/mcs/class/corlib/Mono.Security/PKCS7.cs b/mcs/class/corlib/Mono.Security/PKCS7.cs deleted file mode 100644 index 3cdbb6fe4eb..00000000000 --- a/mcs/class/corlib/Mono.Security/PKCS7.cs +++ /dev/null @@ -1,976 +0,0 @@ -// -// PKCS7.cs: PKCS #7 - Cryptographic Message Syntax Standard -// http://www.rsasecurity.com/rsalabs/pkcs/pkcs-7/index.html -// -// Author: -// Sebastien Pouliot -// -// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections; -using System.Security.Cryptography; - -using Mono.Security.X509; - -namespace Mono.Security { - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class PKCS7 { - - public class Oid { - // pkcs 1 - public const string rsaEncryption = "1.2.840.113549.1.1.1"; - // pkcs 7 - public const string data = "1.2.840.113549.1.7.1"; - public const string signedData = "1.2.840.113549.1.7.2"; - public const string envelopedData = "1.2.840.113549.1.7.3"; - public const string signedAndEnvelopedData = "1.2.840.113549.1.7.4"; - public const string digestedData = "1.2.840.113549.1.7.5"; - public const string encryptedData = "1.2.840.113549.1.7.6"; - // pkcs 9 - public const string contentType = "1.2.840.113549.1.9.3"; - public const string messageDigest = "1.2.840.113549.1.9.4"; - public const string signingTime = "1.2.840.113549.1.9.5"; - public const string countersignature = "1.2.840.113549.1.9.6"; - - public Oid () - { - } - } - - private PKCS7 () - { - } - - static public ASN1 Attribute (string oid, ASN1 value) - { - ASN1 attr = new ASN1 (0x30); - attr.Add (ASN1Convert.FromOid (oid)); - ASN1 aset = attr.Add (new ASN1 (0x31)); - aset.Add (value); - return attr; - } - - static public ASN1 AlgorithmIdentifier (string oid) - { - ASN1 ai = new ASN1 (0x30); - ai.Add (ASN1Convert.FromOid (oid)); - ai.Add (new ASN1 (0x05)); // NULL - return ai; - } - - static public ASN1 AlgorithmIdentifier (string oid, ASN1 parameters) - { - ASN1 ai = new ASN1 (0x30); - ai.Add (ASN1Convert.FromOid (oid)); - ai.Add (parameters); - return ai; - } - - /* - * IssuerAndSerialNumber ::= SEQUENCE { - * issuer Name, - * serialNumber CertificateSerialNumber - * } - */ - static public ASN1 IssuerAndSerialNumber (X509Certificate x509) - { - ASN1 issuer = null; - ASN1 serial = null; - ASN1 cert = new ASN1 (x509.RawData); - int tbs = 0; - bool flag = false; - while (tbs < cert[0].Count) { - ASN1 e = cert[0][tbs++]; - if (e.Tag == 0x02) - serial = e; - else if (e.Tag == 0x30) { - if (flag) { - issuer = e; - break; - } - flag = true; - } - } - ASN1 iasn = new ASN1 (0x30); - iasn.Add (issuer); - iasn.Add (serial); - return iasn; - } - - /* - * ContentInfo ::= SEQUENCE { - * contentType ContentType, - * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL - * } - * ContentType ::= OBJECT IDENTIFIER - */ - public class ContentInfo { - - private string contentType; - private ASN1 content; - - public ContentInfo () - { - content = new ASN1 (0xA0); - } - - public ContentInfo (string oid) : this () - { - contentType = oid; - } - - public ContentInfo (byte[] data) - : this (new ASN1 (data)) {} - - public ContentInfo (ASN1 asn1) - { - // SEQUENCE with 1 or 2 elements - if ((asn1.Tag != 0x30) || ((asn1.Count < 1) && (asn1.Count > 2))) - throw new ArgumentException ("Invalid ASN1"); - if (asn1[0].Tag != 0x06) - throw new ArgumentException ("Invalid contentType"); - contentType = ASN1Convert.ToOid (asn1[0]); - if (asn1.Count > 1) { - if (asn1[1].Tag != 0xA0) - throw new ArgumentException ("Invalid content"); - content = asn1[1]; - } - } - - public ASN1 ASN1 { - get { return GetASN1(); } - } - - public ASN1 Content { - get { return content; } - set { content = value; } - } - - public string ContentType { - get { return contentType; } - set { contentType = value; } - } - - internal ASN1 GetASN1 () - { - // ContentInfo ::= SEQUENCE { - ASN1 contentInfo = new ASN1 (0x30); - // contentType ContentType, -> ContentType ::= OBJECT IDENTIFIER - contentInfo.Add (ASN1Convert.FromOid (contentType)); - // content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL - if ((content != null) && (content.Count > 0)) - contentInfo.Add (content); - return contentInfo; - } - - public byte[] GetBytes () - { - return GetASN1 ().GetBytes (); - } - } - - /* - * EncryptedData ::= SEQUENCE { - * version INTEGER {edVer0(0)} (edVer0), - * encryptedContentInfo EncryptedContentInfo - * } - */ - public class EncryptedData { - private byte _version; - private ContentInfo _content; - private ContentInfo _encryptionAlgorithm; - private byte[] _encrypted; - - public EncryptedData () - { - _version = 0; - } - - public EncryptedData (byte[] data) - : this (new ASN1 (data)) - { - } - - public EncryptedData (ASN1 asn1) : this () - { - if ((asn1.Tag != 0x30) || (asn1.Count < 2)) - throw new ArgumentException ("Invalid EncryptedData"); - - if (asn1 [0].Tag != 0x02) - throw new ArgumentException ("Invalid version"); - _version = asn1 [0].Value [0]; - - ASN1 encryptedContentInfo = asn1 [1]; - if (encryptedContentInfo.Tag != 0x30) - throw new ArgumentException ("missing EncryptedContentInfo"); - - ASN1 contentType = encryptedContentInfo [0]; - if (contentType.Tag != 0x06) - throw new ArgumentException ("missing EncryptedContentInfo.ContentType"); - _content = new ContentInfo (ASN1Convert.ToOid (contentType)); - - ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1]; - if (contentEncryptionAlgorithm.Tag != 0x30) - throw new ArgumentException ("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier"); - _encryptionAlgorithm = new ContentInfo (ASN1Convert.ToOid (contentEncryptionAlgorithm [0])); - _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1]; - - ASN1 encryptedContent = encryptedContentInfo [2]; - if (encryptedContent.Tag != 0x80) - throw new ArgumentException ("missing EncryptedContentInfo.EncryptedContent"); - _encrypted = encryptedContent.Value; - } - - public ASN1 ASN1 { - get { return GetASN1(); } - } - - public ContentInfo ContentInfo { - get { return _content; } - } - - public ContentInfo EncryptionAlgorithm { - get { return _encryptionAlgorithm; } - } - - public byte[] EncryptedContent { - get { - if (_encrypted == null) - return null; - return (byte[]) _encrypted.Clone (); - } - } - - public byte Version { - get { return _version; } - set { _version = value; } - } - - // methods - - internal ASN1 GetASN1 () - { - return null; - } - - public byte[] GetBytes () - { - return GetASN1 ().GetBytes (); - } - } - - /* - * EnvelopedData ::= SEQUENCE { - * version Version, - * recipientInfos RecipientInfos, - * encryptedContentInfo EncryptedContentInfo - * } - * - * RecipientInfos ::= SET OF RecipientInfo - * - * EncryptedContentInfo ::= SEQUENCE { - * contentType ContentType, - * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, - * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL - * } - * - * EncryptedContent ::= OCTET STRING - * - */ - public class EnvelopedData { - private byte _version; - private ContentInfo _content; - private ContentInfo _encryptionAlgorithm; - private ArrayList _recipientInfos; - private byte[] _encrypted; - - public EnvelopedData () - { - _version = 0; - _content = new ContentInfo (); - _encryptionAlgorithm = new ContentInfo (); - _recipientInfos = new ArrayList (); - } - - public EnvelopedData (byte[] data) - : this (new ASN1 (data)) - { - } - - public EnvelopedData (ASN1 asn1) : this () - { - if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 3)) - throw new ArgumentException ("Invalid EnvelopedData"); - - if (asn1[0][0].Tag != 0x02) - throw new ArgumentException ("Invalid version"); - _version = asn1[0][0].Value[0]; - - // recipientInfos - - ASN1 recipientInfos = asn1 [0][1]; - if (recipientInfos.Tag != 0x31) - throw new ArgumentException ("missing RecipientInfos"); - for (int i=0; i < recipientInfos.Count; i++) { - ASN1 recipientInfo = recipientInfos [i]; - _recipientInfos.Add (new RecipientInfo (recipientInfo)); - } - - ASN1 encryptedContentInfo = asn1[0][2]; - if (encryptedContentInfo.Tag != 0x30) - throw new ArgumentException ("missing EncryptedContentInfo"); - - ASN1 contentType = encryptedContentInfo [0]; - if (contentType.Tag != 0x06) - throw new ArgumentException ("missing EncryptedContentInfo.ContentType"); - _content = new ContentInfo (ASN1Convert.ToOid (contentType)); - - ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1]; - if (contentEncryptionAlgorithm.Tag != 0x30) - throw new ArgumentException ("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier"); - _encryptionAlgorithm = new ContentInfo (ASN1Convert.ToOid (contentEncryptionAlgorithm [0])); - _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1]; - - ASN1 encryptedContent = encryptedContentInfo [2]; - if (encryptedContent.Tag != 0x80) - throw new ArgumentException ("missing EncryptedContentInfo.EncryptedContent"); - _encrypted = encryptedContent.Value; - } - - public ArrayList RecipientInfos { - get { return _recipientInfos; } - } - - public ASN1 ASN1 { - get { return GetASN1(); } - } - - public ContentInfo ContentInfo { - get { return _content; } - } - - public ContentInfo EncryptionAlgorithm { - get { return _encryptionAlgorithm; } - } - - public byte[] EncryptedContent { - get { - if (_encrypted == null) - return null; - return (byte[]) _encrypted.Clone (); - } - } - - public byte Version { - get { return _version; } - set { _version = value; } - } - - internal ASN1 GetASN1 () - { - // SignedData ::= SEQUENCE { - ASN1 signedData = new ASN1 (0x30); - // version Version -> Version ::= INTEGER -/* byte[] ver = { _version }; - signedData.Add (new ASN1 (0x02, ver)); - // digestAlgorithms DigestAlgorithmIdentifiers -> DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier - ASN1 digestAlgorithms = signedData.Add (new ASN1 (0x31)); - if (hashAlgorithm != null) { - string hashOid = CryptoConfig.MapNameToOid (hashAlgorithm); - digestAlgorithms.Add (AlgorithmIdentifier (hashOid)); - } - - // contentInfo ContentInfo, - ASN1 ci = contentInfo.ASN1; - signedData.Add (ci); - if ((mda == null) && (hashAlgorithm != null)) { - // automatically add the messageDigest authenticated attribute - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - byte[] idcHash = ha.ComputeHash (ci[1][0].Value); - ASN1 md = new ASN1 (0x30); - mda = Attribute (messageDigest, md.Add (new ASN1 (0x04, idcHash))); - signerInfo.AuthenticatedAttributes.Add (mda); - } - - // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, - if (certs.Count > 0) { - ASN1 a0 = signedData.Add (new ASN1 (0xA0)); - foreach (X509Certificate x in certs) - a0.Add (new ASN1 (x.RawData)); - } - // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, - if (crls.Count > 0) { - ASN1 a1 = signedData.Add (new ASN1 (0xA1)); - foreach (byte[] crl in crls) - a1.Add (new ASN1 (crl)); - } - // signerInfos SignerInfos -> SignerInfos ::= SET OF SignerInfo - ASN1 signerInfos = signedData.Add (new ASN1 (0x31)); - if (signerInfo.Key != null) - signerInfos.Add (signerInfo.ASN1);*/ - return signedData; - } - - public byte[] GetBytes () { - return GetASN1 ().GetBytes (); - } - } - - /* RecipientInfo ::= SEQUENCE { - * version Version, - * issuerAndSerialNumber IssuerAndSerialNumber, - * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - * encryptedKey EncryptedKey - * } - * - * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedKey ::= OCTET STRING - */ - public class RecipientInfo { - - private int _version; - private string _oid; - private byte[] _key; - private byte[] _ski; - private string _issuer; - private byte[] _serial; - - public RecipientInfo () {} - - public RecipientInfo (ASN1 data) - { - if (data.Tag != 0x30) - throw new ArgumentException ("Invalid RecipientInfo"); - - ASN1 version = data [0]; - if (version.Tag != 0x02) - throw new ArgumentException ("missing Version"); - _version = version.Value [0]; - - // issuerAndSerialNumber IssuerAndSerialNumber - ASN1 subjectIdentifierType = data [1]; - if ((subjectIdentifierType.Tag == 0x80) && (_version == 3)) { - _ski = subjectIdentifierType.Value; - } - else { - _issuer = X501.ToString (subjectIdentifierType [0]); - _serial = subjectIdentifierType [1].Value; - } - - ASN1 keyEncryptionAlgorithm = data [2]; - _oid = ASN1Convert.ToOid (keyEncryptionAlgorithm [0]); - - ASN1 encryptedKey = data [3]; - _key = encryptedKey.Value; - } - - public string Oid { - get { return _oid; } - } - - public byte[] Key { - get { - if (_key == null) - return null; - return (byte[]) _key.Clone (); - } - } - - public byte[] SubjectKeyIdentifier { - get { - if (_ski == null) - return null; - return (byte[]) _ski.Clone (); - } - } - - public string Issuer { - get { return _issuer; } - } - - public byte[] Serial { - get { - if (_serial == null) - return null; - return (byte[]) _serial.Clone (); - } - } - - public int Version { - get { return _version; } - } - } - - /* - * SignedData ::= SEQUENCE { - * version Version, - * digestAlgorithms DigestAlgorithmIdentifiers, - * contentInfo ContentInfo, - * certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, - * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, - * signerInfos SignerInfos - * } - */ - public class SignedData { - private byte version; - private string hashAlgorithm; - private ContentInfo contentInfo; - private X509CertificateCollection certs; - private ArrayList crls; - private SignerInfo signerInfo; - private bool mda; - private bool signed; - - public SignedData () - { - version = 1; - contentInfo = new ContentInfo (); - certs = new X509CertificateCollection (); - crls = new ArrayList (); - signerInfo = new SignerInfo (); - mda = true; - signed = false; - } - - public SignedData (byte[] data) - : this (new ASN1 (data)) - { - } - - public SignedData (ASN1 asn1) - { - if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 4)) - throw new ArgumentException ("Invalid SignedData"); - - if (asn1[0][0].Tag != 0x02) - throw new ArgumentException ("Invalid version"); - version = asn1[0][0].Value[0]; - - contentInfo = new ContentInfo (asn1[0][2]); - - int n = 3; - certs = new X509CertificateCollection (); - if (asn1[0][n].Tag == 0xA0) { - for (int i=0; i < asn1[0][n].Count; i++) - certs.Add (new X509Certificate (asn1[0][n][i].GetBytes ())); - n++; - } - - crls = new ArrayList (); - if (asn1[0][n].Tag == 0xA1) { - for (int i=0; i < asn1[0][n].Count; i++) - crls.Add (asn1[0][n][i].GetBytes ()); - n++; - } - - if (asn1[0][n].Count > 0) - signerInfo = new SignerInfo (asn1[0][n]); - else - signerInfo = new SignerInfo (); - - // Exchange hash algorithm Oid from SignerInfo - if (signerInfo.HashName != null) { - HashName = OidToName(signerInfo.HashName); - } - - // Check if SignerInfo has authenticated attributes - mda = (signerInfo.AuthenticatedAttributes.Count > 0); - } - - public ASN1 ASN1 { - get { return GetASN1(); } - } - - public X509CertificateCollection Certificates { - get { return certs; } - } - - public ContentInfo ContentInfo { - get { return contentInfo; } - } - - public ArrayList Crls { - get { return crls; } - } - - public string HashName { - get { return hashAlgorithm; } - // todo add validation - set { - hashAlgorithm = value; - signerInfo.HashName = value; - } - } - - public SignerInfo SignerInfo { - get { return signerInfo; } - } - - public byte Version { - get { return version; } - set { version = value; } - } - - public bool UseAuthenticatedAttributes { - get { return mda; } - set { mda = value; } - } - - public bool VerifySignature (AsymmetricAlgorithm aa) - { - if (aa == null) { - return false; - } - - RSAPKCS1SignatureDeformatter r = new RSAPKCS1SignatureDeformatter (aa); - r.SetHashAlgorithm (hashAlgorithm); - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - - byte[] signature = signerInfo.Signature; - byte[] hash = null; - - if (mda) { - ASN1 asn = new ASN1 (0x31); - foreach (ASN1 attr in signerInfo.AuthenticatedAttributes) - asn.Add (attr); - - hash = ha.ComputeHash (asn.GetBytes ()); - } else { - hash = ha.ComputeHash (contentInfo.Content[0].Value); - } - - if (hash != null && signature != null) { - return r.VerifySignature (hash, signature); - } - return false; - } - - internal string OidToName (string oid) - { - switch (oid) { - case "1.3.14.3.2.26" : - return "SHA1"; - case "1.2.840.113549.2.2" : - return "MD2"; - case "1.2.840.113549.2.5" : - return "MD5"; - case "2.16.840.1.101.3.4.1" : - return "SHA256"; - case "2.16.840.1.101.3.4.2" : - return "SHA384"; - case "2.16.840.1.101.3.4.3" : - return "SHA512"; - default : - break; - } - // Unknown Oid - return oid; - } - - internal ASN1 GetASN1 () - { - // SignedData ::= SEQUENCE { - ASN1 signedData = new ASN1 (0x30); - // version Version -> Version ::= INTEGER - byte[] ver = { version }; - signedData.Add (new ASN1 (0x02, ver)); - // digestAlgorithms DigestAlgorithmIdentifiers -> DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier - ASN1 digestAlgorithms = signedData.Add (new ASN1 (0x31)); - if (hashAlgorithm != null) { - string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm); - digestAlgorithms.Add (AlgorithmIdentifier (hashOid)); - } - - // contentInfo ContentInfo, - ASN1 ci = contentInfo.ASN1; - signedData.Add (ci); - if (!signed && (hashAlgorithm != null)) { - if (mda) { - // Use authenticated attributes for signature - - // Automatically add the contentType authenticated attribute - ASN1 ctattr = Attribute (Oid.contentType, ci[0]); - signerInfo.AuthenticatedAttributes.Add (ctattr); - - // Automatically add the messageDigest authenticated attribute - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - byte[] idcHash = ha.ComputeHash (ci[1][0].Value); - ASN1 md = new ASN1 (0x30); - ASN1 mdattr = Attribute (Oid.messageDigest, md.Add (new ASN1 (0x04, idcHash))); - signerInfo.AuthenticatedAttributes.Add (mdattr); - } else { - // Don't use authenticated attributes for signature -- signature is content - RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (signerInfo.Key); - r.SetHashAlgorithm (hashAlgorithm); - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - byte[] sig = ha.ComputeHash (ci[1][0].Value); - signerInfo.Signature = r.CreateSignature (sig); - } - signed = true; - } - - // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, - if (certs.Count > 0) { - ASN1 a0 = signedData.Add (new ASN1 (0xA0)); - foreach (X509Certificate x in certs) - a0.Add (new ASN1 (x.RawData)); - } - // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, - if (crls.Count > 0) { - ASN1 a1 = signedData.Add (new ASN1 (0xA1)); - foreach (byte[] crl in crls) - a1.Add (new ASN1 (crl)); - } - // signerInfos SignerInfos -> SignerInfos ::= SET OF SignerInfo - ASN1 signerInfos = signedData.Add (new ASN1 (0x31)); - if (signerInfo.Key != null) - signerInfos.Add (signerInfo.ASN1); - return signedData; - } - - public byte[] GetBytes () - { - return GetASN1 ().GetBytes (); - } - } - - /* - * SignerInfo ::= SEQUENCE { - * version Version, - * issuerAndSerialNumber IssuerAndSerialNumber, - * digestAlgorithm DigestAlgorithmIdentifier, - * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, - * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, - * encryptedDigest EncryptedDigest, - * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL - * } - * - * For version == 3 issuerAndSerialNumber may be replaced by ... - */ - public class SignerInfo { - - private byte version; - private X509Certificate x509; - private string hashAlgorithm; - private AsymmetricAlgorithm key; - private ArrayList authenticatedAttributes; - private ArrayList unauthenticatedAttributes; - private byte[] signature; - private string issuer; - private byte[] serial; - private byte[] ski; - - public SignerInfo () - { - version = 1; - authenticatedAttributes = new ArrayList (); - unauthenticatedAttributes = new ArrayList (); - } - - public SignerInfo (byte[] data) - : this (new ASN1 (data)) {} - - // TODO: INCOMPLETE - public SignerInfo (ASN1 asn1) : this () - { - if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 5)) - throw new ArgumentException ("Invalid SignedData"); - - // version Version - if (asn1[0][0].Tag != 0x02) - throw new ArgumentException ("Invalid version"); - version = asn1[0][0].Value[0]; - - // issuerAndSerialNumber IssuerAndSerialNumber - ASN1 subjectIdentifierType = asn1 [0][1]; - if ((subjectIdentifierType.Tag == 0x80) && (version == 3)) { - ski = subjectIdentifierType.Value; - } - else { - issuer = X501.ToString (subjectIdentifierType [0]); - serial = subjectIdentifierType [1].Value; - } - - // digestAlgorithm DigestAlgorithmIdentifier - ASN1 digestAlgorithm = asn1 [0][2]; - hashAlgorithm = ASN1Convert.ToOid (digestAlgorithm [0]); - - // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL - int n = 3; - ASN1 authAttributes = asn1 [0][n]; - if (authAttributes.Tag == 0xA0) { - n++; - for (int i=0; i < authAttributes.Count; i++) - authenticatedAttributes.Add (authAttributes [i]); - } - - // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier - n++; - // ASN1 digestEncryptionAlgorithm = asn1 [0][n++]; - // string digestEncryptionAlgorithmOid = ASN1Convert.ToOid (digestEncryptionAlgorithm [0]); - - // encryptedDigest EncryptedDigest - ASN1 encryptedDigest = asn1 [0][n++]; - if (encryptedDigest.Tag == 0x04) - signature = encryptedDigest.Value; - - // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL - ASN1 unauthAttributes = asn1 [0][n]; - if ((unauthAttributes != null) && (unauthAttributes.Tag == 0xA1)) { - for (int i=0; i < unauthAttributes.Count; i++) - unauthenticatedAttributes.Add (unauthAttributes [i]); - } - } - - public string IssuerName { - get { return issuer; } - } - - public byte[] SerialNumber { - get { - if (serial == null) - return null; - return (byte[]) serial.Clone (); - } - } - - public byte[] SubjectKeyIdentifier { - get { - if (ski == null) - return null; - return (byte[]) ski.Clone (); - } - } - - public ASN1 ASN1 { - get { return GetASN1(); } - } - - public ArrayList AuthenticatedAttributes { - get { return authenticatedAttributes; } - } - - public X509Certificate Certificate { - get { return x509; } - set { x509 = value; } - } - - public string HashName { - get { return hashAlgorithm; } - set { hashAlgorithm = value; } - } - - public AsymmetricAlgorithm Key { - get { return key; } - set { key = value; } - } - - public byte[] Signature { - get { - if (signature == null) - return null; - return (byte[]) signature.Clone (); - } - - set { - if (value != null) { - signature = (byte[]) value.Clone (); - } - } - } - - public ArrayList UnauthenticatedAttributes { - get { return unauthenticatedAttributes; } - } - - public byte Version { - get { return version; } - set { version = value; } - } - - internal ASN1 GetASN1 () - { - if ((key == null) || (hashAlgorithm == null)) - return null; - byte[] ver = { version }; - ASN1 signerInfo = new ASN1 (0x30); - // version Version -> Version ::= INTEGER - signerInfo.Add (new ASN1 (0x02, ver)); - // issuerAndSerialNumber IssuerAndSerialNumber, - signerInfo.Add (PKCS7.IssuerAndSerialNumber (x509)); - // digestAlgorithm DigestAlgorithmIdentifier, - string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm); - signerInfo.Add (AlgorithmIdentifier (hashOid)); - // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, - ASN1 aa = null; - if (authenticatedAttributes.Count > 0) { - aa = signerInfo.Add (new ASN1 (0xA0)); - foreach (ASN1 attr in authenticatedAttributes) - aa.Add (attr); - } - // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, - if (key is RSA) { - signerInfo.Add (AlgorithmIdentifier (PKCS7.Oid.rsaEncryption)); - - if (aa != null) { - // Calculate the signature here; otherwise it must be set from SignedData - RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (key); - r.SetHashAlgorithm (hashAlgorithm); - byte[] tbs = aa.GetBytes (); - tbs [0] = 0x31; // not 0xA0 for signature - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - byte[] tbsHash = ha.ComputeHash (tbs); - signature = r.CreateSignature (tbsHash); - } - } - else if (key is DSA) { - throw new NotImplementedException ("not yet"); - } - else - throw new CryptographicException ("Unknown assymetric algorithm"); - // encryptedDigest EncryptedDigest, - signerInfo.Add (new ASN1 (0x04, signature)); - // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL - if (unauthenticatedAttributes.Count > 0) { - ASN1 ua = signerInfo.Add (new ASN1 (0xA1)); - foreach (ASN1 attr in unauthenticatedAttributes) - ua.Add (attr); - } - return signerInfo; - } - - public byte[] GetBytes () - { - return GetASN1 ().GetBytes (); - } - } - } -} diff --git a/mcs/class/corlib/Mono.Security/StrongName.cs b/mcs/class/corlib/Mono.Security/StrongName.cs deleted file mode 100644 index 4c6aaeeb3f9..00000000000 --- a/mcs/class/corlib/Mono.Security/StrongName.cs +++ /dev/null @@ -1,546 +0,0 @@ -// -// StrongName.cs - Strong Name Implementation -// -// Author: -// Sebastien Pouliot (sebastien@ximian.com) -// -// (C) 2003 Motus Technologies Inc. (http://www.motus.com) -// (C) 2004 Novell (http://www.novell.com) -// - -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Configuration.Assemblies; -using System.Globalization; -using System.IO; -using System.Reflection; -using System.Security.Cryptography; - -using Mono.Security.Cryptography; - -namespace Mono.Security { - -#if INSIDE_CORLIB - internal -#else - public -#endif - sealed class StrongName { - - internal class StrongNameSignature { - private byte[] hash; - private byte[] signature; - private UInt32 signaturePosition; - private UInt32 signatureLength; - private UInt32 metadataPosition; - private UInt32 metadataLength; - private byte cliFlag; - private UInt32 cliFlagPosition; - - public byte[] Hash { - get { return hash; } - set { hash = value; } - } - - public byte[] Signature { - get { return signature; } - set { signature = value; } - } - - public UInt32 MetadataPosition { - get { return metadataPosition; } - set { metadataPosition = value; } - } - - public UInt32 MetadataLength { - get { return metadataLength; } - set { metadataLength = value; } - } - - public UInt32 SignaturePosition { - get { return signaturePosition; } - set { signaturePosition = value; } - } - - public UInt32 SignatureLength { - get { return signatureLength; } - set { signatureLength = value; } - } - - // delay signed -> flag = 0x01 - // strongsigned -> flag = 0x09 - public byte CliFlag { - get { return cliFlag; } - set { cliFlag = value; } - } - - public UInt32 CliFlagPosition { - get { return cliFlagPosition; } - set { cliFlagPosition = value; } - } - } - - internal enum StrongNameOptions { - Metadata, - Signature - } - - private RSA rsa; - private byte[] publicKey; - private byte[] keyToken; - private string tokenAlgorithm; - - public StrongName () - { - } - - public StrongName (int keySize) - { - rsa = new RSAManaged (keySize); - } - - public StrongName (byte[] data) - { - if (data == null) - throw new ArgumentNullException ("data"); - - // check for ECMA key - if (data.Length == 16) { - int i = 0; - int sum = 0; - while (i < data.Length) - sum += data [i++]; - if (sum == 4) { - // it is the ECMA key - publicKey = (byte[]) data.Clone (); - } - } - else { - RSA = CryptoConvert.FromCapiKeyBlob (data); - if (rsa == null) - throw new ArgumentException ("data isn't a correctly encoded RSA public key"); - } - } - - public StrongName (RSA rsa) - { - if (rsa == null) - throw new ArgumentNullException ("rsa"); - - RSA = rsa; - } - - private void InvalidateCache () - { - publicKey = null; - keyToken = null; - } - - public bool CanSign { - get { - if (rsa == null) - return false; -#if INSIDE_CORLIB - // the easy way - if (RSA is RSACryptoServiceProvider) { - // available as internal for corlib - return !(rsa as RSACryptoServiceProvider).PublicOnly; - } - else -#endif - if (RSA is RSAManaged) { - return !(rsa as RSAManaged).PublicOnly; - } - else { - // the hard way - try { - RSAParameters p = rsa.ExportParameters (true); - return ((p.D != null) && (p.P != null) && (p.Q != null)); - } - catch (CryptographicException) { - return false; - } - } - } - } - - public RSA RSA { - get { - // if none then we create a new keypair - if (rsa == null) - rsa = (RSA) RSA.Create (); - return rsa; - } - set { - rsa = value; - InvalidateCache (); - } - } - - public byte[] PublicKey { - get { - if (publicKey == null) { - byte[] keyPair = CryptoConvert.ToCapiKeyBlob (rsa, false); - // since 2.0 public keys can vary from 384 to 16384 bits - publicKey = new byte [32 + (rsa.KeySize >> 3)]; - - // The first 12 bytes are documented at: - // http://msdn.microsoft.com/library/en-us/cprefadd/html/grfungethashfromfile.asp - // ALG_ID - Signature - publicKey [0] = keyPair [4]; - publicKey [1] = keyPair [5]; - publicKey [2] = keyPair [6]; - publicKey [3] = keyPair [7]; - // ALG_ID - Hash (SHA1 == 0x8004) - publicKey [4] = 0x04; - publicKey [5] = 0x80; - publicKey [6] = 0x00; - publicKey [7] = 0x00; - // Length of Public Key (in bytes) - byte[] lastPart = BitConverterLE.GetBytes (publicKey.Length - 12); - publicKey [8] = lastPart [0]; - publicKey [9] = lastPart [1]; - publicKey [10] = lastPart [2]; - publicKey [11] = lastPart [3]; - // Ok from here - Same structure as keypair - expect for public key - publicKey [12] = 0x06; // PUBLICKEYBLOB - // we can copy this part - Buffer.BlockCopy (keyPair, 1, publicKey, 13, publicKey.Length - 13); - // and make a small adjustment - publicKey [23] = 0x31; // (RSA1 not RSA2) - } - return (byte[]) publicKey.Clone (); - } - } - - public byte[] PublicKeyToken { - get { - if (keyToken == null) { - byte[] publicKey = PublicKey; - if (publicKey == null) - return null; - HashAlgorithm ha = HashAlgorithm.Create (TokenAlgorithm); - byte[] hash = ha.ComputeHash (publicKey); - // we need the last 8 bytes in reverse order - keyToken = new byte [8]; - Buffer.BlockCopy (hash, (hash.Length - 8), keyToken, 0, 8); - Array.Reverse (keyToken, 0, 8); - } - return (byte[]) keyToken.Clone (); - } - } - - public string TokenAlgorithm { - get { - if (tokenAlgorithm == null) - tokenAlgorithm = "SHA1"; - return tokenAlgorithm; - } - set { - string algo = value.ToUpper (CultureInfo.InvariantCulture); - if ((algo == "SHA1") || (algo == "MD5")) { - tokenAlgorithm = value; - InvalidateCache (); - } - else - throw new ArgumentException ("Unsupported hash algorithm for token"); - } - } - - public byte[] GetBytes () - { - return CryptoConvert.ToCapiPrivateKeyBlob (RSA); - } - - private UInt32 RVAtoPosition (UInt32 r, int sections, byte[] headers) - { - for (int i=0; i < sections; i++) { - UInt32 p = BitConverterLE.ToUInt32 (headers, i * 40 + 20); - UInt32 s = BitConverterLE.ToUInt32 (headers, i * 40 + 12); - int l = (int) BitConverterLE.ToUInt32 (headers, i * 40 + 8); - if ((s <= r) && (r < s + l)) { - return p + r - s; - } - } - return 0; - } - - internal StrongNameSignature StrongHash (Stream stream, StrongNameOptions options) - { - StrongNameSignature info = new StrongNameSignature (); - - HashAlgorithm hash = HashAlgorithm.Create (TokenAlgorithm); - CryptoStream cs = new CryptoStream (Stream.Null, hash, CryptoStreamMode.Write); - - // MS-DOS Header - always 128 bytes - // ref: Section 24.2.1, Partition II Metadata - byte[] mz = new byte [128]; - stream.Read (mz, 0, 128); - if (BitConverterLE.ToUInt16 (mz, 0) != 0x5a4d) - return null; - UInt32 peHeader = BitConverterLE.ToUInt32 (mz, 60); - cs.Write (mz, 0, 128); - if (peHeader != 128) { - byte[] mzextra = new byte [peHeader - 128]; - stream.Read (mzextra, 0, mzextra.Length); - cs.Write (mzextra, 0, mzextra.Length); - } - - // PE File Header - always 248 bytes - // ref: Section 24.2.2, Partition II Metadata - byte[] pe = new byte [248]; - stream.Read (pe, 0, 248); - if (BitConverterLE.ToUInt32 (pe, 0) != 0x4550) - return null; - if (BitConverterLE.ToUInt16 (pe, 4) != 0x14c) - return null; - // MUST zeroize both CheckSum and Security Directory - byte[] v = new byte [8]; - Buffer.BlockCopy (v, 0, pe, 88, 4); - Buffer.BlockCopy (v, 0, pe, 152, 8); - cs.Write (pe, 0, 248); - - UInt16 numSection = BitConverterLE.ToUInt16 (pe, 6); - int sectionLength = (numSection * 40); - byte[] sectionHeaders = new byte [sectionLength]; - stream.Read (sectionHeaders, 0, sectionLength); - cs.Write (sectionHeaders, 0, sectionLength); - - UInt32 cliHeaderRVA = BitConverterLE.ToUInt32 (pe, 232); - UInt32 cliHeaderPos = RVAtoPosition (cliHeaderRVA, numSection, sectionHeaders); - int cliHeaderSiz = (int) BitConverterLE.ToUInt32 (pe, 236); - - // CLI Header - // ref: Section 24.3.3, Partition II Metadata - byte[] cli = new byte [cliHeaderSiz]; - stream.Position = cliHeaderPos; - stream.Read (cli, 0, cliHeaderSiz); - - UInt32 strongNameSignatureRVA = BitConverterLE.ToUInt32 (cli, 32); - info.SignaturePosition = RVAtoPosition (strongNameSignatureRVA, numSection, sectionHeaders); - info.SignatureLength = BitConverterLE.ToUInt32 (cli, 36); - - UInt32 metadataRVA = BitConverterLE.ToUInt32 (cli, 8); - info.MetadataPosition = RVAtoPosition (metadataRVA, numSection, sectionHeaders); - info.MetadataLength = BitConverterLE.ToUInt32 (cli, 12); - - if (options == StrongNameOptions.Metadata) { - cs.Close (); - hash.Initialize (); - byte[] metadata = new byte [info.MetadataLength]; - stream.Position = info.MetadataPosition; - stream.Read (metadata, 0, metadata.Length); - info.Hash = hash.ComputeHash (metadata); - return info; - } - - // now we hash every section EXCEPT the signature block - for (int i=0; i < numSection; i++) { - UInt32 start = BitConverterLE.ToUInt32 (sectionHeaders, i * 40 + 20); - int length = (int) BitConverterLE.ToUInt32 (sectionHeaders, i * 40 + 16); - byte[] section = new byte [length]; - stream.Position = start; - stream.Read (section, 0, length); - if ((start <= info.SignaturePosition) && (info.SignaturePosition < start + length)) { - // hash before the signature - int before = (int)(info.SignaturePosition - start); - if (before > 0) { - cs.Write (section, 0, before); - } - // copy signature - info.Signature = new byte [info.SignatureLength]; - Buffer.BlockCopy (section, before, info.Signature, 0, (int)info.SignatureLength); - Array.Reverse (info.Signature); - // hash after the signature - int s = (int)(before + info.SignatureLength); - int after = (int)(length - s); - if (after > 0) { - cs.Write (section, s, after); - } - } - else - cs.Write (section, 0, length); - } - - cs.Close (); - info.Hash = hash.Hash; - return info; - } - - // return the same result as the undocumented and unmanaged GetHashFromAssemblyFile - public byte[] Hash (string fileName) - { - FileStream fs = File.OpenRead (fileName); - StrongNameSignature sn = StrongHash (fs, StrongNameOptions.Metadata); - fs.Close (); - - return sn.Hash; - } - - public bool Sign (string fileName) - { - bool result = false; - StrongNameSignature sn; - using (FileStream fs = File.OpenRead (fileName)) { - sn = StrongHash (fs, StrongNameOptions.Signature); - fs.Close (); - } - if (sn.Hash == null) - return false; - - byte[] signature = null; - try { - RSAPKCS1SignatureFormatter sign = new RSAPKCS1SignatureFormatter (rsa); - sign.SetHashAlgorithm (TokenAlgorithm); - signature = sign.CreateSignature (sn.Hash); - Array.Reverse (signature); - } - catch (CryptographicException) { - return false; - } - - using (FileStream fs = File.OpenWrite (fileName)) { - fs.Position = sn.SignaturePosition; - fs.Write (signature, 0, signature.Length); - fs.Close (); - result = true; - } - return result; - } - - public bool Verify (string fileName) - { - bool result = false; - using (FileStream fs = File.OpenRead (fileName)) { - result = Verify (fs); - fs.Close (); - } - return result; - } - - public bool Verify (Stream stream) - { - StrongNameSignature sn = StrongHash (stream, StrongNameOptions.Signature); - if (sn.Hash == null) { - return false; - } - - try { - AssemblyHashAlgorithm algorithm = AssemblyHashAlgorithm.SHA1; - if (tokenAlgorithm == "MD5") - algorithm = AssemblyHashAlgorithm.MD5; - return Verify (rsa, algorithm, sn.Hash, sn.Signature); - } - catch (CryptographicException) { - // no exception allowed - return false; - } - } - -#if INSIDE_CORLIB - static object lockObject = new object (); - static bool initialized; - - // We don't want a dependency on StrongNameManager in Mono.Security.dll - static public bool IsAssemblyStrongnamed (string assemblyName) - { - if (!initialized) { - lock (lockObject) { - if (!initialized) { -#if NET_2_1 - // Moonlight cannot depend on machine.config -#else - string config = Environment.GetMachineConfigPath (); - StrongNameManager.LoadConfig (config); -#endif - initialized = true; - } - } - } - - try { - // this doesn't load the assembly (well it unloads it ;) - // http://weblogs.asp.net/nunitaddin/posts/9991.aspx - AssemblyName an = AssemblyName.GetAssemblyName (assemblyName); - if (an == null) - return false; - - byte[] publicKey = StrongNameManager.GetMappedPublicKey (an.GetPublicKeyToken ()); - if ((publicKey == null) || (publicKey.Length < 12)) { - // no mapping - publicKey = an.GetPublicKey (); - if ((publicKey == null) || (publicKey.Length < 12)) - return false; - } - - // Note: MustVerify is based on the original token (by design). Public key - // remapping won't affect if the assembly is verified or not. - if (!StrongNameManager.MustVerify (an)) { - return true; - } - - RSA rsa = CryptoConvert.FromCapiPublicKeyBlob (publicKey, 12); - StrongName sn = new StrongName (rsa); - bool result = sn.Verify (assemblyName); - return result; - } - catch { - // no exception allowed - return false; - } - } - - // TODO - // we would get better performance if the runtime hashed the - // assembly - as we wouldn't have to load it from disk a - // second time. The runtime already have implementations of - // SHA1 (and even MD5 if required someday). - static public bool VerifySignature (byte[] publicKey, int algorithm, byte[] hash, byte[] signature) - { - try { - RSA rsa = CryptoConvert.FromCapiPublicKeyBlob (publicKey); - return Verify (rsa, (AssemblyHashAlgorithm) algorithm, hash, signature); - } - catch { - // no exception allowed - return false; - } - } -#endif - static private bool Verify (RSA rsa, AssemblyHashAlgorithm algorithm, byte[] hash, byte[] signature) - { - RSAPKCS1SignatureDeformatter vrfy = new RSAPKCS1SignatureDeformatter (rsa); - switch (algorithm) { - case AssemblyHashAlgorithm.MD5: - vrfy.SetHashAlgorithm ("MD5"); - break; - case AssemblyHashAlgorithm.SHA1: - case AssemblyHashAlgorithm.None: - default: - vrfy.SetHashAlgorithm ("SHA1"); - break; - } - return vrfy.VerifySignature (hash, signature); - } - } -} -- 2.11.4.GIT