BouncyCastle update.

git-svn-id: svn://svn.code.sf.net/p/itextsharp/code/trunk@45 820d3149-562b-4f88-9aa4-a8e61a3485cf
master
psoares33 2009-07-01 15:07:44 +00:00
parent 1737ad65dd
commit 1ea1146eb1
14 changed files with 8317 additions and 8279 deletions

View File

@ -1,130 +1,130 @@
using System; using System;
using System.Collections; using System.Collections;
using System.IO; using System.IO;
using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math; using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Asn1.Pkcs namespace Org.BouncyCastle.Asn1.Pkcs
{ {
public class PrivateKeyInfo public class PrivateKeyInfo
: Asn1Encodable : Asn1Encodable
{ {
private readonly Asn1Object privKey; private readonly Asn1Object privKey;
private readonly AlgorithmIdentifier algID; private readonly AlgorithmIdentifier algID;
private readonly Asn1Set attributes; private readonly Asn1Set attributes;
public static PrivateKeyInfo GetInstance( public static PrivateKeyInfo GetInstance(
object obj) object obj)
{ {
if (obj is PrivateKeyInfo || obj == null) if (obj is PrivateKeyInfo || obj == null)
{ {
return (PrivateKeyInfo) obj; return (PrivateKeyInfo) obj;
} }
if (obj is Asn1Sequence) if (obj is Asn1Sequence)
{ {
return new PrivateKeyInfo((Asn1Sequence) obj); return new PrivateKeyInfo((Asn1Sequence) obj);
} }
throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj"); throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
} }
public PrivateKeyInfo( public PrivateKeyInfo(
AlgorithmIdentifier algID, AlgorithmIdentifier algID,
Asn1Object privateKey) Asn1Object privateKey)
: this(algID, privateKey, null) : this(algID, privateKey, null)
{ {
} }
public PrivateKeyInfo( public PrivateKeyInfo(
AlgorithmIdentifier algID, AlgorithmIdentifier algID,
Asn1Object privateKey, Asn1Object privateKey,
Asn1Set attributes) Asn1Set attributes)
{ {
this.privKey = privateKey; this.privKey = privateKey;
this.algID = algID; this.algID = algID;
this.attributes = attributes; this.attributes = attributes;
} }
private PrivateKeyInfo( private PrivateKeyInfo(
Asn1Sequence seq) Asn1Sequence seq)
{ {
IEnumerator e = seq.GetEnumerator(); IEnumerator e = seq.GetEnumerator();
e.MoveNext(); e.MoveNext();
BigInteger version = ((DerInteger) e.Current).Value; BigInteger version = ((DerInteger) e.Current).Value;
if (version.IntValue != 0) if (version.IntValue != 0)
{ {
throw new ArgumentException("wrong version for private key info"); throw new ArgumentException("wrong version for private key info");
} }
e.MoveNext(); e.MoveNext();
algID = AlgorithmIdentifier.GetInstance(e.Current); algID = AlgorithmIdentifier.GetInstance(e.Current);
try try
{ {
e.MoveNext(); e.MoveNext();
Asn1OctetString data = (Asn1OctetString) e.Current; Asn1OctetString data = (Asn1OctetString) e.Current;
privKey = Asn1Object.FromByteArray(data.GetOctets()); privKey = Asn1Object.FromByteArray(data.GetOctets());
} }
catch (IOException) catch (IOException)
{ {
throw new ArgumentException("Error recoverying private key from sequence"); throw new ArgumentException("Error recoverying private key from sequence");
} }
if (e.MoveNext()) if (e.MoveNext())
{ {
attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false); attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false);
} }
} }
public AlgorithmIdentifier AlgorithmID public AlgorithmIdentifier AlgorithmID
{ {
get { return algID; } get { return algID; }
} }
public Asn1Object PrivateKey public Asn1Object PrivateKey
{ {
get { return privKey; } get { return privKey; }
} }
public Asn1Set Attributes public Asn1Set Attributes
{ {
get { return attributes; } get { return attributes; }
} }
/** /**
* write out an RSA private key with it's asscociated information * write out an RSA private key with its associated information
* as described in Pkcs8. * as described in Pkcs8.
* <pre> * <pre>
* PrivateKeyInfo ::= Sequence { * PrivateKeyInfo ::= Sequence {
* version Version, * version Version,
* privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}}, * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
* privateKey PrivateKey, * privateKey PrivateKey,
* attributes [0] IMPLICIT Attributes OPTIONAL * attributes [0] IMPLICIT Attributes OPTIONAL
* } * }
* Version ::= Integer {v1(0)} (v1,...) * Version ::= Integer {v1(0)} (v1,...)
* *
* PrivateKey ::= OCTET STRING * PrivateKey ::= OCTET STRING
* *
* Attributes ::= Set OF Attr * Attributes ::= Set OF Attr
* </pre> * </pre>
*/ */
public override Asn1Object ToAsn1Object() public override Asn1Object ToAsn1Object()
{ {
Asn1EncodableVector v = new Asn1EncodableVector( Asn1EncodableVector v = new Asn1EncodableVector(
new DerInteger(0), new DerInteger(0),
algID, algID,
new DerOctetString(privKey)); new DerOctetString(privKey));
if (attributes != null) if (attributes != null)
{ {
v.Add(new DerTaggedObject(false, 0, attributes)); v.Add(new DerTaggedObject(false, 0, attributes));
} }
return new DerSequence(v); return new DerSequence(v);
} }
} }
} }

View File

@ -1,106 +1,110 @@
using System; using System;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math; using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Modes namespace Org.BouncyCastle.Crypto.Modes
{ {
/** /**
* Implements the Segmented Integer Counter (SIC) mode on top of a simple * Implements the Segmented Integer Counter (SIC) mode on top of a simple
* block cipher. * block cipher.
*/ */
public class SicBlockCipher public class SicBlockCipher
: IBlockCipher : IBlockCipher
{ {
private readonly IBlockCipher cipher; private readonly IBlockCipher cipher;
private readonly int blockSize; private readonly int blockSize;
private readonly byte[] IV; private readonly byte[] IV;
private readonly byte[] counter; private readonly byte[] counter;
private readonly byte[] counterOut; private readonly byte[] counterOut;
/** /**
* Basic constructor. * Basic constructor.
* *
* @param c the block cipher to be used. * @param c the block cipher to be used.
*/ */
public SicBlockCipher(IBlockCipher cipher) public SicBlockCipher(IBlockCipher cipher)
{ {
this.cipher = cipher; this.cipher = cipher;
this.blockSize = cipher.GetBlockSize(); this.blockSize = cipher.GetBlockSize();
this.IV = new byte[blockSize]; this.IV = new byte[blockSize];
this.counter = new byte[blockSize]; this.counter = new byte[blockSize];
this.counterOut = new byte[blockSize]; this.counterOut = new byte[blockSize];
} }
/** /**
* return the underlying block cipher that we are wrapping. * return the underlying block cipher that we are wrapping.
* *
* @return the underlying block cipher that we are wrapping. * @return the underlying block cipher that we are wrapping.
*/ */
public IBlockCipher GetUnderlyingCipher() public IBlockCipher GetUnderlyingCipher()
{ {
return cipher; return cipher;
} }
public void Init( public void Init(
bool forEncryption, //ignored by this CTR mode bool forEncryption, //ignored by this CTR mode
ICipherParameters parameters) ICipherParameters parameters)
{ {
if (parameters is ParametersWithIV) if (parameters is ParametersWithIV)
{ {
ParametersWithIV ivParam = (ParametersWithIV) parameters; ParametersWithIV ivParam = (ParametersWithIV) parameters;
byte[] iv = ivParam.GetIV(); byte[] iv = ivParam.GetIV();
Array.Copy(iv, 0, IV, 0, IV.Length); Array.Copy(iv, 0, IV, 0, IV.Length);
Reset(); Reset();
cipher.Init(true, ivParam.Parameters); cipher.Init(true, ivParam.Parameters);
} }
} else
{
public string AlgorithmName throw new ArgumentException("SIC mode requires ParametersWithIV", "parameters");
{ }
get { return cipher.AlgorithmName + "/SIC"; } }
}
public string AlgorithmName
public bool IsPartialBlockOkay {
{ get { return cipher.AlgorithmName + "/SIC"; }
get { return true; } }
}
public bool IsPartialBlockOkay
public int GetBlockSize() {
{ get { return true; }
return cipher.GetBlockSize(); }
}
public int GetBlockSize()
public int ProcessBlock( {
byte[] input, return cipher.GetBlockSize();
int inOff, }
byte[] output,
int outOff) public int ProcessBlock(
{ byte[] input,
cipher.ProcessBlock(counter, 0, counterOut, 0); int inOff,
byte[] output,
// int outOff)
// XOR the counterOut with the plaintext producing the cipher text {
// cipher.ProcessBlock(counter, 0, counterOut, 0);
for (int i = 0; i < counterOut.Length; i++)
{ //
output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]); // XOR the counterOut with the plaintext producing the cipher text
} //
for (int i = 0; i < counterOut.Length; i++)
// Increment the counter {
int j = counter.Length; output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]);
while (--j >= 0 && ++counter[j] == 0) }
{
} // Increment the counter
int j = counter.Length;
return counter.Length; while (--j >= 0 && ++counter[j] == 0)
} {
}
public void Reset()
{ return counter.Length;
Array.Copy(IV, 0, counter, 0, counter.Length); }
cipher.Reset();
} public void Reset()
} {
} Array.Copy(IV, 0, counter, 0, counter.Length);
cipher.Reset();
}
}
}

