diff --git a/crypto/src/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs
index fdcdeb90d..79394094d 100644
--- a/crypto/src/cmp/ProtectedPkiMessage.cs
+++ b/crypto/src/cmp/ProtectedPkiMessage.cs
@@ -139,12 +139,8 @@ namespace Org.BouncyCastle.Cmp
private TResult Process<TResult>(IStreamCalculator<TResult> streamCalculator)
{
- using (var s = streamCalculator.Stream)
- {
- new DerSequence(m_pkiMessage.Header, m_pkiMessage.Body).EncodeTo(s, Asn1Encodable.Der);
- }
-
- return streamCalculator.GetResult();
+ var asn1Encodable = new DerSequence(m_pkiMessage.Header, m_pkiMessage.Body);
+ return X509Utilities.CalculateResult(streamCalculator, asn1Encodable);
}
}
}
diff --git a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
index 508b00ff5..a3070ee56 100644
--- a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
+++ b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs
@@ -97,14 +97,12 @@ namespace Org.BouncyCastle.Cmp
if (null == body)
throw new InvalidOperationException("body must be set before building");
- var calculator = signatureFactory.CreateCalculator();
-
if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails))
throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier");
FinalizeHeader(algorithmDetails);
PkiHeader header = m_hdrBuilder.Build();
- DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
+ DerBitString protection = X509Utilities.GenerateSignature(signatureFactory, new DerSequence(header, body));
return FinalizeMessage(header, protection);
}
@@ -113,14 +111,12 @@ namespace Org.BouncyCastle.Cmp
if (null == body)
throw new InvalidOperationException("body must be set before building");
- var calculator = macFactory.CreateCalculator();
-
if (!(macFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails))
throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier");
FinalizeHeader(algorithmDetails);
PkiHeader header = m_hdrBuilder.Build();
- DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
+ DerBitString protection = X509Utilities.GenerateMac(macFactory, new DerSequence(header, body));
return FinalizeMessage(header, protection);
}
@@ -146,15 +142,5 @@ namespace Org.BouncyCastle.Cmp
return new ProtectedPkiMessage(new PkiMessage(header, body, protection, cmpCertificates));
}
-
- private byte[] CalculateSignature(IStreamCalculator<IBlockResult> signer, PkiHeader header, PkiBody body)
- {
- using (var s = signer.Stream)
- {
- new DerSequence(header, body).EncodeTo(s);
- }
-
- return signer.GetResult().Collect();
- }
}
}
diff --git a/crypto/src/crmf/CertificateRequestMessage.cs b/crypto/src/crmf/CertificateRequestMessage.cs
index 0a246aaa4..36149c791 100644
--- a/crypto/src/crmf/CertificateRequestMessage.cs
+++ b/crypto/src/crmf/CertificateRequestMessage.cs
@@ -178,43 +178,25 @@ namespace Org.BouncyCastle.Crmf
{
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);
+
+ return VerifySignature(verifierProvider, popoSign);
}
throw new InvalidOperationException("not Signing Key type of proof of possession");
}
- private bool verifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey)
+ private bool VerifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey)
{
- IVerifierFactory verifer;
- IStreamCalculator<IVerifier> calculator;
- try
- {
- verifer = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier);
- calculator = verifer.CreateCalculator();
- }
- catch (Exception ex)
- {
- throw new CrmfException("unable to create verifier: " + ex.Message, ex);
- }
+ var verifierFactory = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier);
- if (signKey.PoposkInput != null)
+ Asn1Encodable asn1Encodable = signKey.PoposkInput;
+ if (asn1Encodable == null)
{
- byte[] b = signKey.GetDerEncoded();
- calculator.Stream.Write(b, 0, b.Length);
+ asn1Encodable = certReqMsg.CertReq;
}
- else
- {
- byte[] b = certReqMsg.CertReq.GetDerEncoded();
- calculator.Stream.Write(b, 0, b.Length);
- }
-
- IVerifier result = calculator.GetResult();
- return result.IsVerified(signKey.Signature.GetBytes());
+ return X509.X509Utilities.VerifySignature(verifierFactory, asn1Encodable, signKey.Signature);
}
/// <summary>
diff --git a/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs b/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs
index 8d2ea0bac..02af74924 100644
--- a/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs
+++ b/crypto/src/crmf/ProofOfPossessionSigningKeyBuilder.cs
@@ -1,12 +1,11 @@
using System;
using System.IO;
+using System.Net.Security;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Operators;
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crmf
{
@@ -55,43 +54,33 @@ namespace Org.BouncyCastle.Crmf
throw new InvalidOperationException("name and publicKeyMAC cannot both be set.");
PopoSigningKeyInput popo;
+ Asn1Encodable asn1Encodable;
- IStreamCalculator<IBlockResult> calc = signer.CreateCalculator();
- using (Stream sigStream = calc.Stream)
+ if (_certRequest != null)
{
- if (_certRequest != null)
- {
- popo = null;
- _certRequest.EncodeTo(sigStream, Asn1Encodable.Der);
- }
- else if (_name != null)
- {
- popo = new PopoSigningKeyInput(_name, _pubKeyInfo);
- popo.EncodeTo(sigStream, Asn1Encodable.Der);
- }
- else
- {
- popo = new PopoSigningKeyInput(_publicKeyMAC, _pubKeyInfo);
- popo.EncodeTo(sigStream, Asn1Encodable.Der);
- }
+ popo = null;
+ asn1Encodable = _certRequest;
+ }
+ else if (_name != null)
+ {
+ popo = new PopoSigningKeyInput(_name, _pubKeyInfo);
+ asn1Encodable = popo;
+ }
+ else
+ {
+ popo = new PopoSigningKeyInput(_publicKeyMAC, _pubKeyInfo);
+ asn1Encodable = popo;
}
- var signature = calc.GetResult().Collect();
+ var signature = X509.X509Utilities.GenerateSignature(signer, asn1Encodable);
- return new PopoSigningKey(popo, (AlgorithmIdentifier)signer.AlgorithmDetails, new DerBitString(signature));
+ return new PopoSigningKey(popo, (AlgorithmIdentifier)signer.AlgorithmDetails, signature);
}
- private ProofOfPossessionSigningKeyBuilder ImplSetPublicKeyMac(IMacFactory fact)
+ private ProofOfPossessionSigningKeyBuilder ImplSetPublicKeyMac(IMacFactory macFactory)
{
- IStreamCalculator<IBlockResult> calc = fact.CreateCalculator();
- using (var stream = calc.Stream)
- {
- _pubKeyInfo.EncodeTo(stream, Asn1Encodable.Der);
- }
-
- var mac = calc.GetResult().Collect();
-
- this._publicKeyMAC = new PKMacValue((AlgorithmIdentifier)fact.AlgorithmDetails, new DerBitString(mac));
+ var macValue = X509.X509Utilities.GenerateMac(macFactory, _pubKeyInfo);
+ this._publicKeyMAC = new PKMacValue((AlgorithmIdentifier)macFactory.AlgorithmDetails, macValue);
return this;
}
}
diff --git a/crypto/src/ocsp/BasicOCSPRespGenerator.cs b/crypto/src/ocsp/BasicOCSPRespGenerator.cs
index ff7ae33d3..3d89dfd38 100644
--- a/crypto/src/ocsp/BasicOCSPRespGenerator.cs
+++ b/crypto/src/ocsp/BasicOCSPRespGenerator.cs
@@ -164,12 +164,10 @@ namespace Org.BouncyCastle.Ocsp
this.responseExtensions = responseExtensions;
}
- private BasicOcspResp GenerateResponse(
- ISignatureFactory signatureCalculator,
- X509Certificate[] chain,
- DateTime producedAt)
+ private BasicOcspResp GenerateResponse(ISignatureFactory signatureFactory, X509Certificate[] chain,
+ DateTime producedAt)
{
- AlgorithmIdentifier signingAlgID = (AlgorithmIdentifier)signatureCalculator.AlgorithmDetails;
+ AlgorithmIdentifier signingAlgID = (AlgorithmIdentifier)signatureFactory.AlgorithmDetails;
DerObjectIdentifier signingAlgorithm = signingAlgID.Algorithm;
Asn1EncodableVector responses = new Asn1EncodableVector();
@@ -186,26 +184,20 @@ namespace Org.BouncyCastle.Ocsp
}
}
- ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new Asn1GeneralizedTime(producedAt),
+ var responseData = new ResponseData(responderID.ToAsn1Object(), new Asn1GeneralizedTime(producedAt),
new DerSequence(responses), responseExtensions);
- DerBitString bitSig;
+ DerBitString bitSig;
try
{
- IStreamCalculator<IBlockResult> streamCalculator = signatureCalculator.CreateCalculator();
- using (Stream sigStream = streamCalculator.Stream)
- {
- tbsResp.EncodeTo(sigStream, Asn1Encodable.Der);
- }
-
- bitSig = new DerBitString(streamCalculator.GetResult().Collect());
+ bitSig = X509.X509Utilities.GenerateSignature(signatureFactory, responseData);
}
catch (Exception e)
{
throw new OcspException("exception processing TBSRequest: " + e, e);
}
- AlgorithmIdentifier sigAlgId = OcspUtilities.GetSigAlgID(signingAlgorithm);
+ AlgorithmIdentifier sigAlgID = OcspUtilities.GetSigAlgID(signingAlgorithm);
DerSequence chainSeq = null;
if (chain != null && chain.Length > 0)
@@ -230,7 +222,7 @@ namespace Org.BouncyCastle.Ocsp
chainSeq = new DerSequence(v);
}
- return new BasicOcspResp(new BasicOcspResponse(tbsResp, sigAlgId, bitSig, chainSeq));
+ return new BasicOcspResp(new BasicOcspResponse(responseData, sigAlgID, bitSig, chainSeq));
}
public BasicOcspResp Generate(
diff --git a/crypto/src/pkcs/Pkcs10CertificationRequest.cs b/crypto/src/pkcs/Pkcs10CertificationRequest.cs
index dbaaa34f6..c3e21f8ed 100644
--- a/crypto/src/pkcs/Pkcs10CertificationRequest.cs
+++ b/crypto/src/pkcs/Pkcs10CertificationRequest.cs
@@ -269,10 +269,7 @@ namespace Org.BouncyCastle.Pkcs
Init(signatureFactory, subject, publicKey, attributes);
}
- private void Init(
- ISignatureFactory signatureFactory,
- X509Name subject,
- AsymmetricKeyParameter publicKey,
+ private void Init(ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey,
Asn1Set attributes)
{
this.sigAlgId = (AlgorithmIdentifier)signatureFactory.AlgorithmDetails;
@@ -281,14 +278,7 @@ namespace Org.BouncyCastle.Pkcs
this.reqInfo = new CertificationRequestInfo(subject, pubInfo, attributes);
- IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator();
- using (Stream sigStream = streamCalculator.Stream)
- {
- reqInfo.EncodeTo(sigStream, Der);
- }
-
- // Generate Signature.
- sigBits = new DerBitString(streamCalculator.GetResult().Collect());
+ sigBits = X509.X509Utilities.GenerateSignature(signatureFactory, reqInfo);
}
// internal Pkcs10CertificationRequest(
@@ -337,18 +327,11 @@ namespace Org.BouncyCastle.Pkcs
return Verify(verifierProvider.CreateVerifierFactory(sigAlgId));
}
- public bool Verify(
- IVerifierFactory verifier)
+ public bool Verify(IVerifierFactory verifier)
{
try
{
- IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator();
- using (var stream = streamCalculator.Stream)
- {
- reqInfo.EncodeTo(stream, Asn1Encodable.Der);
- }
-
- return streamCalculator.GetResult().IsVerified(sigBits.GetOctets());
+ return X509.X509Utilities.VerifySignature(verifier, reqInfo, sigBits);
}
catch (Exception e)
{
diff --git a/crypto/src/x509/X509Utilities.cs b/crypto/src/x509/X509Utilities.cs
index bb9b7155f..3ab6b926c 100644
--- a/crypto/src/x509/X509Utilities.cs
+++ b/crypto/src/x509/X509Utilities.cs
@@ -14,7 +14,7 @@ using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.X509
{
- internal class X509Utilities
+ internal static class X509Utilities
{
private static readonly Dictionary<string, DerObjectIdentifier> m_algorithms =
new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
@@ -126,7 +126,17 @@ namespace Org.BouncyCastle.X509
m_exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64));
}
- private static RsassaPssParameters CreatePssParams(
+ internal static TResult CalculateResult<TResult>(IStreamCalculator<TResult> streamCalculator,
+ Asn1Encodable asn1Encodable)
+ {
+ using (var stream = streamCalculator.Stream)
+ {
+ asn1Encodable.EncodeTo(stream, Asn1Encodable.Der);
+ }
+ return streamCalculator.GetResult();
+ }
+
+ private static RsassaPssParameters CreatePssParams(
AlgorithmIdentifier hashAlgId,
int saltSize)
{
@@ -137,7 +147,23 @@ namespace Org.BouncyCastle.X509
new DerInteger(1));
}
- internal static DerObjectIdentifier GetAlgorithmOid(string algorithmName)
+ internal static DerBitString CollectDerBitString(IBlockResult result)
+ {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ var maxResultLength = result.GetMaxResultLength();
+ Span<byte> data = maxResultLength <= 512
+ ? stackalloc byte[maxResultLength]
+ : new byte[maxResultLength];
+ int resultLength = result.Collect(data);
+ data = data[..resultLength];
+#else
+ var data = result.Collect();
+#endif
+
+ return new DerBitString(data);
+ }
+
+ internal static DerObjectIdentifier GetAlgorithmOid(string algorithmName)
{
if (m_algorithms.TryGetValue(algorithmName, out var oid))
return oid;
@@ -161,16 +187,29 @@ namespace Org.BouncyCastle.X509
return CollectionUtilities.Proxy(m_algorithms.Keys);
}
+ internal static DerBitString GenerateBitString(IStreamCalculator<IBlockResult> streamCalculator,
+ Asn1Encodable asn1Encodable)
+ {
+ var result = CalculateResult(streamCalculator, asn1Encodable);
+ return CollectDerBitString(result);
+ }
+
+ internal static DerBitString GenerateMac(IMacFactory macFactory, Asn1Encodable asn1Encodable)
+ {
+ return GenerateBitString(macFactory.CreateCalculator(), asn1Encodable);
+ }
+
internal static DerBitString GenerateSignature(ISignatureFactory signatureFactory, Asn1Encodable asn1Encodable)
{
- var result = CalculateResult(signatureFactory.CreateCalculator(), asn1Encodable);
- return new DerBitString(result.Collect());
+ return GenerateBitString(signatureFactory.CreateCalculator(), asn1Encodable);
}
internal static bool VerifySignature(IVerifierFactory verifierFactory, Asn1Encodable asn1Encodable,
DerBitString signature)
{
var result = CalculateResult(verifierFactory.CreateCalculator(), asn1Encodable);
+
+ // TODO[api] Use GetOctetsSpan() once IsVerified(ReadOnlySpan<byte>) is available
return result.IsVerified(signature.GetOctets());
}
@@ -190,15 +229,5 @@ namespace Org.BouncyCastle.X509
return new DerTaggedObject(true, tagNo, new DerSequence(extV));
}
-
- private static TResult CalculateResult<TResult>(IStreamCalculator<TResult> streamCalculator,
- Asn1Encodable asn1Encodable)
- {
- using (var stream = streamCalculator.Stream)
- {
- asn1Encodable.EncodeTo(stream, Asn1Encodable.Der);
- }
- return streamCalculator.GetResult();
- }
}
}
diff --git a/crypto/src/x509/X509V1CertificateGenerator.cs b/crypto/src/x509/X509V1CertificateGenerator.cs
index 93ec03ea3..2fc53ec7c 100644
--- a/crypto/src/x509/X509V1CertificateGenerator.cs
+++ b/crypto/src/x509/X509V1CertificateGenerator.cs
@@ -122,26 +122,16 @@ namespace Org.BouncyCastle.X509
tbsGen.SetSignature(sigAlgID);
- TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate();
+ var tbsCertificate = tbsGen.GenerateTbsCertificate();
- IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator();
- using (var sigStream = streamCalculator.Stream)
- {
- tbsCert.EncodeTo(sigStream, Asn1Encodable.Der);
- }
-
- var signature = streamCalculator.GetResult().Collect();
+ var signature = X509Utilities.GenerateSignature(signatureFactory, tbsCertificate);
- return new X509Certificate(
- new X509CertificateStructure(tbsCert, sigAlgID, new DerBitString(signature)));
+ return new X509Certificate(new X509CertificateStructure(tbsCertificate, sigAlgID, signature));
}
/// <summary>
/// Allows enumeration of the signature names supported by the generator.
/// </summary>
- public IEnumerable<string> SignatureAlgNames
- {
- get { return X509Utilities.GetAlgNames(); }
- }
+ public IEnumerable<string> SignatureAlgNames => X509Utilities.GetAlgNames();
}
}
diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs
index 65e3c9177..1dd1776be 100644
--- a/crypto/src/x509/X509V3CertificateGenerator.cs
+++ b/crypto/src/x509/X509V3CertificateGenerator.cs
@@ -143,7 +143,7 @@ namespace Org.BouncyCastle.X509
public void SetSubjectUniqueID(
bool[] uniqueID)
{
- tbsGen.SetSubjectUniqueID(booleanToBitString(uniqueID));
+ tbsGen.SetSubjectUniqueID(BooleanToBitString(uniqueID));
}
/// <summary>
@@ -153,30 +153,7 @@ namespace Org.BouncyCastle.X509
public void SetIssuerUniqueID(
bool[] uniqueID)
{
- tbsGen.SetIssuerUniqueID(booleanToBitString(uniqueID));
- }
-
- private DerBitString booleanToBitString(
- bool[] id)
- {
- byte[] bytes = new byte[(id.Length + 7) / 8];
-
- for (int i = 0; i != id.Length; i++)
- {
- if (id[i])
- {
- bytes[i / 8] |= (byte)(1 << ((7 - (i % 8))));
- }
- }
-
- int pad = id.Length % 8;
-
- if (pad == 0)
- {
- return new DerBitString(bytes);
- }
-
- return new DerBitString(bytes, 8 - pad);
+ tbsGen.SetIssuerUniqueID(BooleanToBitString(uniqueID));
}
/// <summary>
@@ -327,9 +304,29 @@ namespace Org.BouncyCastle.X509
/// <summary>
/// Allows enumeration of the signature names supported by the generator.
/// </summary>
- public IEnumerable<string> SignatureAlgNames
- {
- get { return X509Utilities.GetAlgNames(); }
- }
- }
+ public IEnumerable<string> SignatureAlgNames => X509Utilities.GetAlgNames();
+
+ private static DerBitString BooleanToBitString(bool[] id)
+ {
+ int byteLength = (id.Length + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> bytes = byteLength <= 512
+ ? stackalloc byte[byteLength]
+ : new byte[byteLength];
+#else
+ byte[] bytes = new byte[byteLength];
+#endif
+
+ for (int i = 0; i != id.Length; i++)
+ {
+ if (id[i])
+ {
+ bytes[i >> 3] |= (byte)(0x80 >> (i & 7));
+ }
+ }
+
+ return new DerBitString(bytes, (8 - id.Length) & 7);
+ }
+ }
}
|