init commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Cms;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class CertificateConfirmationContent
|
||||
{
|
||||
private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder;
|
||||
|
||||
private readonly CertConfirmContent content;
|
||||
|
||||
public CertificateConfirmationContent(CertConfirmContent content)
|
||||
{
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public CertificateConfirmationContent(CertConfirmContent content, DefaultDigestAlgorithmIdentifierFinder digestAlgFinder)
|
||||
{
|
||||
this.content = content;
|
||||
this.digestAlgFinder = digestAlgFinder;
|
||||
}
|
||||
|
||||
public CertConfirmContent ToAsn1Structure()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
public CertificateStatus[] GetStatusMessages()
|
||||
{
|
||||
CertStatus[] array = content.ToCertStatusArray();
|
||||
CertificateStatus[] array2 = new CertificateStatus[array.Length];
|
||||
for (int i = 0; i != array2.Length; i++)
|
||||
{
|
||||
array2[i] = new CertificateStatus(digestAlgFinder, array[i]);
|
||||
}
|
||||
return array2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Cms;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class CertificateConfirmationContentBuilder
|
||||
{
|
||||
private static readonly DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
|
||||
|
||||
private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder;
|
||||
|
||||
private readonly IList acceptedCerts = Platform.CreateArrayList();
|
||||
|
||||
private readonly IList acceptedReqIds = Platform.CreateArrayList();
|
||||
|
||||
public CertificateConfirmationContentBuilder()
|
||||
: this(new DefaultDigestAlgorithmIdentifierFinder())
|
||||
{
|
||||
}
|
||||
|
||||
public CertificateConfirmationContentBuilder(DefaultDigestAlgorithmIdentifierFinder digestAlgFinder)
|
||||
{
|
||||
this.digestAlgFinder = digestAlgFinder;
|
||||
}
|
||||
|
||||
public CertificateConfirmationContentBuilder AddAcceptedCertificate(X509Certificate certHolder, BigInteger certReqId)
|
||||
{
|
||||
acceptedCerts.Add(certHolder);
|
||||
acceptedReqIds.Add(certReqId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CertificateConfirmationContent Build()
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
for (int i = 0; i != acceptedCerts.Count; i++)
|
||||
{
|
||||
X509Certificate x509Certificate = (X509Certificate)acceptedCerts[i];
|
||||
BigInteger certReqId = (BigInteger)acceptedReqIds[i];
|
||||
AlgorithmIdentifier sigAlgId = sigAlgFinder.Find(x509Certificate.SigAlgName);
|
||||
AlgorithmIdentifier algorithmIdentifier = digestAlgFinder.find(sigAlgId);
|
||||
if (algorithmIdentifier == null)
|
||||
{
|
||||
throw new CmpException("cannot find algorithm for digest from signature");
|
||||
}
|
||||
byte[] certHash = DigestUtilities.CalculateDigest(algorithmIdentifier.Algorithm, x509Certificate.GetEncoded());
|
||||
asn1EncodableVector.Add(new CertStatus(certHash, certReqId));
|
||||
}
|
||||
return new CertificateConfirmationContent(CertConfirmContent.GetInstance(new DerSequence(asn1EncodableVector)), digestAlgFinder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Cms;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class CertificateStatus
|
||||
{
|
||||
private static readonly DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
|
||||
|
||||
private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder;
|
||||
|
||||
private readonly CertStatus certStatus;
|
||||
|
||||
public PkiStatusInfo PkiStatusInfo => certStatus.StatusInfo;
|
||||
|
||||
public BigInteger CertRequestId => certStatus.CertReqID.Value;
|
||||
|
||||
public CertificateStatus(DefaultDigestAlgorithmIdentifierFinder digestAlgFinder, CertStatus certStatus)
|
||||
{
|
||||
this.digestAlgFinder = digestAlgFinder;
|
||||
this.certStatus = certStatus;
|
||||
}
|
||||
|
||||
public bool IsVerified(X509Certificate cert)
|
||||
{
|
||||
AlgorithmIdentifier algorithmIdentifier = digestAlgFinder.find(sigAlgFinder.Find(cert.SigAlgName));
|
||||
if (algorithmIdentifier == null)
|
||||
{
|
||||
throw new CmpException("cannot find algorithm for digest from signature " + cert.SigAlgName);
|
||||
}
|
||||
byte[] b = DigestUtilities.CalculateDigest(algorithmIdentifier.Algorithm, cert.GetEncoded());
|
||||
return Arrays.ConstantTimeAreEqual(certStatus.CertHash.GetOctets(), b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class CmpException : Exception
|
||||
{
|
||||
public CmpException()
|
||||
{
|
||||
}
|
||||
|
||||
public CmpException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public CmpException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class GeneralPkiMessage
|
||||
{
|
||||
private readonly PkiMessage pkiMessage;
|
||||
|
||||
public PkiHeader Header => pkiMessage.Header;
|
||||
|
||||
public PkiBody Body => pkiMessage.Body;
|
||||
|
||||
public bool HasProtection => pkiMessage.Protection != null;
|
||||
|
||||
private static PkiMessage ParseBytes(byte[] encoding)
|
||||
{
|
||||
return PkiMessage.GetInstance(Asn1Object.FromByteArray(encoding));
|
||||
}
|
||||
|
||||
public GeneralPkiMessage(PkiMessage pkiMessage)
|
||||
{
|
||||
this.pkiMessage = pkiMessage;
|
||||
}
|
||||
|
||||
public GeneralPkiMessage(byte[] encoding)
|
||||
: this(ParseBytes(encoding))
|
||||
{
|
||||
}
|
||||
|
||||
public PkiMessage ToAsn1Structure()
|
||||
{
|
||||
return pkiMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crmf;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class ProtectedPkiMessage
|
||||
{
|
||||
private readonly PkiMessage pkiMessage;
|
||||
|
||||
public PkiHeader Header => pkiMessage.Header;
|
||||
|
||||
public PkiBody Body => pkiMessage.Body;
|
||||
|
||||
public bool HasPasswordBasedMacProtected => Header.ProtectionAlg.Algorithm.Equals(CmpObjectIdentifiers.passwordBasedMac);
|
||||
|
||||
public ProtectedPkiMessage(GeneralPkiMessage pkiMessage)
|
||||
{
|
||||
if (!pkiMessage.HasProtection)
|
||||
{
|
||||
throw new ArgumentException("pki message not protected");
|
||||
}
|
||||
this.pkiMessage = pkiMessage.ToAsn1Structure();
|
||||
}
|
||||
|
||||
public ProtectedPkiMessage(PkiMessage pkiMessage)
|
||||
{
|
||||
if (pkiMessage.Header.ProtectionAlg == null)
|
||||
{
|
||||
throw new ArgumentException("pki message not protected");
|
||||
}
|
||||
this.pkiMessage = pkiMessage;
|
||||
}
|
||||
|
||||
public PkiMessage ToAsn1Message()
|
||||
{
|
||||
return pkiMessage;
|
||||
}
|
||||
|
||||
public X509Certificate[] GetCertificates()
|
||||
{
|
||||
CmpCertificate[] extraCerts = pkiMessage.GetExtraCerts();
|
||||
if (extraCerts == null)
|
||||
{
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
X509Certificate[] array = new X509Certificate[extraCerts.Length];
|
||||
for (int i = 0; i < extraCerts.Length; i++)
|
||||
{
|
||||
array[i] = new X509Certificate(X509CertificateStructure.GetInstance(extraCerts[i].GetEncoded()));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public bool Verify(IVerifierFactory verifierFactory)
|
||||
{
|
||||
IStreamCalculator streamCalculator = verifierFactory.CreateCalculator();
|
||||
IVerifier verifier = (IVerifier)Process(streamCalculator);
|
||||
return verifier.IsVerified(pkiMessage.Protection.GetBytes());
|
||||
}
|
||||
|
||||
private object Process(IStreamCalculator streamCalculator)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
asn1EncodableVector.Add(pkiMessage.Header);
|
||||
asn1EncodableVector.Add(pkiMessage.Body);
|
||||
byte[] derEncoded = new DerSequence(asn1EncodableVector).GetDerEncoded();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
streamCalculator.Stream.Flush();
|
||||
streamCalculator.Stream.Close();
|
||||
return streamCalculator.GetResult();
|
||||
}
|
||||
|
||||
public bool Verify(PKMacBuilder pkMacBuilder, char[] password)
|
||||
{
|
||||
if (!CmpObjectIdentifiers.passwordBasedMac.Equals(pkiMessage.Header.ProtectionAlg.Algorithm))
|
||||
{
|
||||
throw new InvalidOperationException("protection algorithm is not mac based");
|
||||
}
|
||||
PbmParameter instance = PbmParameter.GetInstance(pkiMessage.Header.ProtectionAlg.Parameters);
|
||||
pkMacBuilder.SetParameters(instance);
|
||||
IBlockResult blockResult = (IBlockResult)Process(pkMacBuilder.Build(password).CreateCalculator());
|
||||
return Arrays.ConstantTimeAreEqual(blockResult.Collect(), pkiMessage.Protection.GetBytes());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Operators;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class ProtectedPkiMessageBuilder
|
||||
{
|
||||
private PkiHeaderBuilder hdrBuilBuilder;
|
||||
|
||||
private PkiBody body;
|
||||
|
||||
private IList generalInfos = Platform.CreateArrayList();
|
||||
|
||||
private IList extraCerts = Platform.CreateArrayList();
|
||||
|
||||
public ProtectedPkiMessageBuilder(GeneralName sender, GeneralName recipient)
|
||||
: this(PkiHeader.CMP_2000, sender, recipient)
|
||||
{
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder(int pvno, GeneralName sender, GeneralName recipient)
|
||||
{
|
||||
hdrBuilBuilder = new PkiHeaderBuilder(pvno, sender, recipient);
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetTransactionId(byte[] tid)
|
||||
{
|
||||
hdrBuilBuilder.SetTransactionID(tid);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetFreeText(PkiFreeText freeText)
|
||||
{
|
||||
hdrBuilBuilder.SetFreeText(freeText);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder AddGeneralInfo(InfoTypeAndValue genInfo)
|
||||
{
|
||||
generalInfos.Add(genInfo);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetMessageTime(DerGeneralizedTime generalizedTime)
|
||||
{
|
||||
hdrBuilBuilder.SetMessageTime(generalizedTime);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetRecipKID(byte[] id)
|
||||
{
|
||||
hdrBuilBuilder.SetRecipKID(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetRecipNonce(byte[] nonce)
|
||||
{
|
||||
hdrBuilBuilder.SetRecipNonce(nonce);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetSenderKID(byte[] id)
|
||||
{
|
||||
hdrBuilBuilder.SetSenderKID(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetSenderNonce(byte[] nonce)
|
||||
{
|
||||
hdrBuilBuilder.SetSenderNonce(nonce);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder SetBody(PkiBody body)
|
||||
{
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessageBuilder AddCmpCertificate(X509Certificate certificate)
|
||||
{
|
||||
extraCerts.Add(certificate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProtectedPkiMessage Build(ISignatureFactory signatureFactory)
|
||||
{
|
||||
IStreamCalculator signer = signatureFactory.CreateCalculator();
|
||||
if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier))
|
||||
{
|
||||
throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier");
|
||||
}
|
||||
FinalizeHeader((AlgorithmIdentifier)signatureFactory.AlgorithmDetails);
|
||||
PkiHeader header = hdrBuilBuilder.Build();
|
||||
DerBitString protection = new DerBitString(CalculateSignature(signer, header, body));
|
||||
return FinalizeMessage(header, protection);
|
||||
}
|
||||
|
||||
public ProtectedPkiMessage Build(IMacFactory factory)
|
||||
{
|
||||
IStreamCalculator signer = factory.CreateCalculator();
|
||||
FinalizeHeader((AlgorithmIdentifier)factory.AlgorithmDetails);
|
||||
PkiHeader header = hdrBuilBuilder.Build();
|
||||
DerBitString protection = new DerBitString(CalculateSignature(signer, header, body));
|
||||
return FinalizeMessage(header, protection);
|
||||
}
|
||||
|
||||
private void FinalizeHeader(AlgorithmIdentifier algorithmIdentifier)
|
||||
{
|
||||
hdrBuilBuilder.SetProtectionAlg(algorithmIdentifier);
|
||||
if (generalInfos.Count > 0)
|
||||
{
|
||||
InfoTypeAndValue[] array = new InfoTypeAndValue[generalInfos.Count];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = (InfoTypeAndValue)generalInfos[i];
|
||||
}
|
||||
hdrBuilBuilder.SetGeneralInfo(array);
|
||||
}
|
||||
}
|
||||
|
||||
private ProtectedPkiMessage FinalizeMessage(PkiHeader header, DerBitString protection)
|
||||
{
|
||||
if (extraCerts.Count > 0)
|
||||
{
|
||||
CmpCertificate[] array = new CmpCertificate[extraCerts.Count];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
byte[] encoded = ((X509Certificate)extraCerts[i]).GetEncoded();
|
||||
array[i] = CmpCertificate.GetInstance(Asn1Object.FromByteArray(encoded));
|
||||
}
|
||||
return new ProtectedPkiMessage(new PkiMessage(header, body, protection, array));
|
||||
}
|
||||
return new ProtectedPkiMessage(new PkiMessage(header, body, protection));
|
||||
}
|
||||
|
||||
private byte[] CalculateSignature(IStreamCalculator signer, PkiHeader header, PkiBody body)
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
asn1EncodableVector.Add(header);
|
||||
asn1EncodableVector.Add(body);
|
||||
byte[] encoded = new DerSequence(asn1EncodableVector).GetEncoded();
|
||||
signer.Stream.Write(encoded, 0, encoded.Length);
|
||||
object result = signer.GetResult();
|
||||
if (result is DefaultSignatureResult)
|
||||
{
|
||||
return ((DefaultSignatureResult)result).Collect();
|
||||
}
|
||||
if (result is IBlockResult)
|
||||
{
|
||||
return ((IBlockResult)result).Collect();
|
||||
}
|
||||
if (result is byte[])
|
||||
{
|
||||
return (byte[])result;
|
||||
}
|
||||
throw new InvalidOperationException("result is not byte[] or DefaultSignatureResult");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class RevocationDetails
|
||||
{
|
||||
private readonly RevDetails revDetails;
|
||||
|
||||
public X509Name Subject => revDetails.CertDetails.Subject;
|
||||
|
||||
public X509Name Issuer => revDetails.CertDetails.Issuer;
|
||||
|
||||
public BigInteger SerialNumber => revDetails.CertDetails.SerialNumber.Value;
|
||||
|
||||
public RevocationDetails(RevDetails revDetails)
|
||||
{
|
||||
this.revDetails = revDetails;
|
||||
}
|
||||
|
||||
public RevDetails ToASN1Structure()
|
||||
{
|
||||
return revDetails;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cmp;
|
||||
using Org.BouncyCastle.Asn1.Crmf;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Cmp;
|
||||
|
||||
public class RevocationDetailsBuilder
|
||||
{
|
||||
private readonly CertTemplateBuilder _templateBuilder = new CertTemplateBuilder();
|
||||
|
||||
public RevocationDetailsBuilder SetPublicKey(SubjectPublicKeyInfo publicKey)
|
||||
{
|
||||
if (publicKey != null)
|
||||
{
|
||||
_templateBuilder.SetPublicKey(publicKey);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RevocationDetailsBuilder SetIssuer(X509Name issuer)
|
||||
{
|
||||
if (issuer != null)
|
||||
{
|
||||
_templateBuilder.SetIssuer(issuer);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RevocationDetailsBuilder SetSerialNumber(BigInteger serialNumber)
|
||||
{
|
||||
if (serialNumber != null)
|
||||
{
|
||||
_templateBuilder.SetSerialNumber(new DerInteger(serialNumber));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RevocationDetailsBuilder SetSubject(X509Name subject)
|
||||
{
|
||||
if (subject != null)
|
||||
{
|
||||
_templateBuilder.SetSubject(subject);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RevocationDetails Build()
|
||||
{
|
||||
return new RevocationDetails(new RevDetails(_templateBuilder.Build()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user