View File

@ -1,92 +1,114 @@
using System; using System;
using System.IO; using System.IO;
using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Modes;
namespace Org.BouncyCastle.Crypto.Tls namespace Org.BouncyCastle.Crypto.Tls
{ {
/// <remarks> /// <remarks>
/// A manager for ciphersuite. This class does manage all ciphersuites /// A manager for ciphersuite. This class does manage all ciphersuites
/// which are used by MicroTLS. /// which are used by MicroTLS.
/// </remarks> /// </remarks>
public class TlsCipherSuiteManager public class TlsCipherSuiteManager
{ {
private const int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000a; private const int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000a;
private const int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; private const int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013;
private const int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; private const int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016;
private const int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002f; private const int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002f;
private const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; private const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032;
private const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; private const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033;
private const int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; private const int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035;
private const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; private const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038;
private const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; private const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039;
internal static void WriteCipherSuites( internal static void WriteCipherSuites(
Stream outStr) Stream outStr)
{ {
int[] suites = new int[] int[] suites = new int[]
{ {
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_3DES_EDE_CBC_SHA,
}; };
TlsUtilities.WriteUint16(2 * suites.Length, outStr); TlsUtilities.WriteUint16(2 * suites.Length, outStr);
for (int i = 0; i < suites.Length; ++i) for (int i = 0; i < suites.Length; ++i)
{ {
TlsUtilities.WriteUint16(suites[i], outStr); TlsUtilities.WriteUint16(suites[i], outStr);
} }
} }
internal static TlsCipherSuite GetCipherSuite( internal static TlsCipherSuite GetCipherSuite(
int number, int number,
TlsProtocolHandler handler) TlsProtocolHandler handler)
{ {
switch (number) switch (number)
{ {
case TLS_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new DesEdeEngine()), new CbcBlockCipher(new DesEdeEngine()), new Sha1Digest(), new Sha1Digest(), 24, TlsCipherSuite.KE_RSA); return createDesEdeCipherSuite(24, TlsCipherSuite.KE_RSA);
case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new DesEdeEngine()), new CbcBlockCipher(new DesEdeEngine()), new Sha1Digest(), new Sha1Digest(), 24, TlsCipherSuite.KE_DHE_DSS); return createDesEdeCipherSuite(24, TlsCipherSuite.KE_DHE_DSS);
case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new DesEdeEngine()), new CbcBlockCipher(new DesEdeEngine()), new Sha1Digest(), new Sha1Digest(), 24, TlsCipherSuite.KE_DHE_RSA); return createDesEdeCipherSuite(24, TlsCipherSuite.KE_DHE_RSA);
case TLS_RSA_WITH_AES_128_CBC_SHA: case TLS_RSA_WITH_AES_128_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new AesFastEngine()), new CbcBlockCipher(new AesFastEngine()), new Sha1Digest(), new Sha1Digest(), 16, TlsCipherSuite.KE_RSA); return createAesCipherSuite(16, TlsCipherSuite.KE_RSA);
case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new AesFastEngine()), new CbcBlockCipher(new AesFastEngine()), new Sha1Digest(), new Sha1Digest(), 16, TlsCipherSuite.KE_DHE_DSS); return createAesCipherSuite(16, TlsCipherSuite.KE_DHE_DSS);
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new AesFastEngine()), new CbcBlockCipher(new AesFastEngine()), new Sha1Digest(), new Sha1Digest(), 16, TlsCipherSuite.KE_DHE_RSA); return createAesCipherSuite(16, TlsCipherSuite.KE_DHE_RSA);
case TLS_RSA_WITH_AES_256_CBC_SHA: case TLS_RSA_WITH_AES_256_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new AesFastEngine()), new CbcBlockCipher(new AesFastEngine()), new Sha1Digest(), new Sha1Digest(), 32, TlsCipherSuite.KE_RSA); return createAesCipherSuite(32, TlsCipherSuite.KE_RSA);
case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new AesFastEngine()), new CbcBlockCipher(new AesFastEngine()), new Sha1Digest(), new Sha1Digest(), 32, TlsCipherSuite.KE_DHE_DSS); return createAesCipherSuite(32, TlsCipherSuite.KE_DHE_DSS);
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
return new TlsBlockCipherCipherSuite(new CbcBlockCipher(new AesFastEngine()), new CbcBlockCipher(new AesFastEngine()), new Sha1Digest(), new Sha1Digest(), 32, TlsCipherSuite.KE_DHE_RSA); return createAesCipherSuite(32, TlsCipherSuite.KE_DHE_RSA);
default: default:
handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_handshake_failure); handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_handshake_failure);
/* /*
* Unreachable Code, failWithError will always throw an exception! * Unreachable Code, failWithError will always throw an exception!
*/ */
return null; return null;
} }
} }
}
} private static TlsCipherSuite createAesCipherSuite(int cipherKeySize, short keyExchange)
{
return new TlsBlockCipherCipherSuite(createAesCipher(), createAesCipher(),
new Sha1Digest(), new Sha1Digest(), cipherKeySize, keyExchange);
}
private static TlsCipherSuite createDesEdeCipherSuite(int cipherKeySize, short keyExchange)
{
return new TlsBlockCipherCipherSuite(createDesEdeCipher(), createDesEdeCipher(),
new Sha1Digest(), new Sha1Digest(), cipherKeySize, keyExchange);
}
private static CbcBlockCipher createAesCipher()
{
return new CbcBlockCipher(new AesFastEngine());
}
private static CbcBlockCipher createDesEdeCipher()
{
return new CbcBlockCipher(new DesEdeEngine());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,211 +1,211 @@
using System; using System;
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math; using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security; using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Pkcs namespace Org.BouncyCastle.Pkcs
{ {
public sealed class PrivateKeyInfoFactory public sealed class PrivateKeyInfoFactory
{ {
private PrivateKeyInfoFactory() private PrivateKeyInfoFactory()
{ {
} }
public static PrivateKeyInfo CreatePrivateKeyInfo( public static PrivateKeyInfo CreatePrivateKeyInfo(
AsymmetricKeyParameter key) AsymmetricKeyParameter key)
{ {
if (key == null) if (key == null)
throw new ArgumentNullException("key"); throw new ArgumentNullException("key");
if (!key.IsPrivate) if (!key.IsPrivate)
throw new ArgumentException("Public key passed - private key expected", "key"); throw new ArgumentException("Public key passed - private key expected", "key");
if (key is ElGamalPrivateKeyParameters) if (key is ElGamalPrivateKeyParameters)
{ {
ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)key; ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)key;
return new PrivateKeyInfo( return new PrivateKeyInfo(
new AlgorithmIdentifier( new AlgorithmIdentifier(
OiwObjectIdentifiers.ElGamalAlgorithm, OiwObjectIdentifiers.ElGamalAlgorithm,
new ElGamalParameter( new ElGamalParameter(
_key.Parameters.P, _key.Parameters.P,
_key.Parameters.G).ToAsn1Object()), _key.Parameters.G).ToAsn1Object()),
new DerInteger(_key.X)); new DerInteger(_key.X));
} }
if (key is DsaPrivateKeyParameters) if (key is DsaPrivateKeyParameters)
{ {
DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)key; DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)key;
return new PrivateKeyInfo( return new PrivateKeyInfo(
new AlgorithmIdentifier( new AlgorithmIdentifier(
X9ObjectIdentifiers.IdDsa, X9ObjectIdentifiers.IdDsa,
new DsaParameter( new DsaParameter(
_key.Parameters.P, _key.Parameters.P,
_key.Parameters.Q, _key.Parameters.Q,
_key.Parameters.G).ToAsn1Object()), _key.Parameters.G).ToAsn1Object()),
new DerInteger(_key.X)); new DerInteger(_key.X));
} }
if (key is DHPrivateKeyParameters) if (key is DHPrivateKeyParameters)
{ {
/* /*
Process DH private key. Process DH private key.
The value for L was set to zero implicitly. The value for L was set to zero implicitly.
This is the same action as found in JCEDHPrivateKey GetEncoded method. This is the same action as found in JCEDHPrivateKey GetEncoded method.
*/ */
DHPrivateKeyParameters _key = (DHPrivateKeyParameters)key; DHPrivateKeyParameters _key = (DHPrivateKeyParameters)key;
DHParameter withNewL = new DHParameter( DHParameter withNewL = new DHParameter(
_key.Parameters.P, _key.Parameters.G, 0); _key.Parameters.P, _key.Parameters.G, 0);
return new PrivateKeyInfo( return new PrivateKeyInfo(
new AlgorithmIdentifier( new AlgorithmIdentifier(
PkcsObjectIdentifiers.DhKeyAgreement, PkcsObjectIdentifiers.DhKeyAgreement,
withNewL.ToAsn1Object()), withNewL.ToAsn1Object()),
new DerInteger(_key.X)); new DerInteger(_key.X));
} }
if (key is RsaKeyParameters) if (key is RsaKeyParameters)
{ {
AlgorithmIdentifier algID = new AlgorithmIdentifier( AlgorithmIdentifier algID = new AlgorithmIdentifier(
PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance);
RsaPrivateKeyStructure keyStruct; RsaPrivateKeyStructure keyStruct;
if (key is RsaPrivateCrtKeyParameters) if (key is RsaPrivateCrtKeyParameters)
{ {
RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)key; RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)key;
keyStruct = new RsaPrivateKeyStructure( keyStruct = new RsaPrivateKeyStructure(
_key.Modulus, _key.Modulus,
_key.PublicExponent, _key.PublicExponent,
_key.Exponent, _key.Exponent,
_key.P, _key.P,
_key.Q, _key.Q,
_key.DP, _key.DP,
_key.DQ, _key.DQ,
_key.QInv); _key.QInv);
} }
else else
{ {
RsaKeyParameters _key = (RsaKeyParameters) key; RsaKeyParameters _key = (RsaKeyParameters) key;
keyStruct = new RsaPrivateKeyStructure( keyStruct = new RsaPrivateKeyStructure(
_key.Modulus, _key.Modulus,
BigInteger.Zero, BigInteger.Zero,
_key.Exponent, _key.Exponent,
BigInteger.Zero, BigInteger.Zero,
BigInteger.Zero, BigInteger.Zero,
BigInteger.Zero, BigInteger.Zero,
BigInteger.Zero, BigInteger.Zero,
BigInteger.Zero); BigInteger.Zero);
} }
return new PrivateKeyInfo(algID, keyStruct.ToAsn1Object()); return new PrivateKeyInfo(algID, keyStruct.ToAsn1Object());
} }
if (key is ECPrivateKeyParameters) if (key is ECPrivateKeyParameters)
{ {
ECPrivateKeyParameters _key = (ECPrivateKeyParameters)key; ECPrivateKeyParameters _key = (ECPrivateKeyParameters)key;
AlgorithmIdentifier algID; AlgorithmIdentifier algID;
if (_key.AlgorithmName == "ECGOST3410") if (_key.AlgorithmName == "ECGOST3410")
{ {
if (_key.PublicKeyParamSet == null) if (_key.PublicKeyParamSet == null)
throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
_key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
algID = new AlgorithmIdentifier( algID = new AlgorithmIdentifier(
CryptoProObjectIdentifiers.GostR3410x2001, CryptoProObjectIdentifiers.GostR3410x2001,
gostParams.ToAsn1Object()); gostParams.ToAsn1Object());
} }
else else
{ {
X9ECParameters ecP = new X9ECParameters( X9ECParameters ecP = new X9ECParameters(
_key.Parameters.Curve, _key.Parameters.Curve,
_key.Parameters.G, _key.Parameters.G,
_key.Parameters.N, _key.Parameters.N,
_key.Parameters.H, _key.Parameters.H,
_key.Parameters.GetSeed()); _key.Parameters.GetSeed());
X962Parameters x962 = new X962Parameters(ecP); X962Parameters x962 = new X962Parameters(ecP);
algID = new AlgorithmIdentifier( algID = new AlgorithmIdentifier(
X9ObjectIdentifiers.IdECPublicKey, X9ObjectIdentifiers.IdECPublicKey,
x962.ToAsn1Object()); x962.ToAsn1Object());
} }
return new PrivateKeyInfo(algID, new ECPrivateKeyStructure(_key.D).ToAsn1Object()); return new PrivateKeyInfo(algID, new ECPrivateKeyStructure(_key.D).ToAsn1Object());
} }
if (key is Gost3410PrivateKeyParameters) if (key is Gost3410PrivateKeyParameters)
{ {
Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)key; Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)key;
if (_key.PublicKeyParamSet == null) if (_key.PublicKeyParamSet == null)
throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
byte[] keyEnc = _key.X.ToByteArrayUnsigned(); byte[] keyEnc = _key.X.ToByteArrayUnsigned();
byte[] keyBytes = new byte[keyEnc.Length]; byte[] keyBytes = new byte[keyEnc.Length];
for (int i = 0; i != keyBytes.Length; i++) for (int i = 0; i != keyBytes.Length; i++)
{ {
keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian
} }
Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
_key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null); _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null);
AlgorithmIdentifier algID = new AlgorithmIdentifier( AlgorithmIdentifier algID = new AlgorithmIdentifier(
CryptoProObjectIdentifiers.GostR3410x94, CryptoProObjectIdentifiers.GostR3410x94,
algParams.ToAsn1Object()); algParams.ToAsn1Object());
return new PrivateKeyInfo(algID, new DerOctetString(keyBytes)); return new PrivateKeyInfo(algID, new DerOctetString(keyBytes));
} }
throw new ArgumentException("Class provided is not convertible: " + key.GetType().FullName); throw new ArgumentException("Class provided is not convertible: " + key.GetType().FullName);
} }
public static PrivateKeyInfo CreatePrivateKeyInfo( public static PrivateKeyInfo CreatePrivateKeyInfo(
char[] passPhrase, char[] passPhrase,
EncryptedPrivateKeyInfo encInfo) EncryptedPrivateKeyInfo encInfo)
{ {
return CreatePrivateKeyInfo(passPhrase, false, encInfo); return CreatePrivateKeyInfo(passPhrase, false, encInfo);
} }
public static PrivateKeyInfo CreatePrivateKeyInfo( public static PrivateKeyInfo CreatePrivateKeyInfo(
char[] passPhrase, char[] passPhrase,
bool wrongPkcs12Zero, bool wrongPkcs12Zero,
EncryptedPrivateKeyInfo encInfo) EncryptedPrivateKeyInfo encInfo)
{ {
AlgorithmIdentifier algID = encInfo.EncryptionAlgorithm; AlgorithmIdentifier algID = encInfo.EncryptionAlgorithm;
IBufferedCipher cipher = PbeUtilities.CreateEngine(algID.ObjectID) as IBufferedCipher; IBufferedCipher cipher = PbeUtilities.CreateEngine(algID) as IBufferedCipher;
if (cipher == null) if (cipher == null)
{ {
// TODO Throw exception? // TODO Throw exception?
} }
ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters( ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters(
algID.ObjectID, passPhrase, wrongPkcs12Zero, algID.Parameters); algID, passPhrase, wrongPkcs12Zero);
cipher.Init(false, keyParameters); cipher.Init(false, keyParameters);
byte[] keyBytes = encInfo.GetEncryptedData(); byte[] keyBytes = encInfo.GetEncryptedData();
byte[] encoding = cipher.DoFinal(keyBytes); byte[] encoding = cipher.DoFinal(keyBytes);
Asn1Object asn1Data = Asn1Object.FromByteArray(encoding); Asn1Object asn1Data = Asn1Object.FromByteArray(encoding);
return PrivateKeyInfo.GetInstance(asn1Data); return PrivateKeyInfo.GetInstance(asn1Data);
} }
} }
} }

