diff options
author | David Hook <dgh@bouncycastle.org> | 2015-10-12 14:48:04 +1100 |
---|---|---|
committer | David Hook <dgh@bouncycastle.org> | 2015-10-12 14:48:04 +1100 |
commit | ce9180e56bababf437e419b4f10699cf40ab01a9 (patch) | |
tree | 638682c526cffc0156276971d161a5f4b2802f9c /crypto/src | |
parent | Port of recent ISO trailer updates from Java (diff) | |
download | BouncyCastle.NET-ed25519-ce9180e56bababf437e419b4f10699cf40ab01a9.tar.xz |
Initial cut of signature generation operators.
Diffstat (limited to '')
-rw-r--r-- | crypto/src/asn1/x509/AlgorithmIdentifier.cs | 11 | ||||
-rw-r--r-- | crypto/src/crypto/ISignatureCalculator.cs | 44 | ||||
-rw-r--r-- | crypto/src/crypto/ISignatureVerifier.cs | 43 | ||||
-rw-r--r-- | crypto/src/crypto/ISignatureVerifierProvider.cs | 18 | ||||
-rw-r--r-- | crypto/src/crypto/operators/Asn1Signature.cs | 442 | ||||
-rw-r--r-- | crypto/src/x509/X509V1CertificateGenerator.cs | 50 | ||||
-rw-r--r-- | crypto/src/x509/X509V2AttributeCertificateGenerator.cs | 69 | ||||
-rw-r--r-- | crypto/src/x509/X509V2CRLGenerator.cs | 92 | ||||
-rw-r--r-- | crypto/src/x509/X509V3CertificateGenerator.cs | 65 |
9 files changed, 717 insertions, 117 deletions
diff --git a/crypto/src/asn1/x509/AlgorithmIdentifier.cs b/crypto/src/asn1/x509/AlgorithmIdentifier.cs index 4ed3a400d..c6f4af5bf 100644 --- a/crypto/src/asn1/x509/AlgorithmIdentifier.cs +++ b/crypto/src/asn1/x509/AlgorithmIdentifier.cs @@ -69,11 +69,22 @@ namespace Org.BouncyCastle.Asn1.X509 } } + /// <summary> + /// Return the OID in the Algorithm entry of this identifier. + /// </summary> + public virtual DerObjectIdentifier Algorithm + { + get { return objectID; } + } + public virtual DerObjectIdentifier ObjectID { get { return objectID; } } + /// <summary> + /// Return the parameters structure in the Parameters entry of this identifier. + /// </summary> public Asn1Encodable Parameters { get { return parameters; } diff --git a/crypto/src/crypto/ISignatureCalculator.cs b/crypto/src/crypto/ISignatureCalculator.cs new file mode 100644 index 000000000..2b7c0378e --- /dev/null +++ b/crypto/src/crypto/ISignatureCalculator.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + + +namespace Org.BouncyCastle.Crypto +{ + /// <summary> + /// Base interface for operators that serve as stream-based signature calculators. + /// </summary> + public interface ISignatureCalculator<out A> + { + /// <summary>The algorithm details object for this calculator.</summary> + A AlgorithmDetails { get ; } + + /// <summary>Return a "bucket" stream which only exists to update the calculator.</summary> + /// <returns>A stream to write to in order to update the calculator.</returns> + Stream GetSignatureUpdater (); // returns writable stream + + /// <summary> + /// Return a stream that wraps the passed in stream, the data written/read to + /// the returned stream will update the calculator as well as being passed through. + /// </summary> + /// <param name="stream">The stream to be wrapped, must be either readable or writeable, but not both</param> + /// <returns>A wrapped version of stream which updates the calculator.</returns> + Stream GetSignatureUpdatingStream (Stream stream); + + /// <summary>Calculate the signature and return it as a byte array.</summary> + /// <returns>The calculated signature.</returns> + byte[] Signature(); + + /// <summary>Calculate the signature and save it in the passed in byte array.</summary> + /// <param name="destination">The destination array to store the signature in.</param> + /// <param name="off">The offset into destination to start writing the signature.</param> + /// <returns>The number of bytes written to destination.</returns> + int Signature(byte[] destination, int off); + } +} + + diff --git a/crypto/src/crypto/ISignatureVerifier.cs b/crypto/src/crypto/ISignatureVerifier.cs new file mode 100644 index 000000000..10463259d --- /dev/null +++ b/crypto/src/crypto/ISignatureVerifier.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto +{ + /// <summary> + /// Base interface for operators that serve as stream-based signature verifiers. + /// </summary> + public interface ISignatureVerifier<out A> + { + /// <summary>The algorithm details object for this verifier.</summary> + A AlgorithmDetails { get ; } + + /// <summary>Return a "bucket" stream which only exists to update the verifier.</summary> + /// <returns>A stream to write to in order to update the verifier.</returns> + Stream GetVerifierUpdater (); + + /// <summary> + /// Return a stream that wraps the passed in stream, the data written/read to + /// the returned stream will update the verifier as well as being passed through. + /// </summary> + /// <param name="stream">The stream to be wrapped, must be either readable or writeable, but not both</param> + /// <returns>A wrapped version of stream which updates the verifier.</returns> + Stream GetVerifierUpdatingStream (Stream stream); + + /// <summary> + /// Return true if the passed in signature matches what is expected by the verifier. + /// </summary> + /// <param name="signature">The bytes representing the signature.</param> + /// <returns>true if the signature verifies, false otherwise.</returns> + bool IsVerified(byte[] signature); + + /// <summary> + /// Return true if the length bytes from off in the source array match the signature + /// expected by the verifier. + /// </summary> + /// <param name="source">Byte array containing the signature.</param> + /// <param name="off">The offset into the source array where the signature starts.</param> + /// <param name="length">The number of bytes in source making up the signature.</param> + /// <returns>true if the signature verifies, false otherwise.</returns> + bool IsVerified(byte[] source, int off, int length); + } +} diff --git a/crypto/src/crypto/ISignatureVerifierProvider.cs b/crypto/src/crypto/ISignatureVerifierProvider.cs new file mode 100644 index 000000000..39264f50e --- /dev/null +++ b/crypto/src/crypto/ISignatureVerifierProvider.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// <summary> + /// Base interface for a provider to support the dynamic creation of signature verifiers. + /// </summary> + public interface ISignatureVerifierProvider<A> + { + /// <summary> + /// Return a signature verfier for signature algorithm described in the passed in algorithm details object. + /// </summary> + /// <param name="algorithmDetails">The details of the signature algorithm verification is required for.</param> + /// <returns>A new signature verifier.</returns> + ISignatureVerifier<A> CreateSignatureVerifier (A algorithmDetails); + } +} + diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs new file mode 100644 index 000000000..8af46aa39 --- /dev/null +++ b/crypto/src/crypto/operators/Asn1Signature.cs @@ -0,0 +1,442 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Operators +{ + internal class X509Utilities + { + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary exParams = Platform.CreateHashtable(); + private static readonly ISet noParams = new HashSet(); + + static X509Utilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); + algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + noParams.Add(NistObjectIdentifiers.DsaWithSha384); + noParams.Add(NistObjectIdentifiers.DsaWithSha512); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (algorithms.Contains(algorithmName)) + { + return (DerObjectIdentifier) algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid, + string algorithmName) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (exParams.Contains(algorithmName)) + { + return new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable GetAlgNames() + { + return new EnumerableProxy(algorithms.Keys); + } + } + + internal class SignerBucket + : Stream + { + protected readonly ISigner signer; + + public SignerBucket( + ISigner signer) + { + this.signer = signer; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + throw new NotImplementedException (); + } + + public override int ReadByte() + { + throw new NotImplementedException (); + } + + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (count > 0) + { + signer.BlockUpdate(buffer, offset, count); + } + } + + public override void WriteByte( + byte b) + { + signer.Update(b); + } + + public override bool CanRead + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override long Length + { + get { return 0; } + } + + public override long Position + { + get { throw new NotImplementedException (); } + set { throw new NotImplementedException (); } + } + + public override void Close() + { + } + + public override void Flush() + { + } + + public override long Seek( + long offset, + SeekOrigin origin) + { + throw new NotImplementedException (); + } + + public override void SetLength( + long length) + { + throw new NotImplementedException (); + } + } + + /// <summary> + /// Calculator class for signature generation in ASN.1 based profiles that use an AlgorithmIdentifier to preserve + /// signature algorithm details. + /// </summary> + public class Asn1SignatureCalculator: ISignatureCalculator<AlgorithmIdentifier> + { + private readonly AlgorithmIdentifier algID; + private readonly ISigner sig; + + /// <summary> + /// Base constructor. + /// </summary> + /// <param name="algorithm">The name of the signature algorithm to use.</param> + /// <param name="privateKey">The private key to be used in the signing operation.</param> + public Asn1SignatureCalculator (String algorithm, AsymmetricKeyParameter privateKey): this(algorithm, privateKey, null) + { + } + + /// <summary> + /// Constructor which also specifies a source of randomness to be used if one is required. + /// </summary> + /// <param name="algorithm">The name of the signature algorithm to use.</param> + /// <param name="privateKey">The private key to be used in the signing operation.</param> + /// <param name="random">The source of randomness to be used in signature calculation.</param> + public Asn1SignatureCalculator (String algorithm, AsymmetricKeyParameter privateKey, SecureRandom random) + { + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid (algorithm); + + this.sig = SignerUtilities.GetSigner(algorithm); + + if (random != null) + { + sig.Init(true, new ParametersWithRandom(privateKey, random)); + } + else + { + sig.Init(true, privateKey); + } + + this.algID = X509Utilities.GetSigAlgID (sigOid, algorithm); + } + + public AlgorithmIdentifier AlgorithmDetails + { + get { return this.algID; } + } + + public Stream GetSignatureUpdater () + { + return new SignerBucket (sig); + } + + public Stream GetSignatureUpdatingStream (Stream stream) + { + if (stream.CanRead && stream.CanWrite) { + throw new ArgumentException ("cannot use read/write stream"); + } + + if (stream.CanRead) { + return new SignerStream (stream, sig, null); + } else { + return new SignerStream (stream, null, sig); + } + } + + public byte[] Signature() + { + return sig.GenerateSignature (); + } + + public int Signature(byte[] destination, int off) + { + byte[] sigBytes = Signature (); + + Array.Copy (sigBytes, 0, destination, off, sigBytes.Length); + + return sigBytes.Length; + } + + /// <summary> + /// Allows enumeration of the signature names supported by the verifier provider. + /// </summary> + public static IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } + + /// <summary> + /// Verifier class for signature verification in ASN.1 based profiles that use an AlgorithmIdentifier to preserve + /// signature algorithm details. + /// </summary> + public class Asn1SignatureVerifier: ISignatureVerifier<AlgorithmIdentifier> + { + private readonly AlgorithmIdentifier algID; + private readonly ISigner sig; + + /// <summary> + /// Base constructor. + /// </summary> + /// <param name="algorithm">The name of the signature algorithm to use.</param> + /// <param name="publicKey">The public key to be used in the verification operation.</param> + public Asn1SignatureVerifier (String algorithm, AsymmetricKeyParameter publicKey) + { + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid (algorithm); + + this.sig = SignerUtilities.GetSigner(algorithm); + + sig.Init(false, publicKey); + + this.algID = X509Utilities.GetSigAlgID (sigOid, algorithm); + } + + public Asn1SignatureVerifier (AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey) + { + DerObjectIdentifier sigOid = algorithm.Algorithm; + + this.sig = SignerUtilities.GetSigner(sigOid); + + sig.Init(false, publicKey); + + this.algID = algorithm; + } + + public AlgorithmIdentifier AlgorithmDetails + { + get { return this.algID; } + } + + public Stream GetVerifierUpdater () + { + return new SignerBucket (sig); + } + + public Stream GetVerifierUpdatingStream (Stream stream) + { + if (stream.CanRead && stream.CanWrite) { + throw new ArgumentException ("cannot use read/write stream"); + } + + if (stream.CanRead) { + return new SignerStream (stream, sig, null); + } else { + return new SignerStream (stream, null, sig); + } + } + + public bool IsVerified(byte[] signature) + { + return sig.VerifySignature(signature); + } + + public bool IsVerified(byte[] signature, int off, int length) + { + byte[] sigBytes = new byte[length]; + + Array.Copy (signature, 0, sigBytes, off, sigBytes.Length); + + return sig.VerifySignature(signature); + } + } + + /// <summary> + /// Provider class which supports dynamic creation of signature verifiers. + /// </summary> + public class Asn1SignatureVerifierProvider: ISignatureVerifierProvider<AlgorithmIdentifier> + { + private readonly AsymmetricKeyParameter publicKey; + + /// <summary> + /// Base constructor - specify the public key to be used in verification. + /// </summary> + /// <param name="publicKey">The public key to be used in creating verifiers provided by this object.</param> + public Asn1SignatureVerifierProvider(AsymmetricKeyParameter publicKey) + { + this.publicKey = publicKey; + } + + public ISignatureVerifier<AlgorithmIdentifier> CreateSignatureVerifier(AlgorithmIdentifier algorithmDetails) + { + return new Asn1SignatureVerifier (algorithmDetails, publicKey); + } + + /// <summary> + /// Allows enumeration of the signature names supported by the verifier provider. + /// </summary> + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} + diff --git a/crypto/src/x509/X509V1CertificateGenerator.cs b/crypto/src/x509/X509V1CertificateGenerator.cs index 02b58a198..8201a66ec 100644 --- a/crypto/src/x509/X509V1CertificateGenerator.cs +++ b/crypto/src/x509/X509V1CertificateGenerator.cs @@ -1,10 +1,12 @@ using System; +using System.IO; using System.Collections; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; @@ -119,6 +121,7 @@ namespace Org.BouncyCastle.X509 /// This can be either a name or an OID, names are treated as case insensitive. /// </summary> /// <param name="signatureAlgorithm">string representation of the algorithm name</param> + [Obsolete("Not needed if Generate used with an ISignatureCalculator")] public void SetSignatureAlgorithm( string signatureAlgorithm) { @@ -143,6 +146,7 @@ namespace Org.BouncyCastle.X509 /// </summary> /// <param name="privateKey">The private key of the issuer used to sign this certificate.</param> /// <returns>An X509Certificate.</returns> + [Obsolete("Use Generate with an ISignatureCalculator")] public X509Certificate Generate( AsymmetricKeyParameter privateKey) { @@ -155,43 +159,43 @@ namespace Org.BouncyCastle.X509 /// <param name="privateKey">The private key of the issuer used to sign this certificate.</param> /// <param name="random">The Secure Random you want to use.</param> /// <returns>An X509Certificate.</returns> + [Obsolete("Use Generate with an ISignatureCalculator")] public X509Certificate Generate( AsymmetricKeyParameter privateKey, SecureRandom random) { + return Generate(new Asn1SignatureCalculator(signatureAlgorithm, privateKey, random)); + } + + /// <summary> + /// Generate a new X509Certificate using the passed in SignatureCalculator. + /// </summary> + /// <param name="signatureCalculator">A signature calculator with the necessary algorithm details.</param> + /// <returns>An X509Certificate.</returns> + public X509Certificate Generate(ISignatureCalculator<AlgorithmIdentifier> signatureCalculator) + { + tbsGen.SetSignature (signatureCalculator.AlgorithmDetails); + TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); - byte[] signature; - try - { - signature = X509Utilities.GetSignatureForObject( - sigOID, signatureAlgorithm, privateKey, random, tbsCert); - } - catch (Exception e) - { - // TODO -// throw new ExtCertificateEncodingException("exception encoding TBS cert", e); - throw new CertificateEncodingException("exception encoding TBS cert", e); - } + Stream sigStream = signatureCalculator.GetSignatureUpdater (); - try - { - return GenerateJcaObject(tbsCert, signature); - } - catch (CertificateParsingException e) - { - // TODO - // throw new ExtCertificateEncodingException("exception producing certificate object", e); - throw new CertificateEncodingException("exception producing certificate object", e); - } + byte[] encoded = tbsCert.GetDerEncoded(); + + sigStream.Write (encoded, 0, encoded.Length); + + sigStream.Close (); + + return GenerateJcaObject(tbsCert, signatureCalculator.AlgorithmDetails, signatureCalculator.Signature()); } private X509Certificate GenerateJcaObject( TbsCertificateStructure tbsCert, + AlgorithmIdentifier sigAlg, byte[] signature) { return new X509Certificate( - new X509CertificateStructure(tbsCert, sigAlgId, new DerBitString(signature))); + new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature))); } /// <summary> diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs index a683d5e20..1cbdbcfcb 100644 --- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs +++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs @@ -8,6 +8,8 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Crypto.Operators; +using System.IO; namespace Org.BouncyCastle.X509 { @@ -66,12 +68,13 @@ namespace Org.BouncyCastle.X509 acInfoGen.SetEndDate(new DerGeneralizedTime(date)); } - /// <summary> - /// Set the signature algorithm. This can be either a name or an OID, names - /// are treated as case insensitive. - /// </summary> - /// <param name="signatureAlgorithm">The algorithm name.</param> - public void SetSignatureAlgorithm( + /// <summary> + /// Set the signature algorithm. This can be either a name or an OID, names + /// are treated as case insensitive. + /// </summary> + /// <param name="signatureAlgorithm">The algorithm name.</param> + [Obsolete("Not needed if Generate used with an ISignatureCalculator")] + public void SetSignatureAlgorithm( string signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; @@ -127,37 +130,57 @@ namespace Org.BouncyCastle.X509 extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); } - /// <summary> - /// Generate an X509 certificate, based on the current issuer and subject. - /// </summary> - public IX509AttributeCertificate Generate( - AsymmetricKeyParameter publicKey) + /// <summary> + /// Generate an X509 certificate, based on the current issuer and subject. + /// </summary> + [Obsolete("Use Generate with an ISignatureCalculator")] + public IX509AttributeCertificate Generate( + AsymmetricKeyParameter privateKey) { - return Generate(publicKey, null); + return Generate(privateKey, null); } - /// <summary> - /// Generate an X509 certificate, based on the current issuer and subject, - /// using the supplied source of randomness, if required. - /// </summary> - public IX509AttributeCertificate Generate( - AsymmetricKeyParameter publicKey, + /// <summary> + /// Generate an X509 certificate, based on the current issuer and subject, + /// using the supplied source of randomness, if required. + /// </summary> + [Obsolete("Use Generate with an ISignatureCalculator")] + public IX509AttributeCertificate Generate( + AsymmetricKeyParameter privateKey, SecureRandom random) - { - if (!extGenerator.IsEmpty) + { + return Generate(new Asn1SignatureCalculator(signatureAlgorithm, privateKey, random)); + } + + /// <summary> + /// Generate a new X.509 Attribute Certificate using the passed in SignatureCalculator. + /// </summary> + /// <param name="signatureCalculator">A signature calculator with the necessary algorithm details.</param> + /// <returns>An IX509AttributeCertificate.</returns> + public IX509AttributeCertificate Generate(ISignatureCalculator<AlgorithmIdentifier> signatureCalculator) + { + if (!extGenerator.IsEmpty) { acInfoGen.SetExtensions(extGenerator.Generate()); } AttributeCertificateInfo acInfo = acInfoGen.GenerateAttributeCertificateInfo(); - Asn1EncodableVector v = new Asn1EncodableVector(); + byte[] encoded = acInfo.GetDerEncoded(); + + Stream sigStream = signatureCalculator.GetSignatureUpdater(); + + sigStream.Write(encoded, 0, encoded.Length); + + sigStream.Close(); + + Asn1EncodableVector v = new Asn1EncodableVector(); - v.Add(acInfo, sigAlgId); + v.Add(acInfo, signatureCalculator.AlgorithmDetails); try { - v.Add(new DerBitString(X509Utilities.GetSignatureForObject(sigOID, signatureAlgorithm, publicKey, random, acInfo))); + v.Add(new DerBitString(signatureCalculator.Signature())); return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(new DerSequence(v))); } diff --git a/crypto/src/x509/X509V2CRLGenerator.cs b/crypto/src/x509/X509V2CRLGenerator.cs index a2293b333..ef0464a82 100644 --- a/crypto/src/x509/X509V2CRLGenerator.cs +++ b/crypto/src/x509/X509V2CRLGenerator.cs @@ -10,6 +10,7 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Crypto.Operators; namespace Org.BouncyCastle.X509 { @@ -129,13 +130,12 @@ namespace Org.BouncyCastle.X509 } } - /** - * Set the signature algorithm. This can be either a name or an oid, names - * are treated as case insensitive. - * - * @param signatureAlgorithm string representation of the algorithm name. - */ - public void SetSignatureAlgorithm( + /// <summary> + /// Set the signature algorithm that will be used to sign this CRL. + /// </summary> + /// <param name="signatureAlgorithm"/> + [Obsolete("Not needed if Generate used with an ISignatureCalculator")] + public void SetSignatureAlgorithm( string signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; @@ -198,40 +198,55 @@ namespace Org.BouncyCastle.X509 extGenerator.AddExtension(oid, critical, new DerOctetString(extensionValue)); } - /// <summary>Generate an X509 CRL, based on the current issuer and subject.</summary> - /// <param name="privateKey">The key used for signing.</param> - public X509Crl Generate( - AsymmetricKeyParameter privateKey) - { - return Generate(privateKey, null); - } + /// <summary> + /// Generate an X.509 CRL, based on the current issuer and subject. + /// </summary> + /// <param name="privateKey">The private key of the issuer that is signing this certificate.</param> + /// <returns>An X509Crl.</returns> + [Obsolete("Use Generate with an ISignatureCalculator")] + public X509Crl Generate( + AsymmetricKeyParameter privateKey) + { + return Generate(privateKey, null); + } - /// <summary>Generate an X509 CRL, based on the current issuer and subject.</summary> - /// <param name="privateKey">The key used for signing.</param> - /// <param name="random">A user-defined source of randomness.</param> - public X509Crl Generate( - AsymmetricKeyParameter privateKey, - SecureRandom random) - { - TbsCertificateList tbsCrl = GenerateCertList(); - byte[] signature; + /// <summary> + /// Generate an X.509 CRL, based on the current issuer and subject using the specified secure random. + /// </summary> + /// <param name="privateKey">The private key of the issuer that is signing this certificate.</param> + /// <param name="random">Your Secure Random instance.</param> + /// <returns>An X509Crl.</returns> + [Obsolete("Use Generate with an ISignatureCalculator")] + public X509Crl Generate( + AsymmetricKeyParameter privateKey, + SecureRandom random) + { + return Generate(new Asn1SignatureCalculator(signatureAlgorithm, privateKey, random)); + } - try - { - signature = X509Utilities.GetSignatureForObject( - sigOID, signatureAlgorithm, privateKey, random, tbsCrl); - } - catch (IOException e) - { - // TODO -// throw new ExtCrlException("cannot generate CRL encoding", e); - throw new CrlException("cannot generate CRL encoding", e); - } + /// <summary> + /// Generate a new X509Crl using the passed in SignatureCalculator. + /// </summary> + /// <param name="signatureCalculator">A signature calculator with the necessary algorithm details.</param> + /// <returns>An X509Crl.</returns> + public X509Crl Generate(ISignatureCalculator<AlgorithmIdentifier> signatureCalculator) + { + tbsGen.SetSignature(signatureCalculator.AlgorithmDetails); - return GenerateJcaObject(tbsCrl, signature); - } + TbsCertificateList tbsCertList = GenerateCertList(); + + Stream sigStream = signatureCalculator.GetSignatureUpdater(); + + byte[] encoded = tbsCertList.GetDerEncoded(); + + sigStream.Write(encoded, 0, encoded.Length); + + sigStream.Close(); + + return GenerateJcaObject(tbsCertList, signatureCalculator.AlgorithmDetails, signatureCalculator.Signature()); + } - private TbsCertificateList GenerateCertList() + private TbsCertificateList GenerateCertList() { if (!extGenerator.IsEmpty) { @@ -243,11 +258,12 @@ namespace Org.BouncyCastle.X509 private X509Crl GenerateJcaObject( TbsCertificateList tbsCrl, + AlgorithmIdentifier algId, byte[] signature) { return new X509Crl( CertificateList.GetInstance( - new DerSequence(tbsCrl, sigAlgId, new DerBitString(signature)))); + new DerSequence(tbsCrl, algId, new DerBitString(signature)))); } /// <summary> diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs index bb0dd9cbc..252b91aa4 100644 --- a/crypto/src/x509/X509V3CertificateGenerator.cs +++ b/crypto/src/x509/X509V3CertificateGenerator.cs @@ -1,9 +1,11 @@ using System; using System.Collections; +using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; @@ -110,6 +112,7 @@ namespace Org.BouncyCastle.X509 /// Set the signature algorithm that will be used to sign this certificate. /// </summary> /// <param name="signatureAlgorithm"/> + [Obsolete("Not needed if Generate used with an ISignatureCalculator")] public void SetSignatureAlgorithm( string signatureAlgorithm) { @@ -274,7 +277,8 @@ namespace Org.BouncyCastle.X509 /// </summary> /// <param name="privateKey">The private key of the issuer that is signing this certificate.</param> /// <returns>An X509Certificate.</returns> - public X509Certificate Generate( + [Obsolete("Use Generate with an ISignatureCalculator")] + public X509Certificate Generate( AsymmetricKeyParameter privateKey) { return Generate(privateKey, null); @@ -286,53 +290,48 @@ namespace Org.BouncyCastle.X509 /// <param name="privateKey">The private key of the issuer that is signing this certificate.</param> /// <param name="random">You Secure Random instance.</param> /// <returns>An X509Certificate.</returns> + [Obsolete("Use Generate with an ISignatureCalculator")] public X509Certificate Generate( AsymmetricKeyParameter privateKey, SecureRandom random) { - TbsCertificateStructure tbsCert = GenerateTbsCert(); - byte[] signature; - - try - { - signature = X509Utilities.GetSignatureForObject( - sigOid, signatureAlgorithm, privateKey, random, tbsCert); - } - catch (Exception e) - { - // TODO -// throw new ExtCertificateEncodingException("exception encoding TBS cert", e); - throw new CertificateEncodingException("exception encoding TBS cert", e); - } - - try - { - return GenerateJcaObject(tbsCert, signature); - } - catch (CertificateParsingException e) - { - // TODO - // throw new ExtCertificateEncodingException("exception producing certificate object", e); - throw new CertificateEncodingException("exception producing certificate object", e); - } + return Generate(new Asn1SignatureCalculator(signatureAlgorithm, privateKey, random)); } - private TbsCertificateStructure GenerateTbsCert() + /// <summary> + /// Generate a new X509Certificate using the passed in SignatureCalculator. + /// </summary> + /// <param name="signatureCalculator">A signature calculator with the necessary algorithm details.</param> + /// <returns>An X509Certificate.</returns> + public X509Certificate Generate(ISignatureCalculator<AlgorithmIdentifier> signatureCalculator) { - if (!extGenerator.IsEmpty) - { - tbsGen.SetExtensions(extGenerator.Generate()); - } + tbsGen.SetSignature (signatureCalculator.AlgorithmDetails); + + if (!extGenerator.IsEmpty) + { + tbsGen.SetExtensions(extGenerator.Generate()); + } + + TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); + + Stream sigStream = signatureCalculator.GetSignatureUpdater (); + + byte[] encoded = tbsCert.GetDerEncoded(); + + sigStream.Write (encoded, 0, encoded.Length); + + sigStream.Close (); - return tbsGen.GenerateTbsCertificate(); + return GenerateJcaObject(tbsCert, signatureCalculator.AlgorithmDetails, signatureCalculator.Signature()); } private X509Certificate GenerateJcaObject( TbsCertificateStructure tbsCert, + AlgorithmIdentifier sigAlg, byte[] signature) { return new X509Certificate( - new X509CertificateStructure(tbsCert, sigAlgId, new DerBitString(signature))); + new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature))); } /// <summary> |