diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
index 33b661761..48abfbfa2 100644
--- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
@@ -102,18 +102,18 @@ namespace Org.BouncyCastle.Cms
if (_sAttr != null)
{
- _sig = Helper.GetSignatureInstance(signatureName);
- }
- else
+ _sig = SignerUtilities.InitSigner(signatureName, true, key, outer.m_random);
+ }
+ else
{
// Note: Need to use raw signatures here since we have already calculated the digest
if (_encName.Equals("RSA"))
{
- _sig = Helper.GetSignatureInstance("RSA");
- }
- else if (_encName.Equals("DSA"))
+ _sig = SignerUtilities.InitSigner("RSA", true, key, outer.m_random);
+ }
+ else if (_encName.Equals("DSA"))
{
- _sig = Helper.GetSignatureInstance("NONEwithDSA");
+ _sig = SignerUtilities.InitSigner("NONEwithDSA", true, key, outer.m_random);
}
// TODO Add support for raw PSS
// else if (_encName.equals("RSAandMGF1"))
@@ -135,10 +135,8 @@ namespace Org.BouncyCastle.Cms
{
throw new SignatureException("algorithm: " + _encName + " not supported in base signatures.");
}
- }
-
- _sig.Init(true, new ParametersWithRandom(key, outer.m_random));
- }
+ }
+ }
public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm,
byte[] calculatedDigest)
diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs
index ea8d28771..acbeb12e8 100644
--- a/crypto/src/crypto/operators/Asn1Signature.cs
+++ b/crypto/src/crypto/operators/Asn1Signature.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
+using Org.BouncyCastle.Asn1.EdEC;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
@@ -97,6 +98,9 @@ namespace Org.BouncyCastle.Crypto.Operators
m_algorithms.Add("GOST3411-2012-256WITHECGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256);
m_algorithms.Add("GOST3411-2012-512WITHECGOST3410", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
m_algorithms.Add("GOST3411-2012-512WITHECGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512);
+ m_algorithms.Add("Ed25519", EdECObjectIdentifiers.id_Ed25519);
+ m_algorithms.Add("Ed448", EdECObjectIdentifiers.id_Ed448);
+ // TODO Ed25519ctx, Ed25519ph, Ed448ph
//
// According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
diff --git a/crypto/src/ocsp/OCSPReqGenerator.cs b/crypto/src/ocsp/OCSPReqGenerator.cs
index dda1625e5..9a5d72ae8 100644
--- a/crypto/src/ocsp/OCSPReqGenerator.cs
+++ b/crypto/src/ocsp/OCSPReqGenerator.cs
@@ -6,6 +6,7 @@ using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Security.Certificates;
@@ -93,13 +94,10 @@ namespace Org.BouncyCastle.Ocsp
this.requestExtensions = requestExtensions;
}
- private OcspReq GenerateRequest(
- DerObjectIdentifier signingAlgorithm,
- AsymmetricKeyParameter privateKey,
- X509Certificate[] chain,
- SecureRandom random)
+ private OcspReq GenerateRequest(DerObjectIdentifier signingAlgorithm, AsymmetricKeyParameter privateKey,
+ X509Certificate[] chain, SecureRandom random)
{
- Asn1EncodableVector requests = new Asn1EncodableVector();
+ Asn1EncodableVector requests = new Asn1EncodableVector(list.Count);
foreach (RequestObject reqObj in list)
{
@@ -114,42 +112,29 @@ namespace Org.BouncyCastle.Ocsp
}
TbsRequest tbsReq = new TbsRequest(requestorName, new DerSequence(requests), requestExtensions);
-
- ISigner sig = null;
Signature signature = null;
if (signingAlgorithm != null)
{
if (requestorName == null)
- {
throw new OcspException("requestorName must be specified if request is signed.");
- }
- try
- {
- sig = SignerUtilities.GetSigner(signingAlgorithm.Id);
- if (random != null)
- {
- sig.Init(true, new ParametersWithRandom(privateKey, random));
- }
- else
- {
- sig.Init(true, privateKey);
- }
+ ISigner signer;
+ try
+ {
+ signer = SignerUtilities.InitSigner(signingAlgorithm, true, privateKey, random);
}
catch (Exception e)
{
throw new OcspException("exception creating signature: " + e, e);
}
- DerBitString bitSig = null;
-
+ DerBitString bitSig;
try
{
- byte[] encoded = tbsReq.GetEncoded();
- sig.BlockUpdate(encoded, 0, encoded.Length);
+ tbsReq.EncodeTo(new SignerSink(signer), Asn1Encodable.Der);
- bitSig = new DerBitString(sig.GenerateSignature());
+ bitSig = new DerBitString(signer.GenerateSignature());
}
catch (Exception e)
{
@@ -158,9 +143,10 @@ namespace Org.BouncyCastle.Ocsp
AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, DerNull.Instance);
- if (chain != null && chain.Length > 0)
+ Asn1Sequence certs = null;
+ if (!Arrays.IsNullOrEmpty(chain))
{
- Asn1EncodableVector v = new Asn1EncodableVector();
+ Asn1EncodableVector v = new Asn1EncodableVector(chain.Length);
try
{
for (int i = 0; i != chain.Length; i++)
@@ -177,15 +163,13 @@ namespace Org.BouncyCastle.Ocsp
throw new OcspException("error encoding certs", e);
}
- signature = new Signature(sigAlgId, bitSig, new DerSequence(v));
+ certs = new DerSequence(v);
}
- else
- {
- signature = new Signature(sigAlgId, bitSig);
- }
- }
- return new OcspReq(new OcspRequest(tbsReq, signature));
+ signature = new Signature(sigAlgId, bitSig, certs);
+ }
+
+ return new OcspReq(new OcspRequest(tbsReq, signature));
}
/**
diff --git a/crypto/src/openpgp/PgpSignatureGenerator.cs b/crypto/src/openpgp/PgpSignatureGenerator.cs
index 12edf9f89..64d256653 100644
--- a/crypto/src/openpgp/PgpSignatureGenerator.cs
+++ b/crypto/src/openpgp/PgpSignatureGenerator.cs
@@ -40,36 +40,34 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
}
/// <summary>Initialise the generator for signing.</summary>
- public void InitSign(
- int sigType,
- PgpPrivateKey privKey)
+ public void InitSign(int sigType, PgpPrivateKey privKey)
{
InitSign(sigType, privKey, null);
}
/// <summary>Initialise the generator for signing.</summary>
- public void InitSign(
- int sigType,
- PgpPrivateKey privKey,
- SecureRandom random)
+ public void InitSign(int sigType, PgpPrivateKey privKey, SecureRandom random)
{
this.privKey = privKey;
this.signatureType = sigType;
AsymmetricKeyParameter key = privKey.Key;
- if (sig == null)
- {
- this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key);
- }
+ this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key);
try
{
ICipherParameters cp = key;
- if (random != null)
+
+ // TODO Ask SignerUtilities whether random is permitted?
+ if (keyAlgorithm == PublicKeyAlgorithmTag.EdDsa)
{
- cp = new ParametersWithRandom(cp, random);
+ // EdDSA signers don't expect a SecureRandom
}
+ else
+ {
+ cp = ParameterUtilities.WithRandom(cp, random);
+ }
sig.Init(true, cp);
}
diff --git a/crypto/src/openpgp/PgpV3SignatureGenerator.cs b/crypto/src/openpgp/PgpV3SignatureGenerator.cs
index 324dbd768..03dd8795d 100644
--- a/crypto/src/openpgp/PgpV3SignatureGenerator.cs
+++ b/crypto/src/openpgp/PgpV3SignatureGenerator.cs
@@ -47,20 +47,23 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
AsymmetricKeyParameter key = privKey.Key;
- if (sig == null)
- {
- this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key);
- }
+ this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key);
try
{
- ICipherParameters cp = key;
- if (random != null)
- {
- cp = new ParametersWithRandom(cp, random);
- }
+ ICipherParameters cp = key;
+
+ // TODO Ask SignerUtilities whether random is permitted?
+ if (keyAlgorithm == PublicKeyAlgorithmTag.EdDsa)
+ {
+ // EdDSA signers don't expect a SecureRandom
+ }
+ else
+ {
+ cp = ParameterUtilities.WithRandom(cp, random);
+ }
- sig.Init(true, cp);
+ sig.Init(true, cp);
}
catch (InvalidKeyException e)
{
diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs
index 6500cdf13..917759a8e 100644
--- a/crypto/src/security/SignerUtilities.cs
+++ b/crypto/src/security/SignerUtilities.cs
@@ -10,16 +10,16 @@ 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;
-using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
-using Org.BouncyCastle.Asn1.Rosstandart;
namespace Org.BouncyCastle.Security
{
@@ -28,9 +28,10 @@ namespace Org.BouncyCastle.Security
/// </summary>
public static class SignerUtilities
{
- internal static readonly IDictionary<string, string> AlgorithmMap =
+ private static readonly IDictionary<string, string> AlgorithmMap =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- internal static readonly IDictionary<string, DerObjectIdentifier> Oids =
+ private static readonly HashSet<string> NoRandom = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+ private static readonly IDictionary<string, DerObjectIdentifier> Oids =
new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase);
static SignerUtilities()
@@ -408,6 +409,14 @@ namespace Org.BouncyCastle.Security
AlgorithmMap["SM3WITHSM2"] = "SM3withSM2";
AlgorithmMap[GMObjectIdentifiers.sm2sign_with_sm3.Id] = "SM3withSM2";
+ NoRandom.Add("Ed25519");
+ NoRandom.Add(EdECObjectIdentifiers.id_Ed25519.Id);
+ NoRandom.Add("Ed25519ctx");
+ NoRandom.Add("Ed25519ph");
+ NoRandom.Add("Ed448");
+ NoRandom.Add(EdECObjectIdentifiers.id_Ed448.Id);
+ NoRandom.Add("Ed448ph");
+
Oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
Oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption;
Oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
@@ -519,6 +528,11 @@ namespace Org.BouncyCastle.Security
return DerNull.Instance;
}
+ private static string GetMechanism(string algorithm)
+ {
+ return AlgorithmMap.TryGetValue(algorithm, out var v) ? v : algorithm.ToUpperInvariant();
+ }
+
private static Asn1Encodable GetPssX509Parameters(
string digestName)
{
@@ -536,6 +550,9 @@ namespace Org.BouncyCastle.Security
public static ISigner GetSigner(DerObjectIdentifier id)
{
+ if (id == null)
+ throw new ArgumentNullException(nameof(id));
+
return GetSigner(id.Id);
}
@@ -544,8 +561,17 @@ namespace Org.BouncyCastle.Security
if (algorithm == null)
throw new ArgumentNullException(nameof(algorithm));
- string mechanism = CollectionUtilities.GetValueOrKey(AlgorithmMap, algorithm.ToUpperInvariant());
+ string mechanism = GetMechanism(algorithm);
+
+ var signer = GetSignerForMechanism(mechanism);
+ if (signer == null)
+ throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
+
+ return signer;
+ }
+ private static ISigner GetSignerForMechanism(string mechanism)
+ {
if (Platform.StartsWith(mechanism, "Ed"))
{
if (mechanism.Equals("Ed25519"))
@@ -638,30 +664,37 @@ namespace Org.BouncyCastle.Security
{
return new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest());
}
- if (mechanism.Equals("ECGOST3410"))
- {
- return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest());
- }
- if (mechanism.Equals("ECGOST3410-2012-256"))
- {
- return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_256Digest());
- }
- if (mechanism.Equals("ECGOST3410-2012-512"))
- {
- return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_512Digest());
- }
- if (mechanism.Equals("SHA1WITHRSA/ISO9796-2"))
- {
- return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true);
- }
- if (mechanism.Equals("MD5WITHRSA/ISO9796-2"))
+ if (Platform.StartsWith(mechanism, "ECGOST3410"))
{
- return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true);
+ if (mechanism.Equals("ECGOST3410"))
+ {
+ return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest());
+ }
+ if (mechanism.Equals("ECGOST3410-2012-256"))
+ {
+ return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_256Digest());
+ }
+ if (mechanism.Equals("ECGOST3410-2012-512"))
+ {
+ return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_512Digest());
+ }
}
- if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2"))
+
+ if (Platform.EndsWith(mechanism, "/ISO9796-2"))
{
- return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true);
+ if (mechanism.Equals("SHA1WITHRSA/ISO9796-2"))
+ {
+ return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true);
+ }
+ if (mechanism.Equals("MD5WITHRSA/ISO9796-2"))
+ {
+ return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true);
+ }
+ if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2"))
+ {
+ return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true);
+ }
}
if (Platform.EndsWith(mechanism, "/X9.31"))
@@ -672,19 +705,20 @@ namespace Org.BouncyCastle.Security
{
int endPos = withPos + "WITH".Length;
- string digestName = x931.Substring(0, withPos);
- IDigest digest = DigestUtilities.GetDigest(digestName);
-
string cipherName = x931.Substring(endPos, x931.Length - endPos);
if (cipherName.Equals("RSA"))
{
IAsymmetricBlockCipher cipher = new RsaBlindedEngine();
+
+ string digestName = x931.Substring(0, withPos);
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+
return new X931Signer(cipher, digest);
}
}
}
- throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
+ return null;
}
public static string GetEncodingName(DerObjectIdentifier oid)
@@ -692,15 +726,36 @@ namespace Org.BouncyCastle.Security
return CollectionUtilities.GetValueOrNull(AlgorithmMap, oid.Id);
}
- public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random)
+ // TODO Rename 'privateKey' to 'key'
+ public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning,
+ AsymmetricKeyParameter privateKey, SecureRandom random)
{
+ if (algorithmOid == null)
+ throw new ArgumentNullException(nameof(algorithmOid));
+
return InitSigner(algorithmOid.Id, forSigning, privateKey, random);
}
- public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random)
+ // TODO Rename 'privateKey' to 'key'
+ public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey,
+ SecureRandom random)
{
- ISigner signer = GetSigner(algorithm);
- signer.Init(forSigning, ParameterUtilities.WithRandom(privateKey, random));
+ if (algorithm == null)
+ throw new ArgumentNullException(nameof(algorithm));
+
+ string mechanism = GetMechanism(algorithm);
+
+ var signer = GetSignerForMechanism(mechanism);
+ if (signer == null)
+ throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
+
+ ICipherParameters cipherParameters = privateKey;
+ if (forSigning && !NoRandom.Contains(mechanism))
+ {
+ cipherParameters = ParameterUtilities.WithRandom(cipherParameters, random);
+ }
+
+ signer.Init(forSigning, cipherParameters);
return signer;
}
}
|