View File

@ -1,215 +1,214 @@
using System; using System;
using System.Collections; using System.Collections;
using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509; using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store; using Org.BouncyCastle.X509.Store;
namespace Org.BouncyCastle.Pkix namespace Org.BouncyCastle.Pkix
{ {
public class PkixAttrCertPathBuilder public class PkixAttrCertPathBuilder
{ {
/** /**
* Build and validate a CertPath using the given parameter. * Build and validate a CertPath using the given parameter.
* *
* @param params PKIXBuilderParameters object containing all information to * @param params PKIXBuilderParameters object containing all information to
* build the CertPath * build the CertPath
*/ */
public virtual PkixCertPathBuilderResult Build( public virtual PkixCertPathBuilderResult Build(
PkixBuilderParameters pkixParams) PkixBuilderParameters pkixParams)
{ {
// search target certificates // search target certificates
IX509Selector certSelect = pkixParams.GetTargetConstraints(); IX509Selector certSelect = pkixParams.GetTargetConstraints();
if (!(certSelect is X509AttrCertStoreSelector)) if (!(certSelect is X509AttrCertStoreSelector))
{ {
throw new PkixCertPathBuilderException( throw new PkixCertPathBuilderException(
"TargetConstraints must be an instance of " "TargetConstraints must be an instance of "
+ typeof(X509AttrCertStoreSelector).FullName + typeof(X509AttrCertStoreSelector).FullName
+ " for " + " for "
+ typeof(PkixAttrCertPathBuilder).FullName + " class."); + typeof(PkixAttrCertPathBuilder).FullName + " class.");
} }
ICollection targets; ICollection targets;
try try
{ {
targets = PkixCertPathValidatorUtilities.FindCertificates( targets = PkixCertPathValidatorUtilities.FindCertificates(
(X509AttrCertStoreSelector)certSelect, pkixParams.GetStores()); (X509AttrCertStoreSelector)certSelect, pkixParams.GetStores());
} }
catch (Exception e) catch (Exception e)
{ {
throw new PkixCertPathBuilderException("Error finding target attribute certificate.", e); throw new PkixCertPathBuilderException("Error finding target attribute certificate.", e);
} }
if (targets.Count == 0) if (targets.Count == 0)
{ {
throw new PkixCertPathBuilderException( throw new PkixCertPathBuilderException(
"No attribute certificate found matching targetContraints."); "No attribute certificate found matching targetContraints.");
} }
PkixCertPathBuilderResult result = null; PkixCertPathBuilderResult result = null;
// check all potential target certificates // check all potential target certificates
foreach (IX509AttributeCertificate cert in targets) foreach (IX509AttributeCertificate cert in targets)
{ {
X509CertStoreSelector selector = new X509CertStoreSelector(); X509CertStoreSelector selector = new X509CertStoreSelector();
X509Name[] principals = cert.Issuer.GetPrincipals(); X509Name[] principals = cert.Issuer.GetPrincipals();
ISet issuers = new HashSet(); ISet issuers = new HashSet();
for (int i = 0; i < principals.Length; i++) for (int i = 0; i < principals.Length; i++)
{ {
try try
{ {
selector.Subject = principals[i]; selector.Subject = principals[i];
issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStores())); issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStores()));
issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetX509Stores())); }
} catch (Exception e)
catch (Exception e) {
{ throw new PkixCertPathBuilderException(
throw new PkixCertPathBuilderException( "Public key certificate for attribute certificate cannot be searched.",
"Public key certificate for attribute certificate cannot be searched.", e);
e); }
} }
}
if (issuers.IsEmpty)
if (issuers.IsEmpty) throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found.");
throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found.");
IList certPathList = new ArrayList();
IList certPathList = new ArrayList();
foreach (X509Certificate issuer in issuers)
foreach (X509Certificate issuer in issuers) {
{ result = Build(cert, issuer, pkixParams, certPathList);
result = Build(cert, issuer, pkixParams, certPathList);
if (result != null)
if (result != null) break;
break; }
}
if (result != null)
if (result != null) break;
break; }
}
if (result == null && certPathException != null)
if (result == null && certPathException != null) {
{ throw new PkixCertPathBuilderException(
throw new PkixCertPathBuilderException( "Possible certificate chain could not be validated.",
"Possible certificate chain could not be validated.", certPathException);
certPathException); }
}
if (result == null && certPathException == null)
if (result == null && certPathException == null) {
{ throw new PkixCertPathBuilderException(
throw new PkixCertPathBuilderException( "Unable to find certificate chain.");
"Unable to find certificate chain."); }
}
return result;
return result; }
}
private Exception certPathException;
private Exception certPathException;
private PkixCertPathBuilderResult Build(
private PkixCertPathBuilderResult Build( IX509AttributeCertificate attrCert,
IX509AttributeCertificate attrCert, X509Certificate tbvCert,
X509Certificate tbvCert, PkixBuilderParameters pkixParams,
PkixBuilderParameters pkixParams, IList tbvPath)
IList tbvPath) {
{ // If tbvCert is readily present in tbvPath, it indicates having run
// If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the
// into a cycle in the // PKI graph.
// PKI graph. if (tbvPath.Contains(tbvCert))
if (tbvPath.Contains(tbvCert)) return null;
return null;
// step out, the certificate is not allowed to appear in a certification
// step out, the certificate is not allowed to appear in a certification // chain
// chain if (pkixParams.GetExcludedCerts().Contains(tbvCert))
if (pkixParams.GetExcludedCerts().Contains(tbvCert)) return null;
return null;
// test if certificate path exceeds maximum length
// test if certificate path exceeds maximum length if (pkixParams.MaxPathLength != -1)
if (pkixParams.MaxPathLength != -1) {
{ if (tbvPath.Count - 1 > pkixParams.MaxPathLength)
if (tbvPath.Count - 1 > pkixParams.MaxPathLength) return null;
return null; }
}
tbvPath.Add(tbvCert);
tbvPath.Add(tbvCert);
PkixCertPathBuilderResult builderResult = null;
PkixCertPathBuilderResult builderResult = null;
X509CertificateParser certParser = new X509CertificateParser();
X509CertificateParser certParser = new X509CertificateParser(); PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator();
PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator();
try
try {
{ // check whether the issuer of <tbvCert> is a TrustAnchor
// check whether the issuer of <tbvCert> is a TrustAnchor if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null)
if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null) {
{ PkixCertPath certPath = new PkixCertPath(tbvPath);
PkixCertPath certPath = new PkixCertPath(tbvPath); PkixCertPathValidatorResult result;
PkixCertPathValidatorResult result;
try
try {
{ result = validator.Validate(certPath, pkixParams);
result = validator.Validate(certPath, pkixParams); }
} catch (Exception e)
catch (Exception e) {
{ throw new Exception("Certification path could not be validated.", e);
throw new Exception("Certification path could not be validated.", e); }
}
return new PkixCertPathBuilderResult(certPath, result.TrustAnchor,
return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, result.PolicyTree, result.SubjectPublicKey);
result.PolicyTree, result.SubjectPublicKey); }
} else
else {
{ // add additional X.509 stores from locations in certificate
// add additional X.509 stores from locations in certificate try
try {
{ PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams);
PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams); }
} catch (CertificateParsingException e)
catch (CertificateParsingException e) {
{ throw new Exception("No additional X.509 stores can be added from certificate locations.", e);
throw new Exception("No additional X.509 stores can be added from certificate locations.", e); }
}
// try to get the issuer certificate from one of the stores
// try to get the issuer certificate from one of the stores ISet issuers = new HashSet();
ISet issuers = new HashSet(); try
try {
{ issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams)); }
} catch (Exception e)
catch (Exception e) {
{ throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
throw new Exception("Cannot find issuer certificate for certificate in certification path.", e); }
}
if (issuers.IsEmpty)
if (issuers.IsEmpty) throw new Exception("No issuer certificate for certificate in certification path found.");
throw new Exception("No issuer certificate for certificate in certification path found.");
foreach (X509Certificate issuer in issuers)
foreach (X509Certificate issuer in issuers) {
{ // if untrusted self signed certificate continue
// if untrusted self signed certificate continue if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer))
if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer)) continue;
continue;
builderResult = Build(attrCert, issuer, pkixParams, tbvPath);
builderResult = Build(attrCert, issuer, pkixParams, tbvPath);
if (builderResult != null)
if (builderResult != null) break;
break; }
} }
} }
} catch (Exception e)
catch (Exception e) {
{ certPathException = new Exception("No valid certification path could be build.", e);
certPathException = new Exception("No valid certification path could be build.", e); }
}
if (builderResult == null)
if (builderResult == null) {
{ tbvPath.Remove(tbvCert);
tbvPath.Remove(tbvCert); }
}
return builderResult;
return builderResult; }
} }
} }
}

