diff --git a/crypto/src/asn1/x509/TBSCertList.cs b/crypto/src/asn1/x509/TBSCertList.cs
index 4cfb44c90..fb8a9907c 100644
--- a/crypto/src/asn1/x509/TBSCertList.cs
+++ b/crypto/src/asn1/x509/TBSCertList.cs
@@ -144,32 +144,21 @@ namespace Org.BouncyCastle.Asn1.X509
internal Asn1Sequence revokedCertificates;
internal X509Extensions crlExtensions;
- public static TbsCertificateList GetInstance(
- Asn1TaggedObject obj,
- bool explicitly)
+ public static TbsCertificateList GetInstance(object obj)
{
- return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ if (obj == null)
+ return null;
+ if (obj is TbsCertificateList tbsCertificateList)
+ return tbsCertificateList;
+ return new TbsCertificateList(Asn1Sequence.GetInstance(obj));
}
- public static TbsCertificateList GetInstance(
- object obj)
+ public static TbsCertificateList GetInstance(Asn1TaggedObject obj, bool explicitly)
{
- TbsCertificateList list = obj as TbsCertificateList;
-
- if (obj == null || list != null)
- {
- return list;
- }
-
- if (obj is Asn1Sequence)
- {
- return new TbsCertificateList((Asn1Sequence) obj);
- }
-
- throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj");
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
}
- internal TbsCertificateList(Asn1Sequence seq)
+ private TbsCertificateList(Asn1Sequence seq)
{
if (seq.Count < 3 || seq.Count > 7)
throw new ArgumentException("Bad sequence size: " + seq.Count);
diff --git a/crypto/src/asn1/x509/TBSCertificateStructure.cs b/crypto/src/asn1/x509/TBSCertificateStructure.cs
index e1fba2488..e41224f4a 100644
--- a/crypto/src/asn1/x509/TBSCertificateStructure.cs
+++ b/crypto/src/asn1/x509/TBSCertificateStructure.cs
@@ -39,27 +39,21 @@ namespace Org.BouncyCastle.Asn1.X509
internal DerBitString subjectUniqueID;
internal X509Extensions extensions;
- public static TbsCertificateStructure GetInstance(
- Asn1TaggedObject obj,
- bool explicitly)
- {
- return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
- }
-
- public static TbsCertificateStructure GetInstance(
- object obj)
- {
- if (obj is TbsCertificateStructure)
- return (TbsCertificateStructure) obj;
-
- if (obj != null)
- return new TbsCertificateStructure(Asn1Sequence.GetInstance(obj));
+ public static TbsCertificateStructure GetInstance(object obj)
+ {
+ if (obj == null)
+ return null;
+ if (obj is TbsCertificateStructure tbsCertificateStructure)
+ return tbsCertificateStructure;
+ return new TbsCertificateStructure(Asn1Sequence.GetInstance(obj));
+ }
- return null;
- }
+ public static TbsCertificateStructure GetInstance(Asn1TaggedObject obj, bool explicitly)
+ {
+ return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+ }
- internal TbsCertificateStructure(
- Asn1Sequence seq)
+ private TbsCertificateStructure(Asn1Sequence seq)
{
int seqStart = 0;
diff --git a/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs b/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs
index 9cbff1ef0..7c191b263 100644
--- a/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs
+++ b/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs
@@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Asn1.X509
throw new InvalidOperationException("not all mandatory fields set in V1 TBScertificate generator");
}
- return new TbsCertificateStructure(
+ return TbsCertificateStructure.GetInstance(
new DerSequence(
//version, - not required as default value
serialNumber,
diff --git a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs
index bf016c22d..d744ed664 100644
--- a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs
+++ b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs
@@ -40,40 +40,34 @@ namespace Org.BouncyCastle.Asn1.X509
{
}
- public void SetSignature(
- AlgorithmIdentifier signature)
+ public void SetSignature(AlgorithmIdentifier signature)
{
this.signature = signature;
}
- public void SetIssuer(
- X509Name issuer)
+ public void SetIssuer(X509Name issuer)
{
this.issuer = issuer;
}
- public void SetThisUpdate(
- Asn1UtcTime thisUpdate)
+ public void SetThisUpdate(Asn1UtcTime thisUpdate)
{
this.thisUpdate = new Time(thisUpdate);
}
- public void SetNextUpdate(
- Asn1UtcTime nextUpdate)
+ public void SetNextUpdate(Asn1UtcTime nextUpdate)
{
this.nextUpdate = (nextUpdate != null)
? new Time(nextUpdate)
: null;
}
- public void SetThisUpdate(
- Time thisUpdate)
+ public void SetThisUpdate(Time thisUpdate)
{
this.thisUpdate = thisUpdate;
}
- public void SetNextUpdate(
- Time nextUpdate)
+ public void SetNextUpdate(Time nextUpdate)
{
this.nextUpdate = nextUpdate;
}
@@ -154,39 +148,49 @@ namespace Org.BouncyCastle.Asn1.X509
AddCrlEntry(new DerSequence(v));
}
- public void SetExtensions(
- X509Extensions extensions)
+ public void SetExtensions(X509Extensions extensions)
{
this.extensions = extensions;
}
- public TbsCertificateList GenerateTbsCertList()
+ public Asn1Sequence GeneratePreTbsCertList()
+ {
+ if (signature != null)
+ throw new InvalidOperationException("signature should not be set in PreTBSCertList generator");
+
+ if ((issuer == null) || (thisUpdate == null))
+ throw new InvalidOperationException("Not all mandatory fields set in V2 PreTBSCertList generator");
+
+ return GenerateTbsCertificateStructure();
+ }
+
+ public TbsCertificateList GenerateTbsCertList()
{
if ((signature == null) || (issuer == null) || (thisUpdate == null))
- {
throw new InvalidOperationException("Not all mandatory fields set in V2 TbsCertList generator.");
- }
- Asn1EncodableVector v = new Asn1EncodableVector(
- version, signature, issuer, thisUpdate);
+ return TbsCertificateList.GetInstance(GenerateTbsCertificateStructure());
+ }
- if (nextUpdate != null)
- {
- v.Add(nextUpdate);
- }
+ private Asn1Sequence GenerateTbsCertificateStructure()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(7);
- // Add CRLEntries if they exist
- if (crlEntries != null)
- {
- v.Add(new DerSequence(crlEntries.ToArray()));
- }
+ v.Add(version);
+ v.AddOptional(signature);
+ v.Add(issuer);
+ v.Add(thisUpdate);
+ v.AddOptional(nextUpdate);
- if (extensions != null)
+ // Add CRLEntries if they exist
+ if (crlEntries != null && crlEntries.Count > 0)
{
- v.Add(new DerTaggedObject(0, extensions));
+ v.Add(new DerSequence(crlEntries.ToArray()));
}
- return new TbsCertificateList(new DerSequence(v));
+ v.AddOptionalTagged(true, 0, extensions);
+
+ return new DerSequence(v);
}
}
}
diff --git a/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs b/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs
index 544582ddb..f58e4a7ab 100644
--- a/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs
+++ b/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs
@@ -39,74 +39,62 @@ namespace Org.BouncyCastle.Asn1.X509
{
}
- public void SetSerialNumber(
- DerInteger serialNumber)
+ public void SetSerialNumber(DerInteger serialNumber)
{
this.serialNumber = serialNumber;
}
- public void SetSignature(
- AlgorithmIdentifier signature)
+ public void SetSignature(AlgorithmIdentifier signature)
{
this.signature = signature;
}
- public void SetIssuer(
- X509Name issuer)
+ public void SetIssuer(X509Name issuer)
{
this.issuer = issuer;
}
- public void SetStartDate(
- Asn1UtcTime startDate)
+ public void SetStartDate(Asn1UtcTime startDate)
{
this.startDate = new Time(startDate);
}
- public void SetStartDate(
- Time startDate)
+ public void SetStartDate(Time startDate)
{
this.startDate = startDate;
}
- public void SetEndDate(
- Asn1UtcTime endDate)
+ public void SetEndDate(Asn1UtcTime endDate)
{
this.endDate = new Time(endDate);
}
- public void SetEndDate(
- Time endDate)
+ public void SetEndDate(Time endDate)
{
this.endDate = endDate;
}
- public void SetSubject(
- X509Name subject)
+ public void SetSubject(X509Name subject)
{
this.subject = subject;
}
- public void SetIssuerUniqueID(
- DerBitString uniqueID)
+ public void SetIssuerUniqueID(DerBitString uniqueID)
{
this.issuerUniqueID = uniqueID;
}
- public void SetSubjectUniqueID(
- DerBitString uniqueID)
+ public void SetSubjectUniqueID(DerBitString uniqueID)
{
this.subjectUniqueID = uniqueID;
}
- public void SetSubjectPublicKeyInfo(
- SubjectPublicKeyInfo pubKeyInfo)
+ public void SetSubjectPublicKeyInfo(SubjectPublicKeyInfo pubKeyInfo)
{
this.subjectPublicKeyInfo = pubKeyInfo;
}
- public void SetExtensions(
- X509Extensions extensions)
+ public void SetExtensions(X509Extensions extensions)
{
this.extensions = extensions;
@@ -121,48 +109,62 @@ namespace Org.BouncyCastle.Asn1.X509
}
}
- public TbsCertificateStructure GenerateTbsCertificate()
+ public Asn1Sequence GeneratePreTbsCertificate()
{
- if ((serialNumber == null) || (signature == null)
+ if (signature != null)
+ throw new InvalidOperationException("signature field should not be set in PreTBSCertificate");
+
+ if ((serialNumber == null)
|| (issuer == null) || (startDate == null) || (endDate == null)
- || (subject == null && !altNamePresentAndCritical)
- || (subjectPublicKeyInfo == null))
+ || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
{
throw new InvalidOperationException("not all mandatory fields set in V3 TBScertificate generator");
}
- DerSequence validity = new DerSequence(startDate, endDate); // before and after dates
+ return GenerateTbsStructure();
+ }
- Asn1EncodableVector v = new Asn1EncodableVector(
- version, serialNumber, signature, issuer, validity);
+ public TbsCertificateStructure GenerateTbsCertificate()
+ {
+ if ((serialNumber == null) || (signature == null)
+ || (issuer == null) || (startDate == null) || (endDate == null)
+ || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
+ {
+ throw new InvalidOperationException("not all mandatory fields set in V3 TBScertificate generator");
+ }
- if (subject != null)
- {
- v.Add(subject);
- }
- else
- {
- v.Add(DerSequence.Empty);
- }
+ return TbsCertificateStructure.GetInstance(GenerateTbsStructure());
+ }
- v.Add(subjectPublicKeyInfo);
+ private Asn1Sequence GenerateTbsStructure()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector(10);
- if (issuerUniqueID != null)
- {
- v.Add(new DerTaggedObject(false, 1, issuerUniqueID));
- }
+ v.Add(version);
+ v.Add(serialNumber);
+ v.AddOptional(signature);
+ v.Add(issuer);
- if (subjectUniqueID != null)
- {
- v.Add(new DerTaggedObject(false, 2, subjectUniqueID));
- }
+ //
+ // before and after dates
+ //
+ v.Add(new DerSequence(startDate, endDate));
- if (extensions != null)
+ if (subject != null)
{
- v.Add(new DerTaggedObject(3, extensions));
+ v.Add(subject);
}
+ else
+ {
+ v.Add(DerSequence.Empty);
+ }
+
+ v.Add(subjectPublicKeyInfo);
+ v.AddOptionalTagged(false, 1, issuerUniqueID);
+ v.AddOptionalTagged(false, 2, subjectUniqueID);
+ v.AddOptionalTagged(true, 3, extensions);
- return new TbsCertificateStructure(new DerSequence(v));
+ return new DerSequence(v);
}
}
}
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs
index cd3d6d680..39df381df 100644
--- a/crypto/src/x509/X509Certificate.cs
+++ b/crypto/src/x509/X509Certificate.cs
@@ -638,8 +638,7 @@ namespace Org.BouncyCastle.X509
/// <param name="key">An appropriate public key parameter object, RsaPublicKeyParameters, DsaPublicKeyParameters or ECDsaPublicKeyParameters</param>
/// <returns>True if the signature is valid.</returns>
/// <exception cref="Exception">If key submitted is not of the above nominated types.</exception>
- public virtual void Verify(
- AsymmetricKeyParameter key)
+ public virtual void Verify(AsymmetricKeyParameter key)
{
CheckSignature(new Asn1VerifierFactory(c.SignatureAlgorithm, key));
}
@@ -648,27 +647,54 @@ namespace Org.BouncyCastle.X509
/// Verify the certificate's signature using a verifier created using the passed in verifier provider.
/// </summary>
/// <param name="verifierProvider">An appropriate provider for verifying the certificate's signature.</param>
- /// <returns>True if the signature is valid.</returns>
- /// <exception cref="Exception">If verifier provider is not appropriate or the certificate algorithm is invalid.</exception>
- public virtual void Verify(
- IVerifierFactoryProvider verifierProvider)
+ /// <exception cref="Exception">If verifier provider is not appropriate or the certificate signature algorithm
+ /// is invalid.</exception>
+ public virtual void Verify(IVerifierFactoryProvider verifierProvider)
{
CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm));
}
- protected virtual void CheckSignature(
- IVerifierFactory verifier)
+ /// <summary>Verify the certificate's alternative signature using a verifier created using the passed in
+ /// verifier provider.</summary>
+ /// <param name="verifierProvider">An appropriate provider for verifying the certificate's alternative
+ /// signature.</param>
+ /// <exception cref="Exception">If verifier provider is not appropriate or the certificate alternative signature
+ /// algorithm is invalid.</exception>
+ public virtual void VerifyAltSignature(IVerifierFactoryProvider verifierProvider)
{
- if (!IsAlgIDEqual(c.SignatureAlgorithm, c.TbsCertificate.Signature))
- throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
+ var tbsCertificate = c.TbsCertificate;
+ var extensions = tbsCertificate.Extensions;
+
+ AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.FromExtensions(extensions);
+ AltSignatureValue altSigValue = AltSignatureValue.FromExtensions(extensions);
+
+ var verifier = verifierProvider.CreateVerifierFactory(altSigAlg.Algorithm);
- IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator();
- using (var stream = streamCalculator.Stream)
+ Asn1Sequence tbsSeq = Asn1Sequence.GetInstance(tbsCertificate.ToAsn1Object());
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ for (int i = 0; i < tbsSeq.Count - 1; i++)
{
- c.TbsCertificate.EncodeTo(stream, Asn1Encodable.Der);
+ if (i != 2) // signature field - must be ver 3 so version always present
+ {
+ v.Add(tbsSeq[i]);
+ }
}
- if (!streamCalculator.GetResult().IsVerified(GetSignature()))
+ v.Add(X509Utilities.TrimExtensions(3, extensions));
+
+ if (!X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature))
+ throw new InvalidKeyException("Public key presented not for certificate alternative signature");
+ }
+
+ protected virtual void CheckSignature(IVerifierFactory verifier)
+ {
+ var tbsCertificate = c.TbsCertificate;
+
+ if (!IsAlgIDEqual(c.SignatureAlgorithm, tbsCertificate.Signature))
+ throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
+
+ if (!X509Utilities.VerifySignature(verifier, tbsCertificate, c.Signature))
throw new InvalidKeyException("Public key presented not for certificate signature");
}
diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs
index 81dd1c20e..1fc13a0a2 100644
--- a/crypto/src/x509/X509Crl.cs
+++ b/crypto/src/x509/X509Crl.cs
@@ -104,8 +104,7 @@ namespace Org.BouncyCastle.X509
: null;
}
- public virtual void Verify(
- AsymmetricKeyParameter publicKey)
+ public virtual void Verify(AsymmetricKeyParameter publicKey)
{
Verify(new Asn1VerifierFactoryProvider(publicKey));
}
@@ -116,26 +115,57 @@ namespace Org.BouncyCastle.X509
/// <param name="verifierProvider">An appropriate provider for verifying the CRL's signature.</param>
/// <returns>True if the signature is valid.</returns>
/// <exception cref="Exception">If verifier provider is not appropriate or the CRL algorithm is invalid.</exception>
- public virtual void Verify(
- IVerifierFactoryProvider verifierProvider)
+ public virtual void Verify(IVerifierFactoryProvider verifierProvider)
{
CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm));
}
- protected virtual void CheckSignature(
- IVerifierFactory verifier)
+ /// <summary>Verify the CRL's alternative signature using a verifier created using the passed in
+ /// verifier provider.</summary>
+ /// <param name="verifierProvider">An appropriate provider for verifying the CRL's alternative signature.
+ /// </param>
+ /// <exception cref="Exception">If verifier provider is not appropriate or the CRL alternative signature
+ /// algorithm is invalid.</exception>
+ public virtual void VerifyAltSignature(IVerifierFactoryProvider verifierProvider)
{
- // TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature
- if (!c.SignatureAlgorithm.Equals(c.TbsCertList.Signature))
- throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList.");
+ var tbsCertList = c.TbsCertList;
+ var extensions = tbsCertList.Extensions;
+
+ AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.FromExtensions(extensions);
+ AltSignatureValue altSigValue = AltSignatureValue.FromExtensions(extensions);
+
+ var verifier = verifierProvider.CreateVerifierFactory(altSigAlg.Algorithm);
+
+ Asn1Sequence tbsSeq = Asn1Sequence.GetInstance(tbsCertList.ToAsn1Object());
+ Asn1EncodableVector v = new Asn1EncodableVector();
- IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator();
- using (var stream = streamCalculator.Stream)
+ int start = 1; // want to skip signature field
+ if (tbsSeq[0] is DerInteger derInteger)
+ {
+ v.Add(derInteger);
+ start++;
+ }
+
+ for (int i = start; i < tbsSeq.Count - 1; i++)
{
- c.TbsCertList.EncodeTo(stream, Asn1Encodable.Der);
- }
+ v.Add(tbsSeq[i]);
+ }
+
+ v.Add(X509Utilities.TrimExtensions(0, extensions));
+
+ if (!X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature))
+ throw new InvalidKeyException("CRL alternative signature does not verify with supplied public key.");
+ }
+
+ protected virtual void CheckSignature(IVerifierFactory verifier)
+ {
+ var tbsCertList = c.TbsCertList;
+
+ // TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature
+ if (!c.SignatureAlgorithm.Equals(tbsCertList.Signature))
+ throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList.");
- if (!streamCalculator.GetResult().IsVerified(GetSignature()))
+ if (!X509Utilities.VerifySignature(verifier, tbsCertList, c.Signature))
throw new InvalidKeyException("CRL does not verify with supplied public key.");
}
diff --git a/crypto/src/x509/X509Utilities.cs b/crypto/src/x509/X509Utilities.cs
index 30ca0b080..bb9b7155f 100644
--- a/crypto/src/x509/X509Utilities.cs
+++ b/crypto/src/x509/X509Utilities.cs
@@ -9,6 +9,7 @@ using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.X509
@@ -159,5 +160,45 @@ namespace Org.BouncyCastle.X509
{
return CollectionUtilities.Proxy(m_algorithms.Keys);
}
- }
+
+ internal static DerBitString GenerateSignature(ISignatureFactory signatureFactory, Asn1Encodable asn1Encodable)
+ {
+ var result = CalculateResult(signatureFactory.CreateCalculator(), asn1Encodable);
+ return new DerBitString(result.Collect());
+ }
+
+ internal static bool VerifySignature(IVerifierFactory verifierFactory, Asn1Encodable asn1Encodable,
+ DerBitString signature)
+ {
+ var result = CalculateResult(verifierFactory.CreateCalculator(), asn1Encodable);
+ return result.IsVerified(signature.GetOctets());
+ }
+
+ internal static Asn1TaggedObject TrimExtensions(int tagNo, X509Extensions exts)
+ {
+ Asn1Sequence extSeq = Asn1Sequence.GetInstance(exts.ToAsn1Object());
+ Asn1EncodableVector extV = new Asn1EncodableVector();
+ foreach (var extEntry in extSeq)
+ {
+ Asn1Sequence ext = Asn1Sequence.GetInstance(extEntry);
+
+ if (!X509Extensions.AltSignatureValue.Equals(ext[0]))
+ {
+ extV.Add(ext);
+ }
+ }
+
+ return new DerTaggedObject(true, tagNo, new DerSequence(extV));
+ }
+
+ private static TResult CalculateResult<TResult>(IStreamCalculator<TResult> streamCalculator,
+ Asn1Encodable asn1Encodable)
+ {
+ using (var stream = streamCalculator.Stream)
+ {
+ asn1Encodable.EncodeTo(stream, Asn1Encodable.Der);
+ }
+ return streamCalculator.GetResult();
+ }
+ }
}
diff --git a/crypto/src/x509/X509V2AttributeCertificate.cs b/crypto/src/x509/X509V2AttributeCertificate.cs
index 836213fdc..963f1ea4f 100644
--- a/crypto/src/x509/X509V2AttributeCertificate.cs
+++ b/crypto/src/x509/X509V2AttributeCertificate.cs
@@ -161,8 +161,7 @@ namespace Org.BouncyCastle.X509
return cert.GetSignatureOctets();
}
- public virtual void Verify(
- AsymmetricKeyParameter key)
+ public virtual void Verify(AsymmetricKeyParameter key)
{
CheckSignature(new Asn1VerifierFactory(cert.SignatureAlgorithm, key));
}
@@ -173,34 +172,20 @@ namespace Org.BouncyCastle.X509
/// <param name="verifierProvider">An appropriate provider for verifying the certificate's signature.</param>
/// <returns>True if the signature is valid.</returns>
/// <exception cref="Exception">If verifier provider is not appropriate or the certificate algorithm is invalid.</exception>
- public virtual void Verify(
- IVerifierFactoryProvider verifierProvider)
+ public virtual void Verify(IVerifierFactoryProvider verifierProvider)
{
CheckSignature(verifierProvider.CreateVerifierFactory(cert.SignatureAlgorithm));
}
- protected virtual void CheckSignature(
- IVerifierFactory verifier)
+ protected virtual void CheckSignature(IVerifierFactory verifier)
{
+ var acInfo = cert.ACInfo;
+
// TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature
- if (!cert.SignatureAlgorithm.Equals(cert.ACInfo.Signature))
+ if (!cert.SignatureAlgorithm.Equals(acInfo.Signature))
throw new CertificateException("Signature algorithm in certificate info not same as outer certificate");
- IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator();
-
- try
- {
- using (var stream = streamCalculator.Stream)
- {
- cert.ACInfo.EncodeTo(stream);
- }
- }
- catch (IOException e)
- {
- throw new SignatureException("Exception encoding certificate info object", e);
- }
-
- if (!streamCalculator.GetResult().IsVerified(GetSignature()))
+ if (!X509Utilities.VerifySignature(verifier, acInfo, cert.SignatureValue))
throw new InvalidKeyException("Public key presented not for certificate signature");
}
diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
index f1f4c0473..bbb246273 100644
--- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
+++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
@@ -117,24 +117,17 @@ namespace Org.BouncyCastle.X509
acInfoGen.SetExtensions(extGenerator.Generate());
}
- AttributeCertificateInfo acInfo = acInfoGen.GenerateAttributeCertificateInfo();
+ var acInfo = acInfoGen.GenerateAttributeCertificateInfo();
- IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator();
- using (var sigStream = streamCalculator.Stream)
- {
- acInfo.EncodeTo(sigStream, Asn1Encodable.Der);
- }
-
- var signature = streamCalculator.GetResult().Collect();
+ var signature = X509Utilities.GenerateSignature(signatureFactory, acInfo);
- return new X509V2AttributeCertificate(
- new AttributeCertificate(acInfo, sigAlgID, new DerBitString(signature)));
+ return new X509V2AttributeCertificate(new AttributeCertificate(acInfo, sigAlgID, signature));
}
- /// <summary>
- /// Allows enumeration of the signature names supported by the generator.
- /// </summary>
- public IEnumerable<string> SignatureAlgNames
+ /// <summary>
+ /// Allows enumeration of the signature names supported by the generator.
+ /// </summary>
+ public IEnumerable<string> SignatureAlgNames
{
get { return X509Utilities.GetAlgNames(); }
}
diff --git a/crypto/src/x509/X509V2CRLGenerator.cs b/crypto/src/x509/X509V2CRLGenerator.cs
index d7c72d673..358dc63de 100644
--- a/crypto/src/x509/X509V2CRLGenerator.cs
+++ b/crypto/src/x509/X509V2CRLGenerator.cs
@@ -217,18 +217,38 @@ namespace Org.BouncyCastle.X509
tbsGen.SetExtensions(extGenerator.Generate());
}
- TbsCertificateList tbsCertList = tbsGen.GenerateTbsCertList();
+ var tbsCertList = tbsGen.GenerateTbsCertList();
- IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator();
- using (var sigStream = streamCalculator.Stream)
- {
- tbsCertList.EncodeTo(sigStream, Asn1Encodable.Der);
- }
+ var signature = X509Utilities.GenerateSignature(signatureFactory, tbsCertList);
+
+ return new X509Crl(CertificateList.GetInstance(new DerSequence(tbsCertList, sigAlgID, signature)));
+ }
+
+ /// <summary>
+ /// Generate a new <see cref="X509Crl"/> using the provided <see cref="ISignatureFactory"/> and
+ /// containing altSignatureAlgorithm and altSignatureValue extensions based on the passed
+ /// <paramref name="altSignatureFactory"/>.
+ /// </summary>
+ /// <param name="signatureFactory">A <see cref="ISignatureFactory">signature factory</see> with the necessary
+ /// algorithm details.</param>
+ /// <param name="isCritical">Whether the 'alt' extensions should be marked critical.</param>
+ /// <param name="altSignatureFactory">A <see cref="ISignatureFactory">signature factory</see> used to create the
+ /// altSignatureAlgorithm and altSignatureValue extensions.</param>
+ /// <returns>An <see cref="X509Certificate"/>.</returns>
+ public X509Crl Generate(ISignatureFactory signatureFactory, bool isCritical,
+ ISignatureFactory altSignatureFactory)
+ {
+ tbsGen.SetSignature(null);
+
+ var altSigAlgID = (AlgorithmIdentifier)altSignatureFactory.AlgorithmDetails;
+ extGenerator.AddExtension(X509Extensions.AltSignatureAlgorithm, isCritical, altSigAlgID);
+
+ tbsGen.SetExtensions(extGenerator.Generate());
- var signature = streamCalculator.GetResult().Collect();
+ var altSignature = X509Utilities.GenerateSignature(altSignatureFactory, tbsGen.GeneratePreTbsCertList());
+ extGenerator.AddExtension(X509Extensions.AltSignatureValue, isCritical, altSignature);
- return new X509Crl(
- CertificateList.GetInstance(new DerSequence(tbsCertList, sigAlgID, new DerBitString(signature))));
+ return Generate(signatureFactory);
}
/// <summary>
diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs
index d5c9ffe92..65e3c9177 100644
--- a/crypto/src/x509/X509V3CertificateGenerator.cs
+++ b/crypto/src/x509/X509V3CertificateGenerator.cs
@@ -290,17 +290,38 @@ namespace Org.BouncyCastle.X509
tbsGen.SetExtensions(extGenerator.Generate());
}
- TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate();
+ var tbsCertificate = tbsGen.GenerateTbsCertificate();
- IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator();
- using (var sigStream = streamCalculator.Stream)
- {
- tbsCert.EncodeTo(sigStream, Asn1Encodable.Der);
- }
+ var signature = X509Utilities.GenerateSignature(signatureFactory, tbsCertificate);
+
+ return new X509Certificate(new X509CertificateStructure(tbsCertificate, sigAlgID, signature));
+ }
+
+ /// <summary>
+ /// Generate a new <see cref="X509Certificate"/> using the provided <see cref="ISignatureFactory"/> and
+ /// containing altSignatureAlgorithm and altSignatureValue extensions based on the passed
+ /// <paramref name="altSignatureFactory"/>.
+ /// </summary>
+ /// <param name="signatureFactory">A <see cref="ISignatureFactory">signature factory</see> with the necessary
+ /// algorithm details.</param>
+ /// <param name="isCritical">Whether the 'alt' extensions should be marked critical.</param>
+ /// <param name="altSignatureFactory">A <see cref="ISignatureFactory">signature factory</see> used to create the
+ /// altSignatureAlgorithm and altSignatureValue extensions.</param>
+ /// <returns>An <see cref="X509Certificate"/>.</returns>
+ public X509Certificate Generate(ISignatureFactory signatureFactory, bool isCritical,
+ ISignatureFactory altSignatureFactory)
+ {
+ tbsGen.SetSignature(null);
+
+ var altSigAlgID = (AlgorithmIdentifier)altSignatureFactory.AlgorithmDetails;
+ extGenerator.AddExtension(X509Extensions.AltSignatureAlgorithm, isCritical, altSigAlgID);
+
+ tbsGen.SetExtensions(extGenerator.Generate());
- var signature = streamCalculator.GetResult().Collect();
+ var altSignature = X509Utilities.GenerateSignature(altSignatureFactory, tbsGen.GeneratePreTbsCertificate());
+ extGenerator.AddExtension(X509Extensions.AltSignatureValue, isCritical, altSignature);
- return new X509Certificate(new X509CertificateStructure(tbsCert, sigAlgID, new DerBitString(signature)));
+ return Generate(signatureFactory);
}
/// <summary>
|