diff --git a/crypto/src/asn1/cmp/CertStatus.cs b/crypto/src/asn1/cmp/CertStatus.cs
index b64a0fe84..29db607d7 100644
--- a/crypto/src/asn1/cmp/CertStatus.cs
+++ b/crypto/src/asn1/cmp/CertStatus.cs
@@ -52,10 +52,15 @@ namespace Org.BouncyCastle.Asn1.Cmp
}
}
- public CertStatus(byte[] certHash, BigInteger certReqID)
+ public CertStatus(byte[] certHash, BigInteger certReqID)
+ : this(certHash, new DerInteger(certReqID))
+ {
+ }
+
+ public CertStatus(byte[] certHash, DerInteger certReqID)
{
m_certHash = new DerOctetString(certHash);
- m_certReqID = new DerInteger(certReqID);
+ m_certReqID = certReqID;
m_statusInfo = null;
m_hashAlg = null;
}
diff --git a/crypto/src/cmp/CertificateConfirmationContentBuilder.cs b/crypto/src/cmp/CertificateConfirmationContentBuilder.cs
index 32fef908b..b46c1ab0e 100644
--- a/crypto/src/cmp/CertificateConfirmationContentBuilder.cs
+++ b/crypto/src/cmp/CertificateConfirmationContentBuilder.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Operators.Utilities;
using Org.BouncyCastle.Security;
@@ -13,8 +14,9 @@ namespace Org.BouncyCastle.Cmp
public sealed class CertificateConfirmationContentBuilder
{
private readonly IDigestAlgorithmFinder m_digestAlgorithmFinder;
- private readonly List<X509Certificate> m_acceptedCerts = new List<X509Certificate>();
- private readonly List<BigInteger> m_acceptedReqIDs = new List<BigInteger>();
+ private readonly List<CmpCertificate> m_acceptedCerts = new List<CmpCertificate>();
+ private readonly List<AlgorithmIdentifier> m_acceptedSignatureAlgorithms = new List<AlgorithmIdentifier>();
+ private readonly List<DerInteger> m_acceptedReqIDs = new List<DerInteger>();
public CertificateConfirmationContentBuilder()
: this(DefaultDigestAlgorithmFinder.Instance)
@@ -32,11 +34,26 @@ namespace Org.BouncyCastle.Cmp
m_digestAlgorithmFinder = digestAlgorithmFinder;
}
+ // TODO[api] Rename parameters to 'cert', 'certReqID'
public CertificateConfirmationContentBuilder AddAcceptedCertificate(X509Certificate certHolder,
BigInteger certReqId)
{
- m_acceptedCerts.Add(certHolder);
- m_acceptedReqIDs.Add(certReqId);
+ return AddAcceptedCertificate(certHolder, new DerInteger(certReqId));
+ }
+
+ public CertificateConfirmationContentBuilder AddAcceptedCertificate(X509Certificate cert, DerInteger certReqID)
+ {
+ return AddAcceptedCertificate(
+ new CmpCertificate(cert.CertificateStructure), cert.SignatureAlgorithm, certReqID);
+ }
+
+ public CertificateConfirmationContentBuilder AddAcceptedCertificate(CmpCertificate cmpCertificate,
+ AlgorithmIdentifier signatureAlgorithm, DerInteger certReqID)
+ {
+ m_acceptedCerts.Add(cmpCertificate);
+ m_acceptedSignatureAlgorithms.Add(signatureAlgorithm);
+ m_acceptedReqIDs.Add(certReqID);
+
return this;
}
@@ -45,16 +62,15 @@ namespace Org.BouncyCastle.Cmp
Asn1EncodableVector v = new Asn1EncodableVector(m_acceptedCerts.Count);
for (int i = 0; i != m_acceptedCerts.Count; i++)
{
- X509Certificate cert = m_acceptedCerts[i];
- BigInteger reqID = m_acceptedReqIDs[i];
-
- var sigAlgID = DefaultSignatureAlgorithmFinder.Instance.Find(cert.SigAlgName)
- ?? throw new CmpException("cannot find algorithm identifier for signature name");
+ CmpCertificate cmpCertificate = m_acceptedCerts[i];
+ AlgorithmIdentifier signatureAlgorithm = m_acceptedSignatureAlgorithms[i];
+ DerInteger reqID = m_acceptedReqIDs[i];
- var digAlgID = m_digestAlgorithmFinder.Find(sigAlgID)
+ var digestAlgorithm = m_digestAlgorithmFinder.Find(signatureAlgorithm)
?? throw new CmpException("cannot find algorithm for digest from signature");
- byte[] digest = DigestUtilities.CalculateDigest(digAlgID.Algorithm, cert.GetEncoded());
+ byte[] digest = DigestUtilities.CalculateDigest(digestAlgorithm.Algorithm,
+ cmpCertificate.GetEncoded(Asn1Encodable.Der));
v.Add(new CertStatus(digest, reqID));
}
diff --git a/crypto/src/cmp/CertificateStatus.cs b/crypto/src/cmp/CertificateStatus.cs
index 55292329a..4df7e0cf5 100644
--- a/crypto/src/cmp/CertificateStatus.cs
+++ b/crypto/src/cmp/CertificateStatus.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
@@ -32,17 +33,16 @@ namespace Org.BouncyCastle.Cmp
public virtual BigInteger CertRequestID => m_certStatus.CertReqID.Value;
- public virtual bool IsVerified(X509Certificate cert)
- {
- var signatureName = cert.SigAlgName;
-
- var signatureAlgorithm = DefaultSignatureAlgorithmFinder.Instance.Find(signatureName)
- ?? throw new CmpException("cannot find algorithm identifier for signature name");
+ public virtual bool IsVerified(X509Certificate cert) =>
+ IsVerified(new CmpCertificate(cert.CertificateStructure), cert.SignatureAlgorithm);
- var digestAlgorithm = m_digestAlgorithmFinder.Find(signatureAlgorithm)
- ?? throw new CmpException("cannot find algorithm for digest from signature " + signatureName);
+ public virtual bool IsVerified(CmpCertificate cmpCertificate, AlgorithmIdentifier signatureAlgorithm)
+ {
+ AlgorithmIdentifier digestAlgorithm = m_digestAlgorithmFinder.Find(signatureAlgorithm)
+ ?? throw new CmpException("cannot find algorithm for digest from signature");
- byte[] digest = DigestUtilities.CalculateDigest(digestAlgorithm.Algorithm, cert.GetEncoded());
+ byte[] digest = DigestUtilities.CalculateDigest(digestAlgorithm.Algorithm,
+ cmpCertificate.GetEncoded(Asn1Encodable.Der));
return Arrays.FixedTimeEquals(m_certStatus.CertHash.GetOctets(), digest);
}
diff --git a/crypto/src/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs
index 79394094d..03dd2327e 100644
--- a/crypto/src/cmp/ProtectedPkiMessage.cs
+++ b/crypto/src/cmp/ProtectedPkiMessage.cs
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Cmp
if (!pkiMessage.HasProtection)
throw new ArgumentException("GeneralPkiMessage not protected");
- this.m_pkiMessage = pkiMessage.ToAsn1Structure();
+ m_pkiMessage = pkiMessage.ToAsn1Structure();
}
// TODO[cmp] Make internal? (Has test that uses it)
@@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Cmp
if (null == pkiMessage.Header.ProtectionAlg)
throw new ArgumentException("PkiMessage not protected");
- this.m_pkiMessage = pkiMessage;
+ m_pkiMessage = pkiMessage;
}
/// <summary>Message header</summary>
@@ -66,6 +66,13 @@ namespace Org.BouncyCastle.Cmp
get { return CmpObjectIdentifiers.passwordBasedMac.Equals(Header.ProtectionAlg.Algorithm); }
}
+ /**
+ * Return the message's protection algorithm.
+ *
+ * @return the algorithm ID for the message's protection algorithm.
+ */
+ public virtual AlgorithmIdentifier ProtectionAlgorithm => m_pkiMessage.Header.ProtectionAlg;
+
/// <summary>
/// Return the extra certificates associated with this message.
/// </summary>
@@ -76,12 +83,8 @@ namespace Org.BouncyCastle.Cmp
if (null == certs)
return new X509Certificate[0];
- X509Certificate[] result = new X509Certificate[certs.Length];
- for (int t = 0; t < certs.Length; t++)
- {
- result[t] = new X509Certificate(certs[t].X509v3PKCert);
- }
- return result;
+ return Array.ConvertAll<CmpCertificate, X509Certificate>(certs,
+ cmpCertificate => new X509Certificate(cmpCertificate.X509v3PKCert));
}
/// <summary>
@@ -107,10 +110,12 @@ namespace Org.BouncyCastle.Cmp
/// <exception cref="InvalidOperationException">if algorithm not MAC based, or an exception is thrown verifying the MAC.</exception>
public virtual bool Verify(PKMacBuilder pkMacBuilder, char[] password)
{
- if (!CmpObjectIdentifiers.passwordBasedMac.Equals(m_pkiMessage.Header.ProtectionAlg.Algorithm))
+ var protectionAlgorithm = m_pkiMessage.Header.ProtectionAlg;
+
+ if (!CmpObjectIdentifiers.passwordBasedMac.Equals(protectionAlgorithm.Algorithm))
throw new InvalidOperationException("protection algorithm is not mac based");
- PbmParameter parameter = PbmParameter.GetInstance(m_pkiMessage.Header.ProtectionAlg.Parameters);
+ PbmParameter parameter = PbmParameter.GetInstance(protectionAlgorithm.Parameters);
pkMacBuilder.SetParameters(parameter);
var macFactory = pkMacBuilder.Build(password);
diff --git a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
index a3070ee56..ff4af5573 100644
--- a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
+++ b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
@@ -12,9 +12,9 @@ namespace Org.BouncyCastle.Cmp
public sealed class ProtectedPkiMessageBuilder
{
private readonly PkiHeaderBuilder m_hdrBuilder;
- private PkiBody body;
- private readonly List<InfoTypeAndValue> generalInfos = new List<InfoTypeAndValue>();
- private readonly List<X509Certificate> extraCerts = new List<X509Certificate>();
+ private readonly List<InfoTypeAndValue> m_generalInfos = new List<InfoTypeAndValue>();
+ private readonly List<X509Certificate> m_extraCerts = new List<X509Certificate>();
+ private PkiBody m_body;
public ProtectedPkiMessageBuilder(GeneralName sender, GeneralName recipient)
: this(PkiHeader.CMP_2000, sender, recipient)
@@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Cmp
public ProtectedPkiMessageBuilder AddGeneralInfo(InfoTypeAndValue genInfo)
{
- generalInfos.Add(genInfo);
+ m_generalInfos.Add(genInfo);
return this;
}
@@ -82,19 +82,49 @@ namespace Org.BouncyCastle.Cmp
public ProtectedPkiMessageBuilder SetBody(PkiBody body)
{
- this.body = body;
+ m_body = body;
+ return this;
+ }
+
+ // TODO[crmf] Add CertificateReqMessages
+ //public ProtectedPkiMessageBuilder SetBody(int bodyType, CertificateReqMessages certificateReqMessages)
+ //{
+ // if (!CertificateReqMessages.IsCertificateRequestMessages(bodyType))
+ // throw new ArgumentException("body type " + bodyType + " does not match CMP type CertReqMessages");
+
+ // m_body = new PkiBody(bodyType, certificateReqMessages.ToAsn1Structure());
+ // return this;
+ //}
+
+ // TODO[crmf] Add CertificateRepMessage
+ //public ProtectedPkiMessageBuilder SetBody(int bodyType, CertificateRepMessage certificateRepMessage)
+ //{
+ // if (!CertificateRepMessage.IsCertificateRepMessage(bodyType))
+ // throw new ArgumentException("body type " + bodyType + " does not match CMP type CertRepMessage");
+
+ // m_body = new PkiBody(bodyType, certificateRepMessage.ToAsn1Structure());
+ // return this;
+ //}
+
+ public ProtectedPkiMessageBuilder SetBody(int bodyType,
+ CertificateConfirmationContent certificateConfirmationContent)
+ {
+ if (!CertificateConfirmationContent.IsCertificateConfirmationContent(bodyType))
+ throw new ArgumentException("body type " + bodyType + " does not match CMP type CertConfirmContent");
+
+ m_body = new PkiBody(bodyType, certificateConfirmationContent.ToAsn1Structure());
return this;
}
public ProtectedPkiMessageBuilder AddCmpCertificate(X509Certificate certificate)
{
- extraCerts.Add(certificate);
+ m_extraCerts.Add(certificate);
return this;
}
public ProtectedPkiMessage Build(ISignatureFactory signatureFactory)
{
- if (null == body)
+ if (null == m_body)
throw new InvalidOperationException("body must be set before building");
if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails))
@@ -102,13 +132,14 @@ namespace Org.BouncyCastle.Cmp
FinalizeHeader(algorithmDetails);
PkiHeader header = m_hdrBuilder.Build();
- DerBitString protection = X509Utilities.GenerateSignature(signatureFactory, new DerSequence(header, body));
+ DerBitString protection = X509Utilities.GenerateSignature(signatureFactory,
+ new DerSequence(header, m_body));
return FinalizeMessage(header, protection);
}
public ProtectedPkiMessage Build(IMacFactory macFactory)
{
- if (null == body)
+ if (null == m_body)
throw new InvalidOperationException("body must be set before building");
if (!(macFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails))
@@ -116,31 +147,31 @@ namespace Org.BouncyCastle.Cmp
FinalizeHeader(algorithmDetails);
PkiHeader header = m_hdrBuilder.Build();
- DerBitString protection = X509Utilities.GenerateMac(macFactory, new DerSequence(header, body));
+ DerBitString protection = X509Utilities.GenerateMac(macFactory, new DerSequence(header, m_body));
return FinalizeMessage(header, protection);
}
private void FinalizeHeader(AlgorithmIdentifier algorithmIdentifier)
{
m_hdrBuilder.SetProtectionAlg(algorithmIdentifier);
- if (generalInfos.Count > 0)
+ if (m_generalInfos.Count > 0)
{
- m_hdrBuilder.SetGeneralInfo(generalInfos.ToArray());
+ m_hdrBuilder.SetGeneralInfo(m_generalInfos.ToArray());
}
}
private ProtectedPkiMessage FinalizeMessage(PkiHeader header, DerBitString protection)
{
- if (extraCerts.Count < 1)
- return new ProtectedPkiMessage(new PkiMessage(header, body, protection));
+ if (m_extraCerts.Count < 1)
+ return new ProtectedPkiMessage(new PkiMessage(header, m_body, protection));
- CmpCertificate[] cmpCertificates = new CmpCertificate[extraCerts.Count];
+ CmpCertificate[] cmpCertificates = new CmpCertificate[m_extraCerts.Count];
for (int i = 0; i < cmpCertificates.Length; i++)
{
- cmpCertificates[i] = new CmpCertificate(extraCerts[i].CertificateStructure);
+ cmpCertificates[i] = new CmpCertificate(m_extraCerts[i].CertificateStructure);
}
- return new ProtectedPkiMessage(new PkiMessage(header, body, protection, cmpCertificates));
+ return new ProtectedPkiMessage(new PkiMessage(header, m_body, protection, cmpCertificates));
}
}
}
diff --git a/crypto/src/cmp/RevocationDetails.cs b/crypto/src/cmp/RevocationDetails.cs
index 6060c6575..e3ad73f28 100644
--- a/crypto/src/cmp/RevocationDetails.cs
+++ b/crypto/src/cmp/RevocationDetails.cs
@@ -19,6 +19,7 @@ namespace Org.BouncyCastle.Cmp
public BigInteger SerialNumber => m_revDetails.CertDetails.SerialNumber.Value;
+ // TODO[api] Rename to 'ToAsn1Structure'
public RevDetails ToASN1Structure() => m_revDetails;
}
}
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs
index b1307d90e..944b627b0 100644
--- a/crypto/src/x509/X509Certificate.cs
+++ b/crypto/src/x509/X509Certificate.cs
@@ -312,6 +312,9 @@ namespace Org.BouncyCastle.X509
return Arrays.Clone(sigAlgParams);
}
+ /// <summary>The signature algorithm.</summary>
+ public virtual AlgorithmIdentifier SignatureAlgorithm => c.SignatureAlgorithm;
+
/// <summary>
/// Get the issuers UID.
/// </summary>
@@ -629,6 +632,7 @@ namespace Org.BouncyCastle.X509
return buf.ToString();
}
+ // TODO[api] Rename 'key' to 'publicKey'
public virtual bool IsSignatureValid(AsymmetricKeyParameter key)
{
return CheckSignatureValid(new Asn1VerifierFactory(c.SignatureAlgorithm, key));
diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs
index 1dd1776be..2df8d5409 100644
--- a/crypto/src/x509/X509V3CertificateGenerator.cs
+++ b/crypto/src/x509/X509V3CertificateGenerator.cs
@@ -156,13 +156,22 @@ namespace Org.BouncyCastle.X509
tbsGen.SetIssuerUniqueID(BooleanToBitString(uniqueID));
}
- /// <summary>
- /// Add a given extension field for the standard extensions tag (tag 3).
- /// </summary>
- /// <param name="oid">string containing a dotted decimal Object Identifier.</param>
- /// <param name="critical">Is it critical.</param>
- /// <param name="extensionValue">The value.</param>
- public void AddExtension(
+ /// <summary>
+ /// Set the SubjectPublicKeyInfo for the public key that this certificate identifies.
+ /// </summary>
+ /// <param name="subjectPublicKeyInfo"/>
+ public void SetSubjectPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
+ {
+ tbsGen.SetSubjectPublicKeyInfo(subjectPublicKeyInfo);
+ }
+
+ /// <summary>
+ /// Add a given extension field for the standard extensions tag (tag 3).
+ /// </summary>
+ /// <param name="oid">string containing a dotted decimal Object Identifier.</param>
+ /// <param name="critical">Is it critical.</param>
+ /// <param name="extensionValue">The value.</param>
+ public void AddExtension(
string oid,
bool critical,
Asn1Encodable extensionValue)
|