View File

@ -1,205 +1,204 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Text; using System.Text;
using Org.BouncyCastle.Asn1.IsisMtt; using Org.BouncyCastle.Asn1.IsisMtt;
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X500; using Org.BouncyCastle.Asn1.X500;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math; using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509; using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store; using Org.BouncyCastle.X509.Store;
namespace Org.BouncyCastle.Pkix namespace Org.BouncyCastle.Pkix
{ {
/** /**
* Implements the PKIX CertPathBuilding algorithm for BouncyCastle. * Implements the PKIX CertPathBuilding algorithm for BouncyCastle.
* *
* @see CertPathBuilderSpi * @see CertPathBuilderSpi
*/ */
public class PkixCertPathBuilder public class PkixCertPathBuilder
// : CertPathBuilderSpi // : CertPathBuilderSpi
{ {
/** /**
* Build and validate a CertPath using the given parameter. * Build and validate a CertPath using the given parameter.
* *
* @param params PKIXBuilderParameters object containing all information to * @param params PKIXBuilderParameters object containing all information to
* build the CertPath * build the CertPath
*/ */
public virtual PkixCertPathBuilderResult Build( public virtual PkixCertPathBuilderResult Build(
PkixBuilderParameters pkixParams) PkixBuilderParameters pkixParams)
{ {
// search target certificates // search target certificates
IX509Selector certSelect = pkixParams.GetTargetCertConstraints(); IX509Selector certSelect = pkixParams.GetTargetCertConstraints();
if (!(certSelect is X509CertStoreSelector)) if (!(certSelect is X509CertStoreSelector))
{ {
throw new PkixCertPathBuilderException( throw new PkixCertPathBuilderException(
"TargetConstraints must be an instance of " "TargetConstraints must be an instance of "
+ typeof(X509CertStoreSelector).FullName + " for " + typeof(X509CertStoreSelector).FullName + " for "
+ this.GetType() + " class."); + this.GetType() + " class.");
} }
ISet targets = new HashSet(); ISet targets = new HashSet();
try try
{ {
targets.AddAll(PkixCertPathValidatorUtilities.FindCertificates((X509CertStoreSelector)certSelect, pkixParams.GetStores())); targets.AddAll(PkixCertPathValidatorUtilities.FindCertificates((X509CertStoreSelector)certSelect, pkixParams.GetStores()));
targets.AddAll(PkixCertPathValidatorUtilities.FindCertificates((X509CertStoreSelector)certSelect, pkixParams.GetX509Stores())); // TODO Should this include an entry for pkixParams.GetAdditionalStores() too?
// TODO Should this include an entry for pkixParams.GetAdditionalStores() too? }
} catch (Exception e)
catch (Exception e) {
{ throw new PkixCertPathBuilderException(
throw new PkixCertPathBuilderException( "Error finding target certificate.", e);
"Error finding target certificate.", e); }
}
if (targets.IsEmpty)
if (targets.IsEmpty) throw new PkixCertPathBuilderException("No certificate found matching targetContraints.");
throw new PkixCertPathBuilderException("No certificate found matching targetContraints.");
PkixCertPathBuilderResult result = null;
PkixCertPathBuilderResult result = null; IList certPathList = new ArrayList();
IList certPathList = new ArrayList();
// check all potential target certificates
// check all potential target certificates foreach (X509Certificate cert in targets)
foreach (X509Certificate cert in targets) {
{ result = Build(cert, pkixParams, certPathList);
result = Build(cert, pkixParams, certPathList);
if (result != null)
if (result != null) break;
break; }
}
if (result == null && certPathException != null)
if (result == null && certPathException != null) {
{ throw new PkixCertPathBuilderException(certPathException.Message, certPathException.InnerException);
throw new PkixCertPathBuilderException(certPathException.Message, certPathException.InnerException); }
}
if (result == null && certPathException == null)
if (result == null && certPathException == null) {
{ throw new PkixCertPathBuilderException("Unable to find certificate chain.");
throw new PkixCertPathBuilderException("Unable to find certificate chain."); }
}
return result;
return result; }
}
private Exception certPathException;
private Exception certPathException;
protected virtual PkixCertPathBuilderResult Build(
protected virtual PkixCertPathBuilderResult Build( X509Certificate tbvCert,
X509Certificate tbvCert, PkixBuilderParameters pkixParams,
PkixBuilderParameters pkixParams, IList tbvPath)
IList tbvPath) {
{ // If tbvCert is readily present in tbvPath, it indicates having run
// If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the PKI graph.
// into a cycle in the PKI graph. if (tbvPath.Contains(tbvCert))
if (tbvPath.Contains(tbvCert)) return null;
return null;
// step out, the certificate is not allowed to appear in a certification
// step out, the certificate is not allowed to appear in a certification // chain.
// chain. if (pkixParams.GetExcludedCerts().Contains(tbvCert))
if (pkixParams.GetExcludedCerts().Contains(tbvCert)) return null;
return null;
// test if certificate path exceeds maximum length
// test if certificate path exceeds maximum length if (pkixParams.MaxPathLength != -1)
if (pkixParams.MaxPathLength != -1) {
{ if (tbvPath.Count - 1 > pkixParams.MaxPathLength)
if (tbvPath.Count - 1 > pkixParams.MaxPathLength) return null;
return null; }
}
tbvPath.Add(tbvCert);
tbvPath.Add(tbvCert);
X509CertificateParser certParser = new X509CertificateParser();
X509CertificateParser certParser = new X509CertificateParser(); PkixCertPathBuilderResult builderResult = null;
PkixCertPathBuilderResult builderResult = null; PkixCertPathValidator validator = new PkixCertPathValidator();
PkixCertPathValidator validator = new PkixCertPathValidator();
try
try {
{ // check whether the issuer of <tbvCert> is a TrustAnchor
// check whether the issuer of <tbvCert> is a TrustAnchor if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null)
if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null) {
{ // exception message from possibly later tried certification
// exception message from possibly later tried certification // chains
// chains PkixCertPath certPath = null;
PkixCertPath certPath = null; try
try {
{ certPath = new PkixCertPath(tbvPath);
certPath = new PkixCertPath(tbvPath); }
} catch (Exception e)
catch (Exception e) {
{ throw new Exception(
throw new Exception( "Certification path could not be constructed from certificate list.",
"Certification path could not be constructed from certificate list.", e);
e); }
}
PkixCertPathValidatorResult result = null;
PkixCertPathValidatorResult result = null; try
try {
{ result = (PkixCertPathValidatorResult)validator.Validate(
result = (PkixCertPathValidatorResult)validator.Validate( certPath, pkixParams);
certPath, pkixParams); }
} catch (Exception e)
catch (Exception e) {
{ throw new Exception(
throw new Exception( "Certification path could not be validated.", e);
"Certification path could not be validated.", e); }
}
return new PkixCertPathBuilderResult(certPath, result.TrustAnchor,
return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, result.PolicyTree, result.SubjectPublicKey);
result.PolicyTree, result.SubjectPublicKey); }
} else
else {
{ // add additional X.509 stores from locations in certificate
// add additional X.509 stores from locations in certificate try
try {
{ PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(
PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames( tbvCert, pkixParams);
tbvCert, pkixParams); }
} catch (CertificateParsingException e)
catch (CertificateParsingException e) {
{ throw new Exception(
throw new Exception( "No additiontal X.509 stores can be added from certificate locations.",
"No additiontal X.509 stores can be added from certificate locations.", e);
e); }
}
// try to get the issuer certificate from one of the stores
// try to get the issuer certificate from one of the stores HashSet issuers = new HashSet();
HashSet issuers = new HashSet(); try
try {
{ issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams)); }
} catch (Exception e)
catch (Exception e) {
{ throw new Exception(
throw new Exception( "Cannot find issuer certificate for certificate in certification path.",
"Cannot find issuer certificate for certificate in certification path.", e);
e); }
}
if (issuers.IsEmpty)
if (issuers.IsEmpty) throw new Exception("No issuer certificate for certificate in certification path found.");
throw new Exception("No issuer certificate for certificate in certification path found.");
foreach (X509Certificate issuer in issuers)
foreach (X509Certificate issuer in issuers) {
{ builderResult = Build(issuer, pkixParams, tbvPath);
builderResult = Build(issuer, pkixParams, tbvPath);
if (builderResult != null)
if (builderResult != null) break;
break; }
} }
} }
} catch (Exception e)
catch (Exception e) {
{ certPathException = e;
certPathException = e; }
}
if (builderResult == null)
if (builderResult == null) {
{ tbvPath.Remove(tbvCert);
tbvPath.Remove(tbvCert); }
}
return builderResult;
return builderResult; }
} }
} }
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -67,9 +67,13 @@ namespace Org.BouncyCastle.Security
"1.2.840.113533.7.66.10"); "1.2.840.113533.7.66.10");
AddKgAlgorithm("CAST6"); AddKgAlgorithm("CAST6");
AddKgAlgorithm("DES", AddKgAlgorithm("DES",
OiwObjectIdentifiers.DesCbc); OiwObjectIdentifiers.DesCbc,
OiwObjectIdentifiers.DesCfb,
OiwObjectIdentifiers.DesEcb,
OiwObjectIdentifiers.DesOfb);
AddKgAlgorithm("DESEDE", AddKgAlgorithm("DESEDE",
"DESEDEWRAP", "DESEDEWRAP",
OiwObjectIdentifiers.DesEde,
PkcsObjectIdentifiers.IdAlgCms3DesWrap); PkcsObjectIdentifiers.IdAlgCms3DesWrap);
AddKgAlgorithm("DESEDE3", AddKgAlgorithm("DESEDE3",
PkcsObjectIdentifiers.DesEde3Cbc); PkcsObjectIdentifiers.DesEde3Cbc);

