diff --git a/crypto/src/asn1/cmp/CertificateConfirmationContent.cs b/crypto/src/asn1/cmp/CertificateConfirmationContent.cs
new file mode 100644
index 000000000..9f2f3e038
--- /dev/null
+++ b/crypto/src/asn1/cmp/CertificateConfirmationContent.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Cms;
+
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class CertificateConfirmationContent
+ {
+ private DefaultDigestAlgorithmIdentifierFinder digestAlgFinder;
+ private 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[] statusArray = content.ToCertStatusArray();
+ CertificateStatus[] ret = new CertificateStatus[statusArray.Length];
+ for (int i = 0; i != ret.Length; i++)
+ {
+ ret[i] = new CertificateStatus(digestAlgFinder, statusArray[i]);
+ }
+
+ return ret;
+ }
+ }
+}
diff --git a/crypto/src/asn1/cmp/CertificateConfirmationContentBuilder.cs b/crypto/src/asn1/cmp/CertificateConfirmationContentBuilder.cs
new file mode 100644
index 000000000..b8c306f81
--- /dev/null
+++ b/crypto/src/asn1/cmp/CertificateConfirmationContentBuilder.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class CertificateConfirmationContentBuilder
+ {
+ DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ private DefaultDigestAlgorithmIdentifierFinder digestAlgFinder;
+ private ArrayList acceptedCerts = new ArrayList();
+ private ArrayList acceptedReqIds = new ArrayList();
+
+ 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 v = new Asn1EncodableVector();
+ for (int i = 0; i != acceptedCerts.Count; i++)
+ {
+ X509Certificate cert = (X509Certificate) acceptedCerts[i];
+ BigInteger reqId = (BigInteger) acceptedReqIds[i];
+
+
+
+ AlgorithmIdentifier algorithmIdentifier = sigAlgFinder.Find(cert.SigAlgName);
+
+ AlgorithmIdentifier digAlg = digestAlgFinder.find(algorithmIdentifier);
+ if (digAlg == null)
+ {
+ throw new CmpException("cannot find algorithm for digest from signature");
+ }
+
+ DigestSink sink = new DigestSink(DigestUtilities.GetDigest(digAlg.Algorithm));
+
+ sink.Write(cert.GetEncoded());
+
+ byte[] dig = new byte[sink.Digest.GetDigestSize()];
+ sink.Digest.DoFinal(dig, 0);
+
+ v.Add(new CertStatus(dig,reqId));
+ }
+
+ return new CertificateConfirmationContent(CertConfirmContent.GetInstance(new DerSequence(v)),
+ digestAlgFinder);
+ }
+ }
+}
diff --git a/crypto/src/asn1/cmp/CertificateStatus.cs b/crypto/src/asn1/cmp/CertificateStatus.cs
new file mode 100644
index 000000000..d16c8e006
--- /dev/null
+++ b/crypto/src/asn1/cmp/CertificateStatus.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class CertificateStatus
+ {
+ private DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
+ private DefaultDigestAlgorithmIdentifierFinder digestAlgFinder;
+ private CertStatus certStatus;
+
+ public CertificateStatus(DefaultDigestAlgorithmIdentifierFinder digestAlgFinder, CertStatus certStatus)
+ {
+ this.digestAlgFinder = digestAlgFinder;
+ this.certStatus = certStatus;
+ }
+
+ public PkiStatusInfo PkiStatusInfo
+ {
+ get { return certStatus.StatusInfo; }
+ }
+
+ public BigInteger CertRequestId
+ {
+ get { return certStatus.CertReqID.Value; }
+ }
+
+ public bool IsVerified(X509Certificate cert)
+ {
+
+ AlgorithmIdentifier digAlg = digestAlgFinder.find( sigAlgFinder.Find(cert.SigAlgName));
+ if (digAlg == null)
+ {
+ throw new CmpException("cannot find algorithm for digest from signature "+cert.SigAlgName);
+ }
+
+ DigestSink digestSink = new DigestSink(DigestUtilities.GetDigest(digAlg.Algorithm));
+
+ digestSink.Write(cert.GetEncoded());
+
+ byte[] digest = new byte[digestSink.Digest.GetDigestSize()];
+ digestSink.Digest.DoFinal(digest, 0);
+ return Arrays.ConstantTimeAreEqual(certStatus.CertHash.GetOctets(), digest);
+ }
+ }
+}
diff --git a/crypto/src/asn1/cmp/CmpException.cs b/crypto/src/asn1/cmp/CmpException.cs
new file mode 100644
index 000000000..0500b7d3e
--- /dev/null
+++ b/crypto/src/asn1/cmp/CmpException.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class CmpException : Exception
+ {
+ public CmpException()
+ {
+ }
+
+ public CmpException(string message) : base(message)
+ {
+ }
+
+ public CmpException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ protected CmpException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
diff --git a/crypto/src/asn1/cmp/GeneralPKIMessage.cs b/crypto/src/asn1/cmp/GeneralPKIMessage.cs
new file mode 100644
index 000000000..d91b8ef7e
--- /dev/null
+++ b/crypto/src/asn1/cmp/GeneralPKIMessage.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class GeneralPKIMessage
+ {
+ private readonly PkiMessage pkiMessage;
+
+ 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 PkiHeader Header {
+ get {
+ return pkiMessage.Header;
+ }
+ }
+
+ public PkiBody Body
+ {
+ get
+ {
+ return pkiMessage.Body;
+ }
+ }
+
+ public bool HasProtection
+ {
+ get { return pkiMessage.Protection != null; }
+ }
+
+ public PkiMessage ToAsn1Structure()
+ {
+ return pkiMessage;
+ }
+ }
+}
diff --git a/crypto/src/asn1/cmp/ProtectedPkiMessage.cs b/crypto/src/asn1/cmp/ProtectedPkiMessage.cs
new file mode 100644
index 000000000..c39f06ad0
--- /dev/null
+++ b/crypto/src/asn1/cmp/ProtectedPkiMessage.cs
@@ -0,0 +1,107 @@
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.X509;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.Crmf;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Crypto.Paddings;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+
+ public class ProtectedPkiMessage
+ {
+ private PkiMessage pkiMessage;
+
+
+ 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 PkiHeader Header { get { return pkiMessage.Header; } }
+ public PkiBody Body { get { return pkiMessage.Body; } }
+
+ public PkiMessage ToAsn1Message() { return pkiMessage; }
+
+ public bool HasPasswordBasedMacProtected { get { return Header.ProtectionAlg.Algorithm.Equals(CmpObjectIdentifiers.passwordBasedMac); } }
+
+ public X509Certificate[] GetCertificates()
+ {
+ CmpCertificate[] certs = pkiMessage.GetExtraCerts();
+
+ if (certs == null)
+ {
+ return new X509Certificate[0];
+ }
+
+ X509Certificate[] res = new X509Certificate[certs.Length];
+ for (int t=0; t<certs.Length;t++)
+ {
+ res[t] = new X509Certificate(X509CertificateStructure.GetInstance(certs[t].GetEncoded()));
+ }
+
+ return res;
+ }
+
+
+
+
+ public bool Verify(IVerifierFactory verifier)
+ {
+ Asn1EncodableVector avec = new Asn1EncodableVector();
+ avec.Add(pkiMessage.Header);
+ avec.Add(pkiMessage.Body);
+ byte[] enc = new DerSequence(avec).GetDerEncoded();
+
+ IStreamCalculator streamCalculator = verifier.CreateCalculator();
+
+ streamCalculator.Stream.Write(enc,0,enc.Length);
+ streamCalculator.Stream.Flush();
+ streamCalculator.Stream.Close();
+
+ IVerifier result = (IVerifier) streamCalculator.GetResult();
+ return result.IsVerified(pkiMessage.Protection.GetBytes());
+ }
+
+
+ public bool Verify(Asn1MacFactoryProvider asn1Factory, byte[] password)
+ {
+ if (!CmpObjectIdentifiers.passwordBasedMac.Equals(pkiMessage.Header.ProtectionAlg.Algorithm))
+ {
+ throw new InvalidOperationException("protection algorithm is not mac based");
+ }
+
+ PbmParameter parameter = PbmParameter.GetInstance(pkiMessage.Header.ProtectionAlg.Parameters);
+
+ PkMacFactory macFactory = (PkMacFactory)asn1Factory.CreateMacFactory(parameter);
+
+ macFactory.Password = password;
+ MacVerifierFactory macVerifierFactory = new MacVerifierFactory(macFactory);
+
+ return Verify(macVerifierFactory);
+ }
+
+ }
+}
diff --git a/crypto/src/asn1/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/asn1/cmp/ProtectedPkiMessageBuilder.cs
new file mode 100644
index 000000000..a6a98d753
--- /dev/null
+++ b/crypto/src/asn1/cmp/ProtectedPkiMessageBuilder.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Crypto.Paddings;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+ public class ProtectedPkiMessageBuilder
+ {
+ private PkiHeaderBuilder hdrBuilBuilder;
+ private PkiBody body;
+ private ArrayList generalInfos = new ArrayList();
+ private ArrayList extraCerts = new ArrayList();
+
+ 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 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 calculator = 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(calculator, header, body));
+ return FinalizeMessage(header, protection);
+ }
+
+ public ProtectedPkiMessage Build(IMacFactory factory)
+ {
+ IStreamCalculator calculator = factory.CreateCalculator();
+ FinalizeHeader((AlgorithmIdentifier)factory.AlgorithmDetails);
+ PkiHeader header = hdrBuilBuilder.Build();
+ DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
+ return FinalizeMessage(header, protection);
+ }
+
+
+ private void FinalizeHeader(AlgorithmIdentifier algorithmIdentifier)
+ {
+ hdrBuilBuilder.SetProtectionAlg(algorithmIdentifier);
+ if (generalInfos.Count > 0)
+ {
+ InfoTypeAndValue[] genInfos = new InfoTypeAndValue[generalInfos.Count];
+ for (int t = 0; t < genInfos.Length; t++)
+ {
+ genInfos[t] = (InfoTypeAndValue) generalInfos[t];
+ }
+
+ hdrBuilBuilder.SetGeneralInfo(genInfos);
+ }
+ }
+
+ private ProtectedPkiMessage FinalizeMessage(PkiHeader header, DerBitString protection)
+ {
+ if (extraCerts.Count > 0)
+ {
+ CmpCertificate[] cmpCertificates = new CmpCertificate[extraCerts.Count];
+ for (int i = 0; i < cmpCertificates.Length; i++)
+ {
+ byte[] cert = ((X509Certificate) extraCerts[i]).GetEncoded();
+ cmpCertificates[i] = CmpCertificate.GetInstance((Asn1Sequence.FromByteArray(cert)));
+ }
+
+ return new ProtectedPkiMessage(new PkiMessage(header, body, protection, cmpCertificates));
+ }
+
+ return new ProtectedPkiMessage(new PkiMessage(header, body, protection));
+ }
+
+ private byte[] CalculateSignature(IStreamCalculator signer, PkiHeader header, PkiBody body)
+ {
+ Asn1EncodableVector avec = new Asn1EncodableVector();
+ avec.Add(header);
+ avec.Add(body);
+ byte[] encoded = new DerSequence(avec).GetEncoded();
+ signer.Stream.Write(encoded, 0, encoded.Length);
+ Object result = signer.GetResult();
+
+
+ if (result is DefaultSignatureResult)
+ {
+ return ((DefaultSignatureResult) result).Collect();
+ }
+ else if (result is DefaultMacAndDigestResult)
+ {
+ return ((DefaultMacAndDigestResult) result).MacResult;
+ }
+ else if (result is byte[])
+ {
+ return (byte[]) result;
+ }
+
+ throw new InvalidOperationException("result is not byte[] or DefaultSignatureResult");
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/asn1/crmf/AuthenticatorControl.cs b/crypto/src/asn1/crmf/AuthenticatorControl.cs
new file mode 100644
index 000000000..060088b1f
--- /dev/null
+++ b/crypto/src/asn1/crmf/AuthenticatorControl.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class AuthenticatorControl:IControl
+ {
+
+ private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_authenticator;
+
+ private readonly DerUtf8String token;
+
+ public AuthenticatorControl(DerUtf8String token)
+ {
+ this.token = token;
+ }
+
+ public AuthenticatorControl(String token)
+ {
+ this.token = new DerUtf8String(token);
+ }
+
+ public DerObjectIdentifier Type
+ {
+ get { return type; }
+ }
+
+ public Asn1Encodable Value {
+ get { return token; }
+ }
+ }
+}
diff --git a/crypto/src/asn1/crmf/CertificateRequestMessage.cs b/crypto/src/asn1/crmf/CertificateRequestMessage.cs
new file mode 100644
index 000000000..b80c2a3fd
--- /dev/null
+++ b/crypto/src/asn1/crmf/CertificateRequestMessage.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class CertificateRequestMessage
+ {
+ public static readonly int popRaVerified = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_RA_VERIFIED;
+ public static readonly int popSigningKey = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_SIGNING_KEY;
+ public static readonly int popKeyEncipherment = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_KEY_ENCIPHERMENT;
+ public static readonly int popKeyAgreement = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_KEY_AGREEMENT;
+
+ private readonly CertReqMsg certReqMsg;
+ private readonly Controls controls;
+
+ private static CertReqMsg ParseBytes(byte[] encoding)
+
+ {
+ return CertReqMsg.GetInstance(encoding);
+ }
+
+ public CertificateRequestMessage(CertReqMsg certReqMsg)
+ {
+ this.certReqMsg = certReqMsg;
+ this.controls = certReqMsg.CertReq.Controls;
+ }
+
+ public CertReqMsg ToAsn1Structure()
+ {
+ return certReqMsg;
+ }
+
+ public CertTemplate GetCertTemplate()
+ {
+ return this.certReqMsg.CertReq.CertTemplate;
+ }
+
+ public bool HasControls
+ {
+ get { return controls != null; }
+ }
+
+
+ public bool HasControl(DerObjectIdentifier objectIdentifier)
+ {
+ return findControl(objectIdentifier) != null;
+ }
+
+ public IControl GetControl(DerObjectIdentifier type)
+ {
+ AttributeTypeAndValue found = findControl(type);
+ if (found != null)
+ {
+ if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions))
+ {
+ return new PkiArchiveControl(PkiArchiveOptions.GetInstance(found.Value));
+ }
+
+ if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_regToken))
+ {
+ return new RegTokenControl(DerUtf8String.GetInstance(found.Value));
+ }
+
+ if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_authenticator))
+ {
+ return new AuthenticatorControl(DerUtf8String.GetInstance(found.Value));
+ }
+ }
+ return null;
+ }
+
+
+
+
+ public AttributeTypeAndValue findControl(DerObjectIdentifier type)
+ {
+ if (controls == null)
+ {
+ return null;
+ }
+
+ AttributeTypeAndValue[] tAndV = controls.ToAttributeTypeAndValueArray();
+ AttributeTypeAndValue found = null;
+
+ for (int i = 0; i < tAndV.Length; i++)
+ {
+ if (tAndV[i].Type.Equals(type))
+ {
+ found = tAndV[i];
+ break;
+ }
+ }
+
+ return found;
+ }
+
+ public bool HasProofOfPossession
+ {
+ get { return certReqMsg.Popo != null; }
+ }
+
+ public int ProofOfPossession
+ {
+ get { return certReqMsg.Popo.Type; }
+ }
+
+ public bool HasSigningKeyProofOfPossessionWithPkMac
+ {
+ get
+ {
+ ProofOfPossession pop = certReqMsg.Popo;
+
+ if (pop.Type == popSigningKey)
+ {
+ PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object);
+
+ return popoSign.PoposkInput.PublicKeyMac != null;
+ }
+
+ return false;
+
+ }
+ }
+
+ public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider)
+ {
+ ProofOfPossession pop = certReqMsg.Popo;
+ if (pop.Type == popSigningKey)
+ {
+ PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object);
+ if (popoSign.PoposkInput != null && popoSign.PoposkInput.PublicKeyMac != null)
+ {
+ throw new InvalidOperationException("verification requires password check");
+ }
+ return verifySignature(verifierProvider, popoSign);
+ }
+
+ throw new InvalidOperationException("not Signing Key type of proof of possession");
+ }
+
+
+
+ private bool verifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey)
+ {
+ IVerifierFactory verifer;
+ IStreamCalculator calculator;
+ try
+ {
+ verifer = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier);
+ calculator = verifer.CreateCalculator();
+ }
+ catch (Exception ex)
+ {
+ throw new CrmfException("unable to create verifier: "+ex.Message, ex);
+ }
+
+ if (signKey.PoposkInput != null)
+ {
+ byte[] b = signKey.GetDerEncoded();
+ calculator.Stream.Write(b,0,b.Length);
+ }
+ else
+ {
+ byte[] b = certReqMsg.GetDerEncoded();
+ calculator.Stream.Write(b,0,b.Length);
+ }
+
+ DefaultVerifierResult result = (DefaultVerifierResult) calculator.GetResult();
+
+ return result.IsVerified(signKey.Signature.GetBytes());
+ }
+
+ public byte[] GetEncoded()
+ {
+ return certReqMsg.GetEncoded();
+ }
+ }
+}
diff --git a/crypto/src/asn1/crmf/CertificateRequestMessageBuilder.cs b/crypto/src/asn1/crmf/CertificateRequestMessageBuilder.cs
new file mode 100644
index 000000000..df604f4f5
--- /dev/null
+++ b/crypto/src/asn1/crmf/CertificateRequestMessageBuilder.cs
@@ -0,0 +1,261 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class CertificateRequestMessageBuilder
+ {
+ private readonly BigInteger _certReqId;
+ private X509ExtensionsGenerator _extGenerator;
+ private CertTemplateBuilder _templateBuilder;
+ private ArrayList _controls= new ArrayList();
+ private ISignatureFactory _popSigner;
+ private PkMacFactory _pkMacBuilder;
+ private char[] _password;
+ private GeneralName _sender;
+ private int _popoType = ProofOfPossession.TYPE_KEY_ENCIPHERMENT;
+ private PopoPrivKey _popoPrivKey;
+ private Asn1Null _popRaVerified;
+ private PKMacValue _agreeMac;
+
+ public CertificateRequestMessageBuilder(BigInteger certReqId)
+ {
+ this._certReqId = certReqId;
+ this._extGenerator = new X509ExtensionsGenerator();
+ this._templateBuilder = new CertTemplateBuilder();
+ }
+
+ public CertificateRequestMessageBuilder SetPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ {
+ if (publicKeyInfo != null)
+ {
+ _templateBuilder.SetPublicKey(publicKeyInfo);
+ }
+
+ return this;
+ }
+
+
+ public CertificateRequestMessageBuilder SetIssuer(X509Name issuer)
+ {
+ if (issuer != null)
+ {
+ _templateBuilder.SetIssuer(issuer);
+ }
+
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetSubject(X509Name subject)
+ {
+ if (subject != null)
+ {
+ _templateBuilder.SetSubject(subject);
+ }
+
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetSerialNumber(BigInteger serialNumber)
+ {
+ if (serialNumber != null)
+ {
+ _templateBuilder.SetSerialNumber(new DerInteger(serialNumber));
+ }
+
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetValidity(Time notBefore, Time notAfter)
+ {
+ _templateBuilder.SetValidity(new OptionalValidity(notBefore, notAfter));
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder AddExtension(DerObjectIdentifier oid, bool critical,
+ Asn1Encodable value)
+ {
+ _extGenerator.AddExtension(oid,critical, value);
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder AddExtension(DerObjectIdentifier oid, bool critical,
+ byte[] value)
+ {
+ _extGenerator.AddExtension(oid, critical, value);
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetProofOfPossessionSignKeySigner(ISignatureFactory popoSignatureFactory)
+ {
+ if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null)
+ {
+ throw new InvalidOperationException("only one proof of possession is allowed.");
+ }
+
+ this._popoType = ProofOfPossession.TYPE_KEY_ENCIPHERMENT;
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetProofOfPossessionSubsequentMessage(SubsequentMessage msg)
+ {
+ if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null)
+ {
+ throw new InvalidOperationException("only one proof of possession is allowed.");
+ }
+
+ this._popoType = ProofOfPossession.TYPE_KEY_ENCIPHERMENT;
+ this._popoPrivKey = new PopoPrivKey(msg);
+
+
+ return this;
+ }
+
+
+ public CertificateRequestMessageBuilder SetProofOfPossessionSubsequentMessage(int type, SubsequentMessage msg)
+ {
+ if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null)
+ {
+ throw new InvalidOperationException("only one proof of possession is allowed.");
+ }
+
+ if (type != ProofOfPossession.TYPE_KEY_ENCIPHERMENT && type != ProofOfPossession.TYPE_KEY_AGREEMENT)
+ {
+ throw new ArgumentException("type must be ProofOfPossession.TYPE_KEY_ENCIPHERMENT || ProofOfPossession.TYPE_KEY_AGREEMENT");
+ }
+
+ this._popoType = type;
+ this._popoPrivKey = new PopoPrivKey(msg);
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetProofOfPossessionAgreeMac(PKMacValue macValue)
+ {
+ if (_popSigner != null || _popRaVerified != null || _popoPrivKey != null)
+ {
+ throw new InvalidOperationException("only one proof of possession allowed");
+ }
+
+ this._agreeMac = macValue;
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetProofOfPossessionRaVerified()
+ {
+ if (_popSigner != null || _popoPrivKey != null)
+ {
+ throw new InvalidOperationException("only one proof of possession allowed");
+ }
+
+ this._popRaVerified = DerNull.Instance;
+
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetAuthInfoPKMAC(PkMacFactory pkmacFactory, char[] password)
+ {
+ this._pkMacBuilder = pkmacFactory;
+ this._password = password;
+
+ return this;
+ }
+
+ public CertificateRequestMessageBuilder SetAuthInfoSender(X509Name sender)
+ {
+ return SetAuthInfoSender(new GeneralName(sender));
+ }
+
+ public CertificateRequestMessageBuilder SetAuthInfoSender(GeneralName sender)
+ {
+ this._sender = sender;
+ return this;
+ }
+
+ public CertificateRequestMessage Build()
+ {
+ Asn1EncodableVector v = new Asn1EncodableVector();
+
+ v.Add(new DerInteger(this._certReqId));
+
+ if (!this._extGenerator.IsEmpty)
+ {
+ this._templateBuilder.SetExtensions(_extGenerator.Generate());
+ }
+
+ v.Add(_templateBuilder.Build());
+
+ if (_controls.Count>0)
+ {
+ Asn1EncodableVector controlV = new Asn1EncodableVector();
+
+ foreach (Object item in _controls)
+ {
+ IControl control = (IControl) item;
+ controlV.Add(new AttributeTypeAndValue(control.Type, control.Value));
+ }
+
+ v.Add(new DerSequence(controlV));
+ }
+
+ CertRequest request = CertRequest.GetInstance(new DerSequence(v));
+
+ v = new Asn1EncodableVector();
+
+ v.Add(request);
+
+ if (_popSigner != null)
+ {
+ CertTemplate template = request.CertTemplate;
+
+ if (template.Subject == null || template.PublicKey == null)
+ {
+ SubjectPublicKeyInfo pubKeyInfo = request.CertTemplate.PublicKey;
+
+ ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(pubKeyInfo);
+
+ if (_sender != null)
+ {
+ builder.setSender(_sender);
+ }
+ else
+ {
+ // PkMa pkmacGenerator = new PKMACValueGenerator(_pkmacBuilder);
+
+ builder.setPublicKeyMac(_pkMacBuilder, _password);
+ }
+
+ v.Add(new ProofOfPossession(builder.build(_popSigner)));
+ }
+ else
+ {
+ ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(request);
+
+ v.Add(new ProofOfPossession(builder.build(_popSigner)));
+ }
+ }
+ else if (_popoPrivKey != null)
+ {
+ v.Add(new ProofOfPossession(_popoType, _popoPrivKey));
+ }
+ else if (_agreeMac != null)
+ {
+ v.Add(new ProofOfPossession(ProofOfPossession.TYPE_KEY_AGREEMENT,
+ PopoPrivKey.GetInstance(new DerTaggedObject(false, PopoPrivKey.agreeMAC, _agreeMac),true )));
+
+ }
+ else if (_popRaVerified != null)
+ {
+ v.Add(new ProofOfPossession());
+ }
+
+ return new CertificateRequestMessage(CertReqMsg.GetInstance(new DerSequence(v)));
+ }
+ }
+}
diff --git a/crypto/src/asn1/crmf/Controls.cs b/crypto/src/asn1/crmf/Controls.cs
index e8b9f3db0..8f986168c 100644
--- a/crypto/src/asn1/crmf/Controls.cs
+++ b/crypto/src/asn1/crmf/Controls.cs
@@ -4,6 +4,15 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1.Crmf
{
+
+ public interface IControl
+ {
+ DerObjectIdentifier Type { get; }
+
+ Asn1Encodable Value { get; }
+ }
+
+
public class Controls
: Asn1Encodable
{
diff --git a/crypto/src/asn1/crmf/CrmfException.cs b/crypto/src/asn1/crmf/CrmfException.cs
new file mode 100644
index 000000000..7043ccd73
--- /dev/null
+++ b/crypto/src/asn1/crmf/CrmfException.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class CrmfException : Exception
+ {
+ public CrmfException()
+ {
+ }
+
+ public CrmfException(string message) : base(message)
+ {
+ }
+
+ public CrmfException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ protected CrmfException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
diff --git a/crypto/src/asn1/crmf/EncryptedValueBuilder.cs b/crypto/src/asn1/crmf/EncryptedValueBuilder.cs
new file mode 100644
index 000000000..4b57156d4
--- /dev/null
+++ b/crypto/src/asn1/crmf/EncryptedValueBuilder.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+
+// public delegate IBlockCipher BlockCipherCreator(ICipherParameters);
+//
+// public class EncryptedValueBuilder
+// {
+// private readonly IBlockCipher _cipher;
+// private static readonly IDictionary algToDelegate = Platform.CreateHashtable();
+// static EncryptedValueBuilder()
+// {
+// algToDelegate[NistObjectIdentifiers.IdAes128Cbc] = new CipherCreator()
+// {Creator = delegate(ICipherParameters param) { return new AesEngine(); }};
+//
+// }
+//
+//
+// public EncryptedValueBuilder(DerObjectIdentifier alg)
+// {
+//
+// }
+//
+//
+// private static IBlockCipher AesCBC(ICipherParameters param)
+// {
+// if (param is ParametersWithIV ivParam) {
+// return new
+// }
+// else
+// {
+// throw new ArgumentException("expecting param to be ParametersWithIv");
+// }
+// }
+//
+//
+//
+// private class CipherCreator
+// {
+// public BlockCipherCreator Creator { get; set; }
+// }
+//
+// }
+}
diff --git a/crypto/src/asn1/crmf/OptionalValidity.cs b/crypto/src/asn1/crmf/OptionalValidity.cs
index d1a0f7ffb..46fd1f860 100644
--- a/crypto/src/asn1/crmf/OptionalValidity.cs
+++ b/crypto/src/asn1/crmf/OptionalValidity.cs
@@ -33,6 +33,12 @@ namespace Org.BouncyCastle.Asn1.Crmf
return new OptionalValidity(Asn1Sequence.GetInstance(obj));
}
+ public OptionalValidity(Time notBefore, Time notAfter)
+ {
+ this.notBefore = notBefore;
+ this.notAfter = notAfter;
+ }
+
public virtual Time NotBefore
{
get { return notBefore; }
diff --git a/crypto/src/asn1/crmf/PkiArchiveControl.cs b/crypto/src/asn1/crmf/PkiArchiveControl.cs
new file mode 100644
index 000000000..0290fdfe6
--- /dev/null
+++ b/crypto/src/asn1/crmf/PkiArchiveControl.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Cms;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class PkiArchiveControl:IControl
+ {
+ public static readonly int encryptedPrivKey = PkiArchiveOptions.encryptedPrivKey;
+ public static readonly int keyGenParameters = PkiArchiveOptions.keyGenParameters;
+ public static readonly int archiveRemGenPrivKey = PkiArchiveOptions.archiveRemGenPrivKey;
+
+ private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions;
+
+ private readonly PkiArchiveOptions pkiArchiveOptions;
+
+ public PkiArchiveControl(PkiArchiveOptions pkiArchiveOptions)
+ {
+ this.pkiArchiveOptions = pkiArchiveOptions;
+ }
+
+ public DerObjectIdentifier Type
+ {
+ get { return type; }
+ }
+
+ public Asn1Encodable Value
+ {
+ get { return pkiArchiveOptions; }
+ }
+
+ public int ArchiveType
+ {
+ get { return pkiArchiveOptions.Type; }
+ }
+
+ public bool EnvelopedData
+ {
+ get
+ {
+ EncryptedKey encKey = EncryptedKey.GetInstance(pkiArchiveOptions.Value);
+ return !encKey.IsEncryptedValue;
+ }
+ }
+
+ public CmsEnvelopedData GetEnvelopedData()
+ {
+ try
+ {
+ EncryptedKey encKey = EncryptedKey.GetInstance(pkiArchiveOptions.Value);
+ EnvelopedData data = Org.BouncyCastle.Asn1.Cms.EnvelopedData.GetInstance(encKey.Value);
+
+ return new CmsEnvelopedData(new ContentInfo(CmsObjectIdentifiers.EnvelopedData, data));
+ }
+ catch (CmsException e)
+ {
+ throw new CrmfException("CMS parsing error: " + e.Message, e);
+ }
+ catch (Exception e)
+ {
+ throw new CrmfException("CRMF parsing error: "+e.Message, e);
+ }
+ }
+
+ }
+}
diff --git a/crypto/src/asn1/crmf/ProofOfPossessionSigningKeyBuilder.cs b/crypto/src/asn1/crmf/ProofOfPossessionSigningKeyBuilder.cs
new file mode 100644
index 000000000..cbaf834a1
--- /dev/null
+++ b/crypto/src/asn1/crmf/ProofOfPossessionSigningKeyBuilder.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Crypto.Paddings;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class ProofOfPossessionSigningKeyBuilder
+ {
+ private CertRequest _certRequest;
+ private SubjectPublicKeyInfo _pubKeyInfo;
+ private GeneralName _name;
+ private PKMacValue _publicKeyMAC;
+
+ public ProofOfPossessionSigningKeyBuilder(CertRequest certRequest)
+ {
+ this._certRequest = certRequest;
+ }
+
+
+ public ProofOfPossessionSigningKeyBuilder(SubjectPublicKeyInfo pubKeyInfo)
+ {
+ this._pubKeyInfo = pubKeyInfo;
+ }
+
+ public ProofOfPossessionSigningKeyBuilder setSender(GeneralName name)
+ {
+ this._name = name;
+
+ return this;
+ }
+
+ public ProofOfPossessionSigningKeyBuilder setPublicKeyMac(PkMacFactory generator, char[] password)
+ {
+ IStreamCalculator calc = generator.CreateCalculator();
+ byte[] d = _pubKeyInfo.GetDerEncoded();
+ calc.Stream.Write(d, 0, d.Length);
+ calc.Stream.Flush();
+ calc.Stream.Close();
+
+
+ this._publicKeyMAC = new PKMacValue(
+ (AlgorithmIdentifier)generator.AlgorithmDetails,
+ new DerBitString(((DefaultMacAndDigestResult)calc.GetResult()).MacResult));
+
+ return this;
+ }
+
+ public PopoSigningKey build(ISignatureFactory signer)
+ {
+ if (_name != null && _publicKeyMAC != null)
+ {
+ throw new InvalidOperationException("name and publicKeyMAC cannot both be set.");
+ }
+
+ PopoSigningKeyInput popo;
+ byte[] b;
+ IStreamCalculator calc = signer.CreateCalculator();
+ if (_certRequest != null)
+ {
+ popo = null;
+ b = _certRequest.GetDerEncoded();
+ calc.Stream.Write(b, 0, b.Length);
+
+ }
+ else if (_name != null)
+ {
+ popo = new PopoSigningKeyInput(_name, _pubKeyInfo);
+ b = popo.GetDerEncoded();
+ calc.Stream.Write(b, 0, b.Length);
+ }
+ else
+ {
+ popo = new PopoSigningKeyInput(_publicKeyMAC, _pubKeyInfo);
+ b = popo.GetDerEncoded();
+ calc.Stream.Write(b, 0, b.Length);
+ }
+
+ calc.Stream.Flush();
+ calc.Stream.Close();
+ DefaultSignatureResult res = (DefaultSignatureResult)calc.GetResult();
+ return new PopoSigningKey(popo, (AlgorithmIdentifier)signer.AlgorithmDetails, new DerBitString(res.Collect()));
+ }
+
+
+ }
+}
diff --git a/crypto/src/asn1/crmf/RegTokenControl.cs b/crypto/src/asn1/crmf/RegTokenControl.cs
new file mode 100644
index 000000000..77bf32557
--- /dev/null
+++ b/crypto/src/asn1/crmf/RegTokenControl.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Org.BouncyCastle.Asn1.Crmf
+{
+ public class RegTokenControl:IControl
+ {
+ private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_regToken;
+
+ private readonly DerUtf8String token;
+
+ public RegTokenControl(DerUtf8String token)
+ {
+ this.token = token;
+ }
+
+ public RegTokenControl(String token)
+ {
+ this.token = new DerUtf8String(token);
+ }
+
+ public DerObjectIdentifier Type
+ {
+ get { return type; }
+ }
+ public Asn1Encodable Value
+ {
+ get { return token; }
+ }
+ }
+}
diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs
index 249d70499..1ac9f39b7 100644
--- a/crypto/src/cms/CMSSignedGenerator.cs
+++ b/crypto/src/cms/CMSSignedGenerator.cs
@@ -3,11 +3,16 @@ using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.BC;
+using Org.BouncyCastle.Asn1.Bsi;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.CryptoPro;
+using Org.BouncyCastle.Asn1.Eac;
+using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.Rosstandart;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
@@ -21,6 +26,338 @@ using Org.BouncyCastle.X509.Store;
namespace Org.BouncyCastle.Cms
{
+
+ public class DefaultSignatureAlgorithmIdentifierFinder
+ {
+ private static readonly IDictionary algorithms = Platform.CreateHashtable();
+ private static readonly ISet noParams = new HashSet();
+ private static readonly IDictionary _params = Platform.CreateHashtable();
+ private static readonly ISet pkcs15RsaEncryption = new HashSet();
+ private static readonly IDictionary digestOids = Platform.CreateHashtable();
+
+ private static readonly IDictionary digestBuilders = Platform.CreateHashtable();
+
+
+ private static readonly DerObjectIdentifier ENCRYPTION_RSA = PkcsObjectIdentifiers.RsaEncryption;
+ private static readonly DerObjectIdentifier ENCRYPTION_DSA = X9ObjectIdentifiers.IdDsaWithSha1;
+ private static readonly DerObjectIdentifier ENCRYPTION_ECDSA = X9ObjectIdentifiers.ECDsaWithSha1;
+ private static readonly DerObjectIdentifier ENCRYPTION_RSA_PSS = PkcsObjectIdentifiers.IdRsassaPss;
+ private static readonly DerObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.GostR3410x94;
+ private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.GostR3410x2001;
+ private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
+ private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512;
+
+
+ static DefaultSignatureAlgorithmIdentifierFinder()
+ {
+ algorithms["MD2WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
+ algorithms["MD2WITHRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
+ algorithms["MD5WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
+ algorithms["MD5WITHRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
+ algorithms["SHA1WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
+ algorithms["SHA1WITHRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
+ algorithms["SHA-1WITHRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
+ algorithms["SHA224WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
+ algorithms["SHA224WITHRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
+ algorithms["SHA256WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
+ algorithms["SHA256WITHRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
+ algorithms["SHA384WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
+ algorithms["SHA384WITHRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
+ algorithms["SHA512WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
+ algorithms["SHA512WITHRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
+ algorithms["SHA1WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA224WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA256WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA384WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA512WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA3-224WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA3-256WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA3-384WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["SHA3-512WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
+ algorithms["RIPEMD160WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
+ algorithms["RIPEMD160WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
+ algorithms["RIPEMD128WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
+ algorithms["RIPEMD128WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
+ algorithms["RIPEMD256WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
+ algorithms["RIPEMD256WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
+ algorithms["SHA1WITHDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
+ algorithms["SHA-1WITHDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
+ algorithms["DSAWITHSHA1"] = X9ObjectIdentifiers.IdDsaWithSha1;
+ algorithms["SHA224WITHDSA"] = NistObjectIdentifiers.DsaWithSha224;
+ algorithms["SHA256WITHDSA"] = NistObjectIdentifiers.DsaWithSha256;
+ algorithms["SHA384WITHDSA"] = NistObjectIdentifiers.DsaWithSha384;
+ algorithms["SHA512WITHDSA"] = NistObjectIdentifiers.DsaWithSha512;
+ algorithms["SHA3-224WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_224; // id_dsa_with_sha3_224;
+ algorithms["SHA3-256WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_256; //id_dsa_with_sha3_256;
+ algorithms["SHA3-384WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_384; //id_dsa_with_sha3_384;
+ algorithms["SHA3-512WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_512; //id_dsa_with_sha3_512;
+ algorithms["SHA3-224WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_224;// id_ecdsa_with_sha3_224;
+ algorithms["SHA3-256WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_256;//id_ecdsa_with_sha3_256;
+ algorithms["SHA3-384WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_384;//id_ecdsa_with_sha3_384;
+ algorithms["SHA3-512WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_512;//id_ecdsa_with_sha3_512;
+ algorithms["SHA3-224WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224;// id_rsassa_pkcs1_v1_5_with_sha3_224;
+ algorithms["SHA3-256WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256;// id_rsassa_pkcs1_v1_5_with_sha3_256;
+ algorithms["SHA3-384WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384;// id_rsassa_pkcs1_v1_5_with_sha3_384;
+ algorithms["SHA3-512WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512;// id_rsassa_pkcs1_v1_5_with_sha3_512;
+ algorithms["SHA3-224WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224;// id_rsassa_pkcs1_v1_5_with_sha3_224;
+ algorithms["SHA3-256WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256;// id_rsassa_pkcs1_v1_5_with_sha3_256;
+ algorithms["SHA3-384WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384; //id_rsassa_pkcs1_v1_5_with_sha3_384;
+ algorithms["SHA3-512WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512; // id_rsassa_pkcs1_v1_5_with_sha3_512;
+ algorithms["SHA1WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1;
+ algorithms["ECDSAWITHSHA1"] = X9ObjectIdentifiers.ECDsaWithSha1;
+ algorithms["SHA224WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
+ algorithms["SHA256WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
+ algorithms["SHA384WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384;
+ algorithms["SHA512WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256;
+
+
+ algorithms["GOST3411WITHGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
+ algorithms["GOST3411WITHGOST3410-94"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
+ algorithms["GOST3411WITHECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
+ algorithms["GOST3411WITHECGOST3410-2001"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
+ algorithms["GOST3411WITHGOST3410-2001"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
+ algorithms["GOST3411WITHECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
+ algorithms["GOST3411WITHECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
+ algorithms["GOST3411WITHGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
+ algorithms["GOST3411WITHGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
+ algorithms["GOST3411-2012-256WITHECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
+ algorithms["GOST3411-2012-512WITHECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
+ algorithms["GOST3411-2012-256WITHGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256;
+ algorithms["GOST3411-2012-512WITHGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512;
+ algorithms["SHA1WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1;
+ algorithms["SHA224WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224;
+ algorithms["SHA256WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256;
+ algorithms["SHA384WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384;
+ algorithms["SHA512WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512;
+ algorithms["RIPEMD160WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160;
+ algorithms["SHA1WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1;
+ algorithms["SHA224WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224;
+ algorithms["SHA256WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256;
+ algorithms["SHA384WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384;
+ algorithms["SHA512WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512;
+ algorithms["SHA3-512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA3_512;
+ algorithms["SHA512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA512;
+ algorithms["SM3WITHSM2"] = GMObjectIdentifiers.sm2sign_with_sm3;
+
+ algorithms["SHA256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA256;
+ algorithms["SHA512WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA512;
+ algorithms["SHAKE128WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHAKE128;
+ algorithms["SHAKE256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHAKE256;
+
+ algorithms["SHA256WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHA256;
+ algorithms["SHA512WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHA512;
+ algorithms["SHAKE128WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHAKE128;
+ algorithms["SHAKE256WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHAKE256;
+
+
+ //
+ // 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((object)X9ObjectIdentifiers.ECDsaWithSha1);
+ noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha224);
+ noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha256);
+ noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha384);
+ noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha512);
+ noParams.Add((object)X9ObjectIdentifiers.IdDsaWithSha1);
+ noParams.Add((object)NistObjectIdentifiers.DsaWithSha224);
+ noParams.Add((object)NistObjectIdentifiers.DsaWithSha256);
+ noParams.Add((object)NistObjectIdentifiers.DsaWithSha384);
+ noParams.Add((object)NistObjectIdentifiers.DsaWithSha512);
+ noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_224);
+ noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_256);
+ noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_384);
+ noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_512);
+ noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_224);
+ noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_256);
+ noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_384);
+ noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_512);
+
+
+ //
+ // RFC 4491
+ //
+ noParams.Add((object)CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
+ noParams.Add((object)CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+ noParams.Add((object)RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
+ noParams.Add((object)RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
+
+ //
+ // SPHINCS-256
+ //
+ noParams.Add((object)BCObjectIdentifiers.sphincs256_with_SHA512);
+ noParams.Add((object)BCObjectIdentifiers.sphincs256_with_SHA3_512);
+
+ //
+ // XMSS
+ //
+ noParams.Add((object)BCObjectIdentifiers.xmss_with_SHA256);
+ noParams.Add((object)BCObjectIdentifiers.xmss_with_SHA512);
+ noParams.Add((object)BCObjectIdentifiers.xmss_with_SHAKE128);
+ noParams.Add((object)BCObjectIdentifiers.xmss_with_SHAKE256);
+ noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHA256);
+ noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHA512);
+ noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHAKE128);
+ noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHAKE256);
+
+ //
+ // SM2
+ //
+ noParams.Add((object)GMObjectIdentifiers.sm2sign_with_sm3);
+
+ //
+ // PKCS 1.5 encrypted algorithms
+ //
+ pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha1WithRsaEncryption);
+ pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha224WithRsaEncryption);
+ pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha256WithRsaEncryption);
+ pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha384WithRsaEncryption);
+ pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha512WithRsaEncryption);
+ pkcs15RsaEncryption.Add((object)TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
+ pkcs15RsaEncryption.Add((object)TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
+ pkcs15RsaEncryption.Add((object)TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
+ pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224);
+ pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256);
+ pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384);
+ pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512);
+
+ //
+ // explicit params
+ //
+ AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+ _params["SHA1WITHRSAANDMGF1"] = CreatePssParams(sha1AlgId, 20);
+
+ AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
+ _params["SHA224WITHRSAANDMGF1"] = CreatePssParams(sha224AlgId, 28);
+
+ AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
+ _params["SHA256WITHRSAANDMGF1"] = CreatePssParams(sha256AlgId, 32);
+
+ AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
+ _params["SHA384WITHRSAANDMGF1"] = CreatePssParams(sha384AlgId, 48);
+
+ AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
+ _params["SHA512WITHRSAANDMGF1"] = CreatePssParams(sha512AlgId, 64);
+
+ AlgorithmIdentifier sha3_224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_224, DerNull.Instance);
+ _params["SHA3-224WITHRSAANDMGF1"] = CreatePssParams(sha3_224AlgId, 28);
+
+ AlgorithmIdentifier sha3_256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_256, DerNull.Instance);
+ _params["SHA3-256WITHRSAANDMGF1"] = CreatePssParams(sha3_256AlgId, 32);
+
+ AlgorithmIdentifier sha3_384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_384, DerNull.Instance);
+ _params["SHA3-384WITHRSAANDMGF1"] = CreatePssParams(sha3_384AlgId, 48);
+
+ AlgorithmIdentifier sha3_512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_512, DerNull.Instance);
+ _params["SHA3-512WITHRSAANDMGF1"] = CreatePssParams(sha3_512AlgId, 64);
+
+ //
+ // digests
+ //
+ digestOids[PkcsObjectIdentifiers.Sha224WithRsaEncryption] = NistObjectIdentifiers.IdSha224;
+ digestOids[PkcsObjectIdentifiers.Sha256WithRsaEncryption] = NistObjectIdentifiers.IdSha256;
+ digestOids[PkcsObjectIdentifiers.Sha384WithRsaEncryption] = NistObjectIdentifiers.IdSha384;
+ digestOids[PkcsObjectIdentifiers.Sha512WithRsaEncryption] = NistObjectIdentifiers.IdSha512;
+ digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha224;
+ digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha256;
+ digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha384;
+ digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha512;
+ digestOids[NistObjectIdentifiers.IdDsaWithSha3_224] = NistObjectIdentifiers.IdSha3_224;
+ digestOids[NistObjectIdentifiers.IdDsaWithSha3_256] = NistObjectIdentifiers.IdSha3_256;
+ digestOids[NistObjectIdentifiers.IdDsaWithSha3_384] = NistObjectIdentifiers.IdSha3_384;
+ digestOids[NistObjectIdentifiers.IdDsaWithSha3_512] = NistObjectIdentifiers.IdSha3_512;
+ digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_224] = NistObjectIdentifiers.IdSha3_224;
+ digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_256] = NistObjectIdentifiers.IdSha3_256;
+ digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_384] = NistObjectIdentifiers.IdSha3_384;
+ digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_512] = NistObjectIdentifiers.IdSha3_512;
+ digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224] = NistObjectIdentifiers.IdSha3_224;
+ digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256] = NistObjectIdentifiers.IdSha3_256;
+ digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384] = NistObjectIdentifiers.IdSha3_384;
+ digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512] = NistObjectIdentifiers.IdSha3_512;
+
+ digestOids[PkcsObjectIdentifiers.MD2WithRsaEncryption] = PkcsObjectIdentifiers.MD2;
+ digestOids[PkcsObjectIdentifiers.MD4WithRsaEncryption] = PkcsObjectIdentifiers.MD4;
+ digestOids[PkcsObjectIdentifiers.MD5WithRsaEncryption] = PkcsObjectIdentifiers.MD5;
+ digestOids[PkcsObjectIdentifiers.Sha1WithRsaEncryption] = OiwObjectIdentifiers.IdSha1;
+ digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128] = TeleTrusTObjectIdentifiers.RipeMD128;
+ digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160] = TeleTrusTObjectIdentifiers.RipeMD160;
+ digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256] = TeleTrusTObjectIdentifiers.RipeMD256;
+ digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94] = CryptoProObjectIdentifiers.GostR3411;
+ digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001] = CryptoProObjectIdentifiers.GostR3411;
+ digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256;
+ digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512;
+ digestOids[GMObjectIdentifiers.sm2sign_with_sm3] = GMObjectIdentifiers.sm3;
+
+ }
+
+ private static AlgorithmIdentifier Generate(string signatureAlgorithm)
+ {
+ AlgorithmIdentifier sigAlgId;
+ AlgorithmIdentifier encAlgId;
+ AlgorithmIdentifier digAlgId;
+
+ string algorithmName = Strings.ToUpperCase(signatureAlgorithm);
+ DerObjectIdentifier sigOID = (DerObjectIdentifier)algorithms[algorithmName];
+ if (sigOID == null)
+ {
+ throw new ArgumentException("Unknown signature type requested: " + algorithmName);
+ }
+
+ if (noParams.Contains(sigOID))
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID);
+ }
+ else if (_params.Contains(algorithmName))
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID, (Asn1Encodable)_params[algorithmName]);
+ }
+ else
+ {
+ sigAlgId = new AlgorithmIdentifier(sigOID, DerNull.Instance);
+ }
+
+ if (pkcs15RsaEncryption.Contains(sigOID))
+ {
+ encAlgId = new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance);
+ }
+ else
+ {
+ encAlgId = sigAlgId;
+ }
+
+ if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
+ {
+ digAlgId = ((RsassaPssParameters)sigAlgId.Parameters).HashAlgorithm;
+ }
+ else
+ {
+ digAlgId = new AlgorithmIdentifier((DerObjectIdentifier)digestOids[sigOID], DerNull.Instance);
+ }
+
+ return sigAlgId;
+ }
+
+ private static RsassaPssParameters CreatePssParams(AlgorithmIdentifier hashAlgId, int saltSize)
+ {
+ return new RsassaPssParameters(
+ hashAlgId,
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId),
+ new DerInteger(saltSize),
+ new DerInteger(1));
+ }
+
+ public AlgorithmIdentifier Find(string sigAlgName)
+ {
+
+ return Generate(sigAlgName);
+ }
+ }
+
+
+
+
+
+
public class DefaultDigestAlgorithmIdentifierFinder
{
private static readonly IDictionary digestOids = Platform.CreateHashtable();
diff --git a/crypto/src/crypto/IMacFactory.cs b/crypto/src/crypto/IMacFactory.cs
new file mode 100644
index 000000000..d6b7ddfa7
--- /dev/null
+++ b/crypto/src/crypto/IMacFactory.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Org.BouncyCastle.Crypto
+{
+ public interface IMacFactory
+ {
+ /// <summary>The algorithm details object for this calculator.</summary>
+ Object AlgorithmDetails { get; }
+
+ /// <summary>
+ /// Create a stream calculator for this signature calculator. The stream
+ /// calculator is used for the actual operation of entering the data to be signed
+ /// and producing the signature block.
+ /// </summary>
+ /// <returns>A calculator producing an IBlockResult with a signature in it.</returns>
+ IStreamCalculator CreateCalculator();
+ }
+}
diff --git a/crypto/src/crypto/operators/Asn1Mac.cs b/crypto/src/crypto/operators/Asn1Mac.cs
new file mode 100644
index 000000000..ff70e5849
--- /dev/null
+++ b/crypto/src/crypto/operators/Asn1Mac.cs
@@ -0,0 +1,410 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Asn1.Iana;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Crypto.Operators
+{
+
+ public class DefaultMacStreamCalculator : IStreamCalculator
+ {
+ private readonly MacSink _stream;
+
+ public DefaultMacStreamCalculator(IMac mac)
+ {
+ _stream = new MacSink(mac);
+ }
+
+ public void Init(KeyParameter key)
+ {
+ _stream.Mac.Init(key);
+ }
+
+ public Stream Stream
+ {
+ get { return _stream; }
+ }
+ public object GetResult()
+ {
+ byte[] res = new byte[_stream.Mac.GetMacSize()];
+ _stream.Mac.DoFinal(res, 0);
+ return res;
+ }
+ }
+
+
+ public class DefaultMacAndDigestStreamCalculator : IStreamCalculator
+ {
+
+ private readonly MacSink macSink;
+ private readonly DigestSink digestSink;
+ private readonly Stream _stream;
+
+
+ public DefaultMacAndDigestStreamCalculator(IMac imac, IDigest idigest)
+ {
+ this.macSink = new MacSink(imac);
+ this.digestSink = new DigestSink(idigest);
+ _stream = new MergedStream(macSink,digestSink);
+ }
+
+
+ public void Init(KeyParameter macKey)
+ {
+ this.macSink.Mac.Init(macKey);
+ }
+
+ public void Init(PbmParameter parameter, byte[] password)
+ {
+
+ byte[] pw = password;
+ byte[] salt = parameter.Salt.GetOctets();
+ byte[] K = new byte[pw.Length + salt.Length];
+
+ System.Array.Copy(pw,K,pw.Length);
+ System.Array.Copy(salt,0,K,pw.Length,salt.Length);
+ int iter = parameter.IterationCount.Value.IntValue;
+ this.digestSink.Digest.Reset();
+
+ IDigest dig = DigestUtilities.GetDigest(digestSink.Digest.AlgorithmName);
+
+
+
+ dig.BlockUpdate(K,0,K.Length);
+ K = new byte[dig.GetDigestSize()];
+ dig.DoFinal(K, 0);
+ iter--;
+
+ do
+ {
+ dig.BlockUpdate(K,0,K.Length);
+ dig.DoFinal(K, 0);
+ } while (--iter > 0);
+
+ macSink.Mac.Init(new KeyParameter(K));
+ }
+
+
+
+ public Stream Stream
+ {
+ get { return _stream; }
+ }
+
+
+ public object GetResult()
+ {
+ byte[] macResult = new byte[macSink.Mac.GetMacSize()];
+ macSink.Mac.DoFinal(macResult, 0);
+ byte[] digestResult = new byte[digestSink.Digest.GetByteLength()];
+ digestSink.Digest.DoFinal(digestResult, 0);
+ return new DefaultMacAndDigestResult(digestResult, macResult);
+ }
+
+ private class MergedStream : Stream
+ {
+
+ private Stream aStream;
+ private Stream bStream;
+
+ public MergedStream(Stream aStream, Stream bStream)
+ {
+ this.aStream = aStream;
+ this.bStream = bStream;
+ }
+
+ public override void Flush()
+ {
+ aStream.Flush();
+ bStream.Flush();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ aStream.Seek(offset, origin);
+ return bStream.Seek(offset, origin);
+ }
+
+ public override void SetLength(long value)
+ {
+ aStream.SetLength(value);
+ bStream.SetLength(value);
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ aStream.Read(buffer, offset, count);
+ return bStream.Read(buffer, offset, count);
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ aStream.Write(buffer, offset, count);
+ bStream.Write(buffer, offset, count);
+ }
+
+ public override bool CanRead
+ {
+ get { return bStream.CanRead && aStream.CanRead; }
+ }
+ public override bool CanSeek
+ {
+ get { return bStream.CanSeek && aStream.CanSeek; }
+
+ }
+ public override bool CanWrite {
+ get { return bStream.CanWrite && aStream.CanWrite; }
+
+ }
+ public override long Length {
+ get
+ {
+ return aStream.Length;
+ }
+ }
+ public override long Position
+ {
+ get { return aStream.Position; }
+
+ set { aStream.Position = value; }
+ }
+ }
+ }
+
+ public struct DefaultMacAndDigestResult
+ {
+ public DefaultMacAndDigestResult(byte[] digestResult, byte[] macResult)
+ {
+ DigestResult = digestResult;
+ MacResult = macResult;
+ }
+
+ public byte[] DigestResult { get; }
+
+ public byte[] MacResult { get; }
+ }
+
+ public class Asn1MacFactory : IMacFactory
+ {
+ protected readonly AlgorithmIdentifier MacAlgorithmIdentifier;
+
+
+
+ public Asn1MacFactory(AlgorithmIdentifier macAlgorithmIdentifier)
+ {
+ MacAlgorithmIdentifier = macAlgorithmIdentifier;
+ }
+
+
+
+ public virtual object AlgorithmDetails
+ {
+ get { return MacAlgorithmIdentifier; }
+ }
+
+ public virtual IStreamCalculator CreateCalculator()
+ {
+ IMac mac = MacUtilities.GetMac(MacAlgorithmIdentifier.Algorithm);
+ return new DefaultMacStreamCalculator(mac);
+ }
+ }
+
+
+ public interface IMacFactoryProvider
+ {
+ IMacFactory CreateMacFactory(AlgorithmIdentifier algorithmIdentifier);
+ }
+
+ public class Asn1MacFactoryProvider : IMacFactoryProvider
+ {
+ public IMacFactory CreateMacFactory(AlgorithmIdentifier algorithmIdentifier)
+ {
+ return new Asn1MacFactory(algorithmIdentifier);
+ }
+
+ public IMacFactory CreateMacFactory(AlgorithmIdentifier digestAlgorithmIdentifier, AlgorithmIdentifier macAlgorithmIdentifier)
+ {
+ return new PkMacFactory(digestAlgorithmIdentifier,macAlgorithmIdentifier);
+ }
+
+ public IMacFactory CreateMacFactory(PbmParameter parameter)
+ {
+ return new PkMacFactory(parameter);
+ }
+
+ }
+
+
+
+ public class PkMacFactory:Asn1MacFactory
+ {
+ private readonly AlgorithmIdentifier _digestAlgorithmIdentifier;
+ private byte[] password;
+ private int iterationCount;
+ private byte[] salt;
+
+
+
+ public PkMacFactory(SecureRandom random) : base(new AlgorithmIdentifier(IanaObjectIdentifiers.HmacSha1))
+ {
+ this._digestAlgorithmIdentifier = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+ this.iterationCount = 1000;
+ this.salt = new byte[20];
+ random.NextBytes(salt);
+ }
+
+ public PkMacFactory(AlgorithmIdentifier digestAlgorithmIdentifier, AlgorithmIdentifier macAlgorithmIdentifier) : base(macAlgorithmIdentifier)
+ {
+ this._digestAlgorithmIdentifier = digestAlgorithmIdentifier;
+ }
+
+ public PkMacFactory(PbmParameter parameter):base(parameter.Mac)
+ {
+ this._digestAlgorithmIdentifier = parameter.Owf;
+ this.salt = parameter.Salt.GetOctets();
+ this.iterationCount = parameter.IterationCount.Value.IntValue;
+ }
+
+ public override object AlgorithmDetails
+ {
+ get
+ {
+ return new AlgorithmIdentifier(CmpObjectIdentifiers.passwordBasedMac,
+ new PbmParameter(salt, _digestAlgorithmIdentifier, iterationCount, MacAlgorithmIdentifier));
+ }
+ }
+
+
+ public int IterationCount
+ {
+ set { this.iterationCount = value; }
+ }
+ public byte[] Salt
+ {
+ set { this.salt = value;}
+ }
+ public byte[] Password {
+ set { this.password = value; }
+ }
+
+
+ public override IStreamCalculator CreateCalculator()
+ {
+
+ DefaultMacAndDigestStreamCalculator calc = new DefaultMacAndDigestStreamCalculator(
+ MacUtilities.GetMac(this.MacAlgorithmIdentifier.Algorithm),
+ DigestUtilities.GetDigest(_digestAlgorithmIdentifier.Algorithm));
+
+ PbmParameter parameter = new PbmParameter(salt, _digestAlgorithmIdentifier,iterationCount,MacAlgorithmIdentifier);
+ calc.Init(parameter, password);
+
+
+ return calc;
+ }
+
+ }
+
+
+ public class MacVerifierFactory : IVerifierFactory
+ {
+ private readonly IMacFactory _macFactory;
+
+
+ public MacVerifierFactory(IMacFactory macFactory)
+ {
+ this._macFactory = macFactory;
+ }
+
+ public object AlgorithmDetails
+ {
+ get { return _macFactory.AlgorithmDetails; }
+ }
+ public IStreamCalculator CreateCalculator()
+ {
+ return new MacVerifier(_macFactory.CreateCalculator());
+ }
+
+ private class MacVerifier : IStreamCalculator
+ {
+ public IStreamCalculator _calculator;
+
+ public MacVerifier(IStreamCalculator calculator)
+ {
+ _calculator = calculator;
+ }
+
+ public Stream Stream
+ {
+ get { return _calculator.Stream; }
+ }
+
+ public object GetResult()
+ {
+ object result = _calculator.GetResult();
+ if (result is byte[])
+ {
+ return new DefaultMacVerifierResult((byte[])result);
+ } else if (result is DefaultMacAndDigestResult)
+ {
+ return new DefaultMacVerifierResult(((DefaultMacAndDigestResult)result).MacResult);
+
+ }
+
+ throw new InvalidOperationException("calculator did not return byte[] or DefaultMacVerifierResult");
+ }
+ }
+
+ }
+
+
+ public class DefaultMacVerifierResult:IVerifier
+ {
+ private readonly byte[] _calculatedResult;
+
+ public DefaultMacVerifierResult(byte[] calculatedResult)
+ {
+ this._calculatedResult = calculatedResult;
+ }
+
+
+ public bool IsVerified(byte[] data)
+ {
+ return Arrays.ConstantTimeAreEqual(_calculatedResult, data);
+ }
+
+ public bool IsVerified(byte[] source, int off, int length)
+ {
+ if (_calculatedResult.Length != length)
+ {
+ return false;
+ }
+
+ //
+ // Must be constant time.
+ //
+ int j = 0;
+ int nonEqual = 0;
+ for (int i = off; i < off + length; i++)
+ {
+ nonEqual |= (_calculatedResult[j++] ^ source[i]);
+ }
+
+ return nonEqual == 0;
+ }
+ }
+
+
+}
diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs
index 3fa193273..3962a4a15 100644
--- a/crypto/src/crypto/operators/Asn1Signature.cs
+++ b/crypto/src/crypto/operators/Asn1Signature.cs
@@ -236,6 +236,8 @@ namespace Org.BouncyCastle.Crypto.Operators
}
}
+
+
/// <summary>
/// Calculator factory class for signature generation in ASN.1 based profiles that use an AlgorithmIdentifier to preserve
/// signature algorithm details.
diff --git a/crypto/src/crypto/operators/GenericKey.cs b/crypto/src/crypto/operators/GenericKey.cs
new file mode 100644
index 000000000..b2df74661
--- /dev/null
+++ b/crypto/src/crypto/operators/GenericKey.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Crypto.Operators
+{
+ public class GenericKey
+ {
+ private AlgorithmIdentifier algorithmIdentifier;
+ private object representation;
+
+ public GenericKey(object representation)
+ {
+ algorithmIdentifier = null;
+ this.representation = representation;
+ }
+
+ public GenericKey(AlgorithmIdentifier algorithmIdentifier, byte[] representation)
+ {
+ this.algorithmIdentifier = algorithmIdentifier;
+ this.representation = representation;
+ }
+
+ public GenericKey(AlgorithmIdentifier algorithmIdentifier, object representation)
+ {
+ this.algorithmIdentifier = algorithmIdentifier;
+ this.representation = representation;
+ }
+
+ public AlgorithmIdentifier AlgorithmIdentifier
+ {
+ get { return algorithmIdentifier; }
+ }
+
+ public object Representation
+ {
+ get { return representation; }
+ }
+ }
+}
diff --git a/crypto/src/util/Strings.cs b/crypto/src/util/Strings.cs
index 3937a087f..73a15ea73 100644
--- a/crypto/src/util/Strings.cs
+++ b/crypto/src/util/Strings.cs
@@ -6,6 +6,31 @@ namespace Org.BouncyCastle.Utilities
/// <summary> General string utilities.</summary>
public abstract class Strings
{
+
+ public static string ToUpperCase(string original)
+ {
+ bool changed = false;
+ char[] chars = original.ToCharArray();
+
+ for (int i = 0; i != chars.Length; i++)
+ {
+ char ch = chars[i];
+ if ('a' <= ch && 'z' >= ch)
+ {
+ changed = true;
+ chars[i] = (char)(ch - 'a' + 'A');
+ }
+ }
+
+ if (changed)
+ {
+ return new String(chars);
+ }
+
+ return original;
+ }
+
+
internal static bool IsOneOf(string s, params string[] candidates)
{
foreach (string candidate in candidates)
diff --git a/crypto/test/src/cms/test/AllTests.cs b/crypto/test/src/cms/test/AllTests.cs
index b47374914..7ab5721ac 100644
--- a/crypto/test/src/cms/test/AllTests.cs
+++ b/crypto/test/src/cms/test/AllTests.cs
@@ -3,7 +3,7 @@ using System;
using NUnit.Core;
using NUnit.Framework;
-
+using Org.BouncyCastle.Asn1.Tests;
using Org.BouncyCastle.Utilities.Test;
namespace Org.BouncyCastle.Cms.Tests
@@ -21,6 +21,7 @@ namespace Org.BouncyCastle.Cms.Tests
get
{
TestSuite suite = new TestSuite("CMS Tests");
+ suite.Add(new ProtectedMessageTest());
suite.Add(new CompressedDataTest());
suite.Add(new CompressedDataStreamTest());
suite.Add(new EnvelopedDataTest());
|