View File

@ -1,318 +1,322 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Globalization; using System.Globalization;
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Kisa; using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Misc; using Org.BouncyCastle.Asn1.Misc;
using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt; using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Security namespace Org.BouncyCastle.Security
{ {
public sealed class ParameterUtilities public sealed class ParameterUtilities
{ {
private ParameterUtilities() private ParameterUtilities()
{ {
} }
private static readonly Hashtable algorithms = new Hashtable(); private static readonly Hashtable algorithms = new Hashtable();
static ParameterUtilities() static ParameterUtilities()
{ {
AddAlgorithm("AES", AddAlgorithm("AES",
"AESWRAP"); "AESWRAP");
AddAlgorithm("AES128", AddAlgorithm("AES128",
"2.16.840.1.101.3.4.2", "2.16.840.1.101.3.4.2",
NistObjectIdentifiers.IdAes128Cbc, NistObjectIdentifiers.IdAes128Cbc,
NistObjectIdentifiers.IdAes128Cfb, NistObjectIdentifiers.IdAes128Cfb,
NistObjectIdentifiers.IdAes128Ecb, NistObjectIdentifiers.IdAes128Ecb,
NistObjectIdentifiers.IdAes128Ofb, NistObjectIdentifiers.IdAes128Ofb,
NistObjectIdentifiers.IdAes128Wrap); NistObjectIdentifiers.IdAes128Wrap);
AddAlgorithm("AES192", AddAlgorithm("AES192",
"2.16.840.1.101.3.4.22", "2.16.840.1.101.3.4.22",
NistObjectIdentifiers.IdAes192Cbc, NistObjectIdentifiers.IdAes192Cbc,
NistObjectIdentifiers.IdAes192Cfb, NistObjectIdentifiers.IdAes192Cfb,
NistObjectIdentifiers.IdAes192Ecb, NistObjectIdentifiers.IdAes192Ecb,
NistObjectIdentifiers.IdAes192Ofb, NistObjectIdentifiers.IdAes192Ofb,
NistObjectIdentifiers.IdAes192Wrap); NistObjectIdentifiers.IdAes192Wrap);
AddAlgorithm("AES256", AddAlgorithm("AES256",
"2.16.840.1.101.3.4.42", "2.16.840.1.101.3.4.42",
NistObjectIdentifiers.IdAes256Cbc, NistObjectIdentifiers.IdAes256Cbc,
NistObjectIdentifiers.IdAes256Cfb, NistObjectIdentifiers.IdAes256Cfb,
NistObjectIdentifiers.IdAes256Ecb, NistObjectIdentifiers.IdAes256Ecb,
NistObjectIdentifiers.IdAes256Ofb, NistObjectIdentifiers.IdAes256Ofb,
NistObjectIdentifiers.IdAes256Wrap); NistObjectIdentifiers.IdAes256Wrap);
AddAlgorithm("BLOWFISH"); AddAlgorithm("BLOWFISH");
AddAlgorithm("CAMELLIA", AddAlgorithm("CAMELLIA",
"CAMELLIAWRAP"); "CAMELLIAWRAP");
AddAlgorithm("CAMELLIA128", AddAlgorithm("CAMELLIA128",
NttObjectIdentifiers.IdCamellia128Cbc, NttObjectIdentifiers.IdCamellia128Cbc,
NttObjectIdentifiers.IdCamellia128Wrap); NttObjectIdentifiers.IdCamellia128Wrap);
AddAlgorithm("CAMELLIA192", AddAlgorithm("CAMELLIA192",
NttObjectIdentifiers.IdCamellia192Cbc, NttObjectIdentifiers.IdCamellia192Cbc,
NttObjectIdentifiers.IdCamellia192Wrap); NttObjectIdentifiers.IdCamellia192Wrap);
AddAlgorithm("CAMELLIA256", AddAlgorithm("CAMELLIA256",
NttObjectIdentifiers.IdCamellia256Cbc, NttObjectIdentifiers.IdCamellia256Cbc,
NttObjectIdentifiers.IdCamellia256Wrap); NttObjectIdentifiers.IdCamellia256Wrap);
AddAlgorithm("CAST5", AddAlgorithm("CAST5",
"1.2.840.113533.7.66.10"); "1.2.840.113533.7.66.10");
AddAlgorithm("CAST6"); AddAlgorithm("CAST6");
AddAlgorithm("DES", AddAlgorithm("DES",
OiwObjectIdentifiers.DesCbc); OiwObjectIdentifiers.DesCbc,
AddAlgorithm("DESEDE", OiwObjectIdentifiers.DesCfb,
"DESEDEWRAP", OiwObjectIdentifiers.DesEcb,
PkcsObjectIdentifiers.IdAlgCms3DesWrap); OiwObjectIdentifiers.DesOfb);
AddAlgorithm("DESEDE3", AddAlgorithm("DESEDE",
PkcsObjectIdentifiers.DesEde3Cbc); "DESEDEWRAP",
AddAlgorithm("GOST28147", OiwObjectIdentifiers.DesEde,
"GOST", PkcsObjectIdentifiers.IdAlgCms3DesWrap);
"GOST-28147", AddAlgorithm("DESEDE3",
CryptoProObjectIdentifiers.GostR28147Cbc); PkcsObjectIdentifiers.DesEde3Cbc);
AddAlgorithm("HC128"); AddAlgorithm("GOST28147",
AddAlgorithm("HC256"); "GOST",
AddAlgorithm("IDEA", "GOST-28147",
"1.3.6.1.4.1.188.7.1.1.2"); CryptoProObjectIdentifiers.GostR28147Cbc);
AddAlgorithm("NOEKEON"); AddAlgorithm("HC128");
AddAlgorithm("RC2", AddAlgorithm("HC256");
PkcsObjectIdentifiers.RC2Cbc, AddAlgorithm("IDEA",
PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); "1.3.6.1.4.1.188.7.1.1.2");
AddAlgorithm("RC4", AddAlgorithm("NOEKEON");
"ARC4", AddAlgorithm("RC2",
"1.2.840.113549.3.4"); PkcsObjectIdentifiers.RC2Cbc,
AddAlgorithm("RC5", PkcsObjectIdentifiers.IdAlgCmsRC2Wrap);
"RC5-32"); AddAlgorithm("RC4",
AddAlgorithm("RC5-64"); "ARC4",
AddAlgorithm("RC6"); "1.2.840.113549.3.4");
AddAlgorithm("RIJNDAEL"); AddAlgorithm("RC5",
AddAlgorithm("SALSA20"); "RC5-32");
AddAlgorithm("SEED", AddAlgorithm("RC5-64");
KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, AddAlgorithm("RC6");
KisaObjectIdentifiers.IdSeedCbc); AddAlgorithm("RIJNDAEL");
AddAlgorithm("SERPENT"); AddAlgorithm("SALSA20");
AddAlgorithm("SKIPJACK"); AddAlgorithm("SEED",
AddAlgorithm("TEA"); KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap,
AddAlgorithm("TWOFISH"); KisaObjectIdentifiers.IdSeedCbc);
AddAlgorithm("VMPC"); AddAlgorithm("SERPENT");
AddAlgorithm("VMPC-KSA3"); AddAlgorithm("SKIPJACK");
AddAlgorithm("XTEA"); AddAlgorithm("TEA");
} AddAlgorithm("TWOFISH");
AddAlgorithm("VMPC");
private static void AddAlgorithm( AddAlgorithm("VMPC-KSA3");
string canonicalName, AddAlgorithm("XTEA");
params object[] aliases) }
{
algorithms[canonicalName] = canonicalName; private static void AddAlgorithm(
string canonicalName,
foreach (object alias in aliases) params object[] aliases)
{ {
algorithms[alias.ToString()] = canonicalName; algorithms[canonicalName] = canonicalName;
}
} foreach (object alias in aliases)
{
public static string GetCanonicalAlgorithmName( algorithms[alias.ToString()] = canonicalName;
string algorithm) }
{ }
return (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
} public static string GetCanonicalAlgorithmName(
string algorithm)
public static KeyParameter CreateKeyParameter( {
DerObjectIdentifier algOid, return (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
byte[] keyBytes) }
{
return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length); public static KeyParameter CreateKeyParameter(
} DerObjectIdentifier algOid,
byte[] keyBytes)
public static KeyParameter CreateKeyParameter( {
string algorithm, return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length);
byte[] keyBytes) }
{
return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length); public static KeyParameter CreateKeyParameter(
} string algorithm,
byte[] keyBytes)
public static KeyParameter CreateKeyParameter( {
DerObjectIdentifier algOid, return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length);
byte[] keyBytes, }
int offset,
int length) public static KeyParameter CreateKeyParameter(
{ DerObjectIdentifier algOid,
return CreateKeyParameter(algOid.Id, keyBytes, offset, length); byte[] keyBytes,
} int offset,
int length)
public static KeyParameter CreateKeyParameter( {
string algorithm, return CreateKeyParameter(algOid.Id, keyBytes, offset, length);
byte[] keyBytes, }
int offset,
int length) public static KeyParameter CreateKeyParameter(
{ string algorithm,
if (algorithm == null) byte[] keyBytes,
throw new ArgumentNullException("algorithm"); int offset,
int length)
string canonical = GetCanonicalAlgorithmName(algorithm); {
if (algorithm == null)
if (canonical == null) throw new ArgumentNullException("algorithm");
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
string canonical = GetCanonicalAlgorithmName(algorithm);
switch (canonical)
{ if (canonical == null)
case "DES": throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
return new DesParameters(keyBytes, offset, length);
case "DESEDE": switch (canonical)
case "DESEDE3": {
return new DesEdeParameters(keyBytes, offset, length); case "DES":
case "RC2": return new DesParameters(keyBytes, offset, length);
return new RC2Parameters(keyBytes, offset, length); case "DESEDE":
default: case "DESEDE3":
return new KeyParameter(keyBytes, offset, length); return new DesEdeParameters(keyBytes, offset, length);
} case "RC2":
} return new RC2Parameters(keyBytes, offset, length);
default:
public static ICipherParameters GetCipherParameters( return new KeyParameter(keyBytes, offset, length);
DerObjectIdentifier algOid, }
ICipherParameters key, }
Asn1Object asn1Params)
{ public static ICipherParameters GetCipherParameters(
return GetCipherParameters(algOid.Id, key, asn1Params); DerObjectIdentifier algOid,
} ICipherParameters key,
Asn1Object asn1Params)
public static ICipherParameters GetCipherParameters( {
string algorithm, return GetCipherParameters(algOid.Id, key, asn1Params);
ICipherParameters key, }
Asn1Object asn1Params)
{ public static ICipherParameters GetCipherParameters(
if (algorithm == null) string algorithm,
throw new ArgumentNullException("algorithm"); ICipherParameters key,
Asn1Object asn1Params)
string canonical = GetCanonicalAlgorithmName(algorithm); {
if (algorithm == null)
if (canonical == null) throw new ArgumentNullException("algorithm");
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
string canonical = GetCanonicalAlgorithmName(algorithm);
byte[] iv = null;
if (canonical == null)
try throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
{
switch (canonical) byte[] iv = null;
{
case "AES": try
case "AES128": {
case "AES192": switch (canonical)
case "AES256": {
case "BLOWFISH": case "AES":
case "CAMELLIA": case "AES128":
case "CAMELLIA128": case "AES192":
case "CAMELLIA192": case "AES256":
case "CAMELLIA256": case "BLOWFISH":
case "DES": case "CAMELLIA":
case "DESEDE": case "CAMELLIA128":
case "DESEDE3": case "CAMELLIA192":
case "NOEKEON": case "CAMELLIA256":
case "RIJNDAEL": case "DES":
case "SEED": case "DESEDE":
case "SKIPJACK": case "DESEDE3":
case "TWOFISH": case "NOEKEON":
iv = ((Asn1OctetString) asn1Params).GetOctets(); case "RIJNDAEL":
break; case "SEED":
case "RC2": case "SKIPJACK":
iv = RC2CbcParameter.GetInstance(asn1Params).GetIV(); case "TWOFISH":
break; iv = ((Asn1OctetString) asn1Params).GetOctets();
case "IDEA": break;
iv = IdeaCbcPar.GetInstance(asn1Params).GetIV(); case "RC2":
break; iv = RC2CbcParameter.GetInstance(asn1Params).GetIV();
case "CAST5": break;
iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV(); case "IDEA":
break; iv = IdeaCbcPar.GetInstance(asn1Params).GetIV();
} break;
} case "CAST5":
catch (Exception e) iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV();
{ break;
throw new ArgumentException("Could not process ASN.1 parameters", e); }
} }
catch (Exception e)
if (iv != null) {
{ throw new ArgumentException("Could not process ASN.1 parameters", e);
return new ParametersWithIV(key, iv); }
}
if (iv != null)
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); {
} return new ParametersWithIV(key, iv);
}
public static Asn1Encodable GenerateParameters(
DerObjectIdentifier algID, throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
SecureRandom random) }
{
return GenerateParameters(algID.Id, random); public static Asn1Encodable GenerateParameters(
} DerObjectIdentifier algID,
SecureRandom random)
public static Asn1Encodable GenerateParameters( {
string algorithm, return GenerateParameters(algID.Id, random);
SecureRandom random) }
{
if (algorithm == null) public static Asn1Encodable GenerateParameters(
throw new ArgumentNullException("algorithm"); string algorithm,
SecureRandom random)
string canonical = GetCanonicalAlgorithmName(algorithm); {
if (algorithm == null)
if (canonical == null) throw new ArgumentNullException("algorithm");
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
string canonical = GetCanonicalAlgorithmName(algorithm);
switch (canonical)
{ if (canonical == null)
// TODO These algorithms support an IV (see GetCipherParameters) throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
// but JCE doesn't seem to provide an AlgorithmParametersGenerator for them
// case "BLOWFISH": switch (canonical)
// case "RIJNDAEL": {
// case "SKIPJACK": // TODO These algorithms support an IV (see GetCipherParameters)
// case "TWOFISH": // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them
// case "BLOWFISH":
case "AES": // case "RIJNDAEL":
case "AES128": // case "SKIPJACK":
case "AES192": // case "TWOFISH":
case "AES256":
return CreateIVOctetString(random, 16); case "AES":
case "CAMELLIA": case "AES128":
case "CAMELLIA128": case "AES192":
case "CAMELLIA192": case "AES256":
case "CAMELLIA256": return CreateIVOctetString(random, 16);
return CreateIVOctetString(random, 16); case "CAMELLIA":
case "CAST5": case "CAMELLIA128":
return new Cast5CbcParameters(CreateIV(random, 8), 128); case "CAMELLIA192":
case "DES": case "CAMELLIA256":
case "DESEDE": return CreateIVOctetString(random, 16);
case "DESEDE3": case "CAST5":
return CreateIVOctetString(random, 8); return new Cast5CbcParameters(CreateIV(random, 8), 128);
case "IDEA": case "DES":
return new IdeaCbcPar(CreateIV(random, 8)); case "DESEDE":
case "NOEKEON": case "DESEDE3":
return CreateIVOctetString(random, 16); return CreateIVOctetString(random, 8);
case "RC2": case "IDEA":
return new RC2CbcParameter(CreateIV(random, 8)); return new IdeaCbcPar(CreateIV(random, 8));
case "SEED": case "NOEKEON":
return CreateIVOctetString(random, 16); return CreateIVOctetString(random, 16);
} case "RC2":
return new RC2CbcParameter(CreateIV(random, 8));
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); case "SEED":
} return CreateIVOctetString(random, 16);
}
private static Asn1OctetString CreateIVOctetString(
SecureRandom random, throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
int ivLength) }
{
return new DerOctetString(CreateIV(random, ivLength)); private static Asn1OctetString CreateIVOctetString(
} SecureRandom random,
int ivLength)
private static byte[] CreateIV( {
SecureRandom random, return new DerOctetString(CreateIV(random, ivLength));
int ivLength) }
{
byte[] iv = new byte[ivLength]; private static byte[] CreateIV(
random.NextBytes(iv); SecureRandom random,
return iv; int ivLength)
} {
} byte[] iv = new byte[ivLength];
} random.NextBytes(iv);
return iv;
}
}
}

File diff suppressed because it is too large Load Diff