diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index c6dd131e7..bada122a3 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -569,6 +569,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\asn1\bsi\BsiObjectIdentifiers.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\asn1\cmp\CAKeyUpdAnnContent.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -3099,6 +3104,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\crypto\IDsaExt.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\crypto\IEntropySource.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -4784,6 +4794,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\crypto\signers\IDsaEncoding.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\crypto\signers\IDsaKCalculator.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -4804,6 +4819,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\crypto\signers\PlainDsaEncoding.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\crypto\signers\PSSSigner.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -4824,6 +4844,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\crypto\signers\StandardDsaEncoding.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\crypto\signers\X931Signer.cs"
SubType = "Code"
BuildAction = "Compile"
diff --git a/crypto/src/asn1/bsi/BsiObjectIdentifiers.cs b/crypto/src/asn1/bsi/BsiObjectIdentifiers.cs
new file mode 100644
index 000000000..95a0d7b52
--- /dev/null
+++ b/crypto/src/asn1/bsi/BsiObjectIdentifiers.cs
@@ -0,0 +1,103 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Bsi
+{
+ /// <remarks>See https://www.bsi.bund.de/cae/servlet/contentblob/471398/publicationFile/30615/BSI-TR-03111_pdf.pdf</remarks>
+ public abstract class BsiObjectIdentifiers
+ {
+ public static readonly DerObjectIdentifier bsi_de = new DerObjectIdentifier("0.4.0.127.0.7");
+
+ /* 0.4.0.127.0.7.1.1 */
+ public static readonly DerObjectIdentifier id_ecc = bsi_de.Branch("1.1");
+
+ /* 0.4.0.127.0.7.1.1.4.1 */
+ public static readonly DerObjectIdentifier ecdsa_plain_signatures = id_ecc.Branch("4.1");
+
+ /* 0.4.0.127.0.7.1.1.4.1.1 */
+ public static readonly DerObjectIdentifier ecdsa_plain_SHA1 = ecdsa_plain_signatures.Branch("1");
+
+ /* 0.4.0.127.0.7.1.1.4.1.2 */
+ public static readonly DerObjectIdentifier ecdsa_plain_SHA224 = ecdsa_plain_signatures.Branch("2");
+
+ /* 0.4.0.127.0.7.1.1.4.1.3 */
+ public static readonly DerObjectIdentifier ecdsa_plain_SHA256 = ecdsa_plain_signatures.Branch("3");
+
+ /* 0.4.0.127.0.7.1.1.4.1.4 */
+ public static readonly DerObjectIdentifier ecdsa_plain_SHA384 = ecdsa_plain_signatures.Branch("4");
+
+ /* 0.4.0.127.0.7.1.1.4.1.5 */
+ public static readonly DerObjectIdentifier ecdsa_plain_SHA512 = ecdsa_plain_signatures.Branch("5");
+
+ /* 0.4.0.127.0.7.1.1.4.1.6 */
+ public static readonly DerObjectIdentifier ecdsa_plain_RIPEMD160 = ecdsa_plain_signatures.Branch("6");
+
+ /** 0.4.0.127.0.7.1 */
+ public static readonly DerObjectIdentifier algorithm = bsi_de.Branch("1");
+
+ public static readonly DerObjectIdentifier ecka_eg = id_ecc.Branch("5.1");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 OID: 0.4.0.127.0.7.1.1.5.1.1 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf = ecka_eg.Branch("1");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963
+ * with hash function SHA-1
+ * OID: 0.4.0.127.0.7.1.1.5.1.1.1 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA1 = ecka_eg_X963kdf.Branch("1");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963
+ * with hash function SHA224
+ * OID: 0.4.0.127.0.7.1.1.5.1.1.2 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA224 = ecka_eg_X963kdf.Branch("2");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963
+ * with hash function SHA256
+ * OID: 0.4.0.127.0.7.1.1.5.1.1.3 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA256 = ecka_eg_X963kdf.Branch("3");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963
+ * with hash function SHA384
+ * OID: 0.4.0.127.0.7.1.1.5.1.1.4 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA384 = ecka_eg_X963kdf.Branch("4");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963
+ * with hash function SHA512
+ * OID: 0.4.0.127.0.7.1.1.5.1.1.5 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA512 = ecka_eg_X963kdf.Branch("5");
+
+ /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963
+ * with hash function RIPEMD160
+ * OID: 0.4.0.127.0.7.1.1.5.1.1.6 */
+ public static readonly DerObjectIdentifier ecka_eg_X963kdf_RIPEMD160 = ecka_eg_X963kdf.Branch("6");
+
+ /**
+ * Key Derivation Function for Session Keys
+ */
+ public static readonly DerObjectIdentifier ecka_eg_SessionKDF = ecka_eg.Branch("2");
+
+ public static readonly DerObjectIdentifier ecka_eg_SessionKDF_3DES = ecka_eg_SessionKDF.Branch("1");
+ public static readonly DerObjectIdentifier ecka_eg_SessionKDF_AES128 = ecka_eg_SessionKDF.Branch("2");
+ public static readonly DerObjectIdentifier ecka_eg_SessionKDF_AES192 = ecka_eg_SessionKDF.Branch("3");
+ public static readonly DerObjectIdentifier ecka_eg_SessionKDF_AES256 = ecka_eg_SessionKDF.Branch("4");
+
+ /** AES encryption (CBC) and authentication (CMAC)
+ * OID: 0.4.0.127.0.7.1.x */
+ //TODO: replace "1" with correct OID
+ //public static readonly DerObjectIdentifier aes_cbc_cmac = algorithm.Branch("1");
+
+ /** AES encryption (CBC) and authentication (CMAC) with 128 bit
+ * OID: 0.4.0.127.0.7.1.x.y1 */
+ //TODO: replace "1" with correct OID
+ //public static readonly DerObjectIdentifier id_aes128_CBC_CMAC = aes_cbc_cmac.Branch("1");
+
+
+ /** AES encryption (CBC) and authentication (CMAC) with 192 bit
+ * OID: 0.4.0.127.0.7.1.x.y2 */
+ //TODO: replace "1" with correct OID
+ //public static readonly DerObjectIdentifier id_aes192_CBC_CMAC = aes_cbc_cmac.Branch("1");
+
+ /** AES encryption (CBC) and authentication (CMAC) with 256 bit
+ * OID: 0.4.0.127.0.7.1.x.y3 */
+ //TODO: replace "1" with correct OID
+ //public static readonly DerObjectIdentifier id_aes256_CBC_CMAC = aes_cbc_cmac.Branch("1");
+ }
+}
diff --git a/crypto/src/crypto/IDSA.cs b/crypto/src/crypto/IDSA.cs
index 46056d8ca..7d1fd5197 100644
--- a/crypto/src/crypto/IDSA.cs
+++ b/crypto/src/crypto/IDSA.cs
@@ -1,4 +1,5 @@
using System;
+
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto
diff --git a/crypto/src/crypto/IDsaExt.cs b/crypto/src/crypto/IDsaExt.cs
new file mode 100644
index 000000000..15b55787a
--- /dev/null
+++ b/crypto/src/crypto/IDsaExt.cs
@@ -0,0 +1,17 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto
+{
+ /// <summary>
+ /// An "extended" interface for classes implementing DSA-style algorithms, that provides access
+ /// to the group order.
+ /// </summary>
+ public interface IDsaExt
+ : IDsa
+ {
+ /// <summary>The order of the group that the r, s values in signatures belong to.</summary>
+ BigInteger Order { get; }
+ }
+}
diff --git a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs
index 97902e093..8046a0b1b 100644
--- a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
public Ed25519PrivateKeyParameters(SecureRandom random)
: base(true)
{
- random.NextBytes(data);
+ Ed25519.GeneratePrivateKey(random, data);
}
public Ed25519PrivateKeyParameters(byte[] buf, int off)
diff --git a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs
index 74b5d63f3..f2fc4d533 100644
--- a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
public Ed448PrivateKeyParameters(SecureRandom random)
: base(true)
{
- random.NextBytes(data);
+ Ed448.GeneratePrivateKey(random, data);
}
public Ed448PrivateKeyParameters(byte[] buf, int off)
diff --git a/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs b/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs
index 09972c7a2..d0bcffa94 100644
--- a/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs
+++ b/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs
@@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
: KeyGenerationParameters
{
public X25519KeyGenerationParameters(SecureRandom random)
- : base(random, 256)
+ : base(random, 255)
{
}
}
diff --git a/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs
index fb49a02b3..f7bbdac74 100644
--- a/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
public X25519PrivateKeyParameters(SecureRandom random)
: base(true)
{
- random.NextBytes(data);
+ X25519.GeneratePrivateKey(random, data);
}
public X25519PrivateKeyParameters(byte[] buf, int off)
diff --git a/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs
index d17aa7947..a073e5799 100644
--- a/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
public X448PrivateKeyParameters(SecureRandom random)
: base(true)
{
- random.NextBytes(data);
+ X448.GeneratePrivateKey(random, data);
}
public X448PrivateKeyParameters(byte[] buf, int off)
diff --git a/crypto/src/crypto/signers/DsaDigestSigner.cs b/crypto/src/crypto/signers/DsaDigestSigner.cs
index 086601481..7fd8f535f 100644
--- a/crypto/src/crypto/signers/DsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/DsaDigestSigner.cs
@@ -1,10 +1,5 @@
using System;
-using System.Collections;
-using System.IO;
-using System.Text;
-using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
@@ -14,26 +9,38 @@ namespace Org.BouncyCastle.Crypto.Signers
public class DsaDigestSigner
: ISigner
{
- private readonly IDigest digest;
- private readonly IDsa dsaSigner;
- private bool forSigning;
+ private readonly IDsa dsa;
+ private readonly IDigest digest;
+ private readonly IDsaEncoding encoding;
+ private bool forSigning;
public DsaDigestSigner(
- IDsa signer,
+ IDsa dsa,
IDigest digest)
{
- this.digest = digest;
- this.dsaSigner = signer;
+ this.dsa = dsa;
+ this.digest = digest;
+ this.encoding = StandardDsaEncoding.Instance;
}
+ public DsaDigestSigner(
+ IDsaExt dsa,
+ IDigest digest,
+ IDsaEncoding encoding)
+ {
+ this.dsa = dsa;
+ this.digest = digest;
+ this.encoding = encoding;
+ }
+
public virtual string AlgorithmName
{
- get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
+ get { return digest.AlgorithmName + "with" + dsa.AlgorithmName; }
}
public virtual void Init(
- bool forSigning,
- ICipherParameters parameters)
+ bool forSigning,
+ ICipherParameters parameters)
{
this.forSigning = forSigning;
@@ -56,7 +63,7 @@ namespace Org.BouncyCastle.Crypto.Signers
Reset();
- dsaSigner.Init(forSigning, parameters);
+ dsa.Init(forSigning, parameters);
}
/**
@@ -91,9 +98,16 @@ namespace Org.BouncyCastle.Crypto.Signers
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
- BigInteger[] sig = dsaSigner.GenerateSignature(hash);
+ BigInteger[] sig = dsa.GenerateSignature(hash);
- return DerEncode(sig[0], sig[1]);
+ try
+ {
+ return encoding.Encode(GetOrder(), sig[0], sig[1]);
+ }
+ catch (Exception)
+ {
+ throw new InvalidOperationException("unable to encode signature");
+ }
}
/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
@@ -106,15 +120,16 @@ namespace Org.BouncyCastle.Crypto.Signers
byte[] hash = new byte[digest.GetDigestSize()];
digest.DoFinal(hash, 0);
- try
- {
- BigInteger[] sig = DerDecode(signature);
- return dsaSigner.VerifySignature(hash, sig[0], sig[1]);
- }
- catch (IOException)
- {
- return false;
- }
+ try
+ {
+ BigInteger[] sig = encoding.Decode(GetOrder(), signature);
+
+ return dsa.VerifySignature(hash, sig[0], sig[1]);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
}
/// <summary>Reset the internal state</summary>
@@ -123,23 +138,9 @@ namespace Org.BouncyCastle.Crypto.Signers
digest.Reset();
}
- private byte[] DerEncode(
- BigInteger r,
- BigInteger s)
- {
- return new DerSequence(new DerInteger(r), new DerInteger(s)).GetDerEncoded();
- }
-
- private BigInteger[] DerDecode(
- byte[] encoding)
- {
- Asn1Sequence s = (Asn1Sequence) Asn1Object.FromByteArray(encoding);
-
- return new BigInteger[]
- {
- ((DerInteger) s[0]).Value,
- ((DerInteger) s[1]).Value
- };
- }
+ protected virtual BigInteger GetOrder()
+ {
+ return dsa is IDsaExt ? ((IDsaExt)dsa).Order : null;
+ }
}
}
diff --git a/crypto/src/crypto/signers/DsaSigner.cs b/crypto/src/crypto/signers/DsaSigner.cs
index bb28addfc..32a33d084 100644
--- a/crypto/src/crypto/signers/DsaSigner.cs
+++ b/crypto/src/crypto/signers/DsaSigner.cs
@@ -12,7 +12,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Cryptography", pages 452 - 453.
*/
public class DsaSigner
- : IDsa
+ : IDsaExt
{
protected readonly IDsaKCalculator kCalculator;
@@ -72,6 +72,11 @@ namespace Org.BouncyCastle.Crypto.Signers
this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom);
}
+ public virtual BigInteger Order
+ {
+ get { return key.Parameters.Q; }
+ }
+
/**
* Generate a signature for the given message using the key we were
* initialised with. For conventional DSA the message should be a SHA-1
diff --git a/crypto/src/crypto/signers/ECDsaSigner.cs b/crypto/src/crypto/signers/ECDsaSigner.cs
index 520507b8c..7b04d1076 100644
--- a/crypto/src/crypto/signers/ECDsaSigner.cs
+++ b/crypto/src/crypto/signers/ECDsaSigner.cs
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* EC-DSA as described in X9.62
*/
public class ECDsaSigner
- : IDsa
+ : IDsaExt
{
private static readonly BigInteger Eight = BigInteger.ValueOf(8);
@@ -75,6 +75,11 @@ namespace Org.BouncyCastle.Crypto.Signers
this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom);
}
+ public virtual BigInteger Order
+ {
+ get { return key.Parameters.N; }
+ }
+
// 5.3 pg 28
/**
* Generate a signature for the given message using the key we were
diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs
index 28ab79c1c..451cd3dd8 100644
--- a/crypto/src/crypto/signers/ECGOST3410Signer.cs
+++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* GOST R 34.10-2001 Signature Algorithm
*/
public class ECGost3410Signer
- : IDsa
+ : IDsaExt
{
private ECKeyParameters key;
private SecureRandom random;
@@ -55,6 +55,11 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
+ public virtual BigInteger Order
+ {
+ get { return key.Parameters.N; }
+ }
+
/**
* generate a signature for the given message using the key we were
* initialised with. For conventional GOST3410 the message should be a GOST3411
diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs
index bb21a4994..bc193e797 100644
--- a/crypto/src/crypto/signers/ECNRSigner.cs
+++ b/crypto/src/crypto/signers/ECNRSigner.cs
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* EC-NR as described in IEEE 1363-2000
*/
public class ECNRSigner
- : IDsa
+ : IDsaExt
{
private bool forSigning;
private ECKeyParameters key;
@@ -58,6 +58,11 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
+ public virtual BigInteger Order
+ {
+ get { return key.Parameters.N; }
+ }
+
// Section 7.2.5 ECSP-NR, pg 34
/**
* generate a signature for the given message using the key we were
@@ -77,7 +82,7 @@ namespace Org.BouncyCastle.Crypto.Signers
throw new InvalidOperationException("not initialised for signing");
}
- BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N;
+ BigInteger n = Order;
int nBitLength = n.BitLength;
BigInteger e = new BigInteger(1, message);
diff --git a/crypto/src/crypto/signers/GOST3410Signer.cs b/crypto/src/crypto/signers/GOST3410Signer.cs
index f1832ae37..c5f3bd5ef 100644
--- a/crypto/src/crypto/signers/GOST3410Signer.cs
+++ b/crypto/src/crypto/signers/GOST3410Signer.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Signers
* Gost R 34.10-94 Signature Algorithm
*/
public class Gost3410Signer
- : IDsa
+ : IDsaExt
{
private Gost3410KeyParameters key;
private SecureRandom random;
@@ -52,6 +52,11 @@ namespace Org.BouncyCastle.Crypto.Signers
}
}
+ public virtual BigInteger Order
+ {
+ get { return key.Parameters.Q; }
+ }
+
/**
* generate a signature for the given message using the key we were
* initialised with. For conventional Gost3410 the message should be a Gost3411
diff --git a/crypto/src/crypto/signers/HMacDsaKCalculator.cs b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
index 8231197b9..05c4ae5c2 100644
--- a/crypto/src/crypto/signers/HMacDsaKCalculator.cs
+++ b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
@@ -49,12 +49,13 @@ namespace Org.BouncyCastle.Crypto.Signers
Arrays.Fill(V, (byte)0x01);
Arrays.Fill(K, (byte)0);
- byte[] x = new byte[(n.BitLength + 7) / 8];
+ int size = BigIntegers.GetUnsignedByteLength(n);
+ byte[] x = new byte[size];
byte[] dVal = BigIntegers.AsUnsignedByteArray(d);
Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length);
- byte[] m = new byte[(n.BitLength + 7) / 8];
+ byte[] m = new byte[size];
BigInteger mInt = BitsToInt(message);
@@ -98,7 +99,7 @@ namespace Org.BouncyCastle.Crypto.Signers
public virtual BigInteger NextK()
{
- byte[] t = new byte[((n.BitLength + 7) / 8)];
+ byte[] t = new byte[BigIntegers.GetUnsignedByteLength(n)];
for (;;)
{
diff --git a/crypto/src/crypto/signers/IDsaEncoding.cs b/crypto/src/crypto/signers/IDsaEncoding.cs
new file mode 100644
index 000000000..cccc4f937
--- /dev/null
+++ b/crypto/src/crypto/signers/IDsaEncoding.cs
@@ -0,0 +1,25 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Signers
+{
+ /// <summary>
+ /// An interface for different encoding formats for DSA signatures.
+ /// </summary>
+ public interface IDsaEncoding
+ {
+ /// <summary>Decode the (r, s) pair of a DSA signature.</summary>
+ /// <param name="n">The order of the group that r, s belong to.</param>
+ /// <param name="encoding">An encoding of the (r, s) pair of a DSA signature.</param>
+ /// <returns>The (r, s) of a DSA signature, stored in an array of exactly two elements, r followed by s.</returns>
+ BigInteger[] Decode(BigInteger n, byte[] encoding);
+
+ /// <summary>Encode the (r, s) pair of a DSA signature.</summary>
+ /// <param name="n">The order of the group that r, s belong to.</param>
+ /// <param name="r">The r value of a DSA signature.</param>
+ /// <param name="s">The s value of a DSA signature.</param>
+ /// <returns>An encoding of the DSA signature given by the provided (r, s) pair.</returns>
+ byte[] Encode(BigInteger n, BigInteger r, BigInteger s);
+ }
+}
diff --git a/crypto/src/crypto/signers/PlainDsaEncoding.cs b/crypto/src/crypto/signers/PlainDsaEncoding.cs
new file mode 100644
index 000000000..2e1f65a1f
--- /dev/null
+++ b/crypto/src/crypto/signers/PlainDsaEncoding.cs
@@ -0,0 +1,58 @@
+using System;
+
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Signers
+{
+ public class PlainDsaEncoding
+ : IDsaEncoding
+ {
+ public static readonly PlainDsaEncoding Instance = new PlainDsaEncoding();
+
+ public virtual BigInteger[] Decode(BigInteger n, byte[] encoding)
+ {
+ int valueLength = BigIntegers.GetUnsignedByteLength(n);
+ if (encoding.Length != valueLength * 2)
+ throw new ArgumentException("Encoding has incorrect length", "encoding");
+
+ return new BigInteger[] {
+ DecodeValue(n, encoding, 0, valueLength),
+ DecodeValue(n, encoding, valueLength, valueLength),
+ };
+ }
+
+ public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s)
+ {
+ int valueLength = BigIntegers.GetUnsignedByteLength(n);
+ byte[] result = new byte[valueLength * 2];
+ EncodeValue(n, r, result, 0, valueLength);
+ EncodeValue(n, s, result, valueLength, valueLength);
+ return result;
+ }
+
+ protected virtual BigInteger CheckValue(BigInteger n, BigInteger x)
+ {
+ if (x.SignValue < 0 || x.CompareTo(n) >= 0)
+ throw new ArgumentException("Value out of range", "x");
+
+ return x;
+ }
+
+ protected virtual BigInteger DecodeValue(BigInteger n, byte[] buf, int off, int len)
+ {
+ return CheckValue(n, new BigInteger(1, buf, off, len));
+ }
+
+ protected virtual void EncodeValue(BigInteger n, BigInteger x, byte[] buf, int off, int len)
+ {
+ byte[] bs = CheckValue(n, x).ToByteArrayUnsigned();
+ int bsOff = System.Math.Max(0, bs.Length - len);
+ int bsLen = bs.Length - bsOff;
+
+ int pos = len - bsLen;
+ Arrays.Fill(buf, off, off + pos, 0);
+ Array.Copy(bs, bsOff, buf, off + pos, bsLen);
+ }
+ }
+}
diff --git a/crypto/src/crypto/signers/SM2Signer.cs b/crypto/src/crypto/signers/SM2Signer.cs
index 8151e6be0..d9ec20525 100644
--- a/crypto/src/crypto/signers/SM2Signer.cs
+++ b/crypto/src/crypto/signers/SM2Signer.cs
@@ -1,15 +1,11 @@
using System;
-using System.IO;
-using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Crypto.Signers
@@ -20,12 +16,23 @@ namespace Org.BouncyCastle.Crypto.Signers
{
private readonly IDsaKCalculator kCalculator = new RandomDsaKCalculator();
private readonly SM3Digest digest = new SM3Digest();
+ private readonly IDsaEncoding encoding;
private ECDomainParameters ecParams;
private ECPoint pubPoint;
private ECKeyParameters ecKey;
private byte[] z;
+ public SM2Signer()
+ {
+ this.encoding = StandardDsaEncoding.Instance;
+ }
+
+ public SM2Signer(IDsaEncoding encoding)
+ {
+ this.encoding = encoding;
+ }
+
public virtual string AlgorithmName
{
get { return "SM2Sign"; }
@@ -92,13 +99,11 @@ namespace Org.BouncyCastle.Crypto.Signers
{
try
{
- BigInteger[] rs = DerDecode(signature);
- if (rs != null)
- {
- return VerifySignature(rs[0], rs[1]);
- }
+ BigInteger[] rs = encoding.Decode(ecParams.N, signature);
+
+ return VerifySignature(rs[0], rs[1]);
}
- catch (IOException e)
+ catch (Exception)
{
}
@@ -154,9 +159,9 @@ namespace Org.BouncyCastle.Crypto.Signers
// A7
try
{
- return DerEncode(r, s);
+ return encoding.Encode(ecParams.N, r, s);
}
- catch (IOException ex)
+ catch (Exception ex)
{
throw new CryptoException("unable to encode signature: " + ex.Message, ex);
}
@@ -233,26 +238,5 @@ namespace Org.BouncyCastle.Crypto.Signers
{
return new FixedPointCombMultiplier();
}
-
- protected virtual BigInteger[] DerDecode(byte[] encoding)
- {
- Asn1Sequence seq = Asn1Sequence.GetInstance(Asn1Object.FromByteArray(encoding));
- if (seq.Count != 2)
- return null;
-
- BigInteger r = DerInteger.GetInstance(seq[0]).Value;
- BigInteger s = DerInteger.GetInstance(seq[1]).Value;
-
- byte[] expectedEncoding = DerEncode(r, s);
- if (!Arrays.ConstantTimeAreEqual(expectedEncoding, encoding))
- return null;
-
- return new BigInteger[]{ r, s };
- }
-
- protected virtual byte[] DerEncode(BigInteger r, BigInteger s)
- {
- return new DerSequence(new DerInteger(r), new DerInteger(s)).GetEncoded(Asn1Encodable.Der);
- }
}
}
diff --git a/crypto/src/crypto/signers/StandardDsaEncoding.cs b/crypto/src/crypto/signers/StandardDsaEncoding.cs
new file mode 100644
index 000000000..75ac08411
--- /dev/null
+++ b/crypto/src/crypto/signers/StandardDsaEncoding.cs
@@ -0,0 +1,56 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Signers
+{
+ public class StandardDsaEncoding
+ : IDsaEncoding
+ {
+ public static readonly StandardDsaEncoding Instance = new StandardDsaEncoding();
+
+ public virtual BigInteger[] Decode(BigInteger n, byte[] encoding)
+ {
+ Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(encoding);
+ if (seq.Count == 2)
+ {
+ BigInteger r = DecodeValue(n, seq, 0);
+ BigInteger s = DecodeValue(n, seq, 1);
+
+ byte[] expectedEncoding = Encode(n, r, s);
+ if (Arrays.AreEqual(expectedEncoding, encoding))
+ return new BigInteger[]{ r, s };
+ }
+
+ throw new ArgumentException("Malformed signature", "encoding");
+ }
+
+ public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s)
+ {
+ return new DerSequence(
+ EncodeValue(n, r),
+ EncodeValue(n, s)
+ ).GetEncoded(Asn1Encodable.Der);
+ }
+
+ protected virtual BigInteger CheckValue(BigInteger n, BigInteger x)
+ {
+ if (x.SignValue < 0 || (null != n && x.CompareTo(n) >= 0))
+ throw new ArgumentException("Value out of range", "x");
+
+ return x;
+ }
+
+ protected virtual BigInteger DecodeValue(BigInteger n, Asn1Sequence s, int pos)
+ {
+ return CheckValue(n, ((DerInteger)s[pos]).Value);
+ }
+
+ protected virtual DerInteger EncodeValue(BigInteger n, BigInteger x)
+ {
+ return new DerInteger(CheckValue(n, x));
+ }
+ }
+}
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
index c6e44bad8..6aeff87ad 100644
--- a/crypto/src/crypto/signers/X931Signer.cs
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -145,7 +145,8 @@ namespace Org.BouncyCastle.Crypto.Signers
t = t.Min(kParam.Modulus.Subtract(t));
- return BigIntegers.AsUnsignedByteArray((kParam.Modulus.BitLength + 7) / 8, t);
+ int size = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
+ return BigIntegers.AsUnsignedByteArray(size, t);
}
private void CreateSignatureBlock()
diff --git a/crypto/src/math/ec/rfc7748/X25519.cs b/crypto/src/math/ec/rfc7748/X25519.cs
index d8db2527a..8524b9e2c 100644
--- a/crypto/src/math/ec/rfc7748/X25519.cs
+++ b/crypto/src/math/ec/rfc7748/X25519.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
+using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Rfc7748
@@ -50,6 +51,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
n[7] |= 0x40000000U;
}
+ public static void GeneratePrivateKey(SecureRandom random, byte[] k)
+ {
+ random.NextBytes(k);
+
+ k[0] &= 0xF8;
+ k[ScalarSize - 1] &= 0x7F;
+ k[ScalarSize - 1] |= 0x40;
+ }
+
private static void PointDouble(int[] x, int[] z)
{
int[] A = X25519Field.Create();
diff --git a/crypto/src/math/ec/rfc7748/X448.cs b/crypto/src/math/ec/rfc7748/X448.cs
index 63d34d1cf..63e526703 100644
--- a/crypto/src/math/ec/rfc7748/X448.cs
+++ b/crypto/src/math/ec/rfc7748/X448.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
+using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Rfc7748
@@ -52,6 +53,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
n[13] |= 0x80000000U;
}
+ public static void GeneratePrivateKey(SecureRandom random, byte[] k)
+ {
+ random.NextBytes(k);
+
+ k[0] &= 0xFC;
+ k[ScalarSize - 1] |= 0x80;
+ }
+
private static void PointDouble(uint[] x, uint[] z)
{
uint[] A = X448Field.Create();
diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs
index 403f11f50..b77853f30 100644
--- a/crypto/src/math/ec/rfc8032/Ed25519.cs
+++ b/crypto/src/math/ec/rfc8032/Ed25519.cs
@@ -5,6 +5,7 @@ using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Math.Raw;
+using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Rfc8032
@@ -248,6 +249,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
r[rOff + PointBytes - 1] |= (byte)((x[0] & 1) << 7);
}
+ public static void GeneratePrivateKey(SecureRandom random, byte[] k)
+ {
+ random.NextBytes(k);
+ }
+
public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff)
{
IDigest d = CreateDigest();
diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs
index 10ebe8f15..38bdee83e 100644
--- a/crypto/src/math/ec/rfc8032/Ed448.cs
+++ b/crypto/src/math/ec/rfc8032/Ed448.cs
@@ -5,6 +5,7 @@ using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Math.Raw;
+using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Rfc8032
@@ -257,6 +258,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
r[rOff + PointBytes - 1] = (byte)((x[0] & 1) << 7);
}
+ public static void GeneratePrivateKey(SecureRandom random, byte[] k)
+ {
+ random.NextBytes(k);
+ }
+
public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff)
{
IXof d = CreateXof();
diff --git a/crypto/src/security/DigestUtilities.cs b/crypto/src/security/DigestUtilities.cs
index 445304196..24a68f63d 100644
--- a/crypto/src/security/DigestUtilities.cs
+++ b/crypto/src/security/DigestUtilities.cs
@@ -31,6 +31,7 @@ namespace Org.BouncyCastle.Security
GOST3411_2012_256, GOST3411_2012_512,
KECCAK_224, KECCAK_256, KECCAK_288, KECCAK_384, KECCAK_512,
MD2, MD4, MD5,
+ NONE,
RIPEMD128, RIPEMD160, RIPEMD256, RIPEMD320,
SHA_1, SHA_224, SHA_256, SHA_384, SHA_512,
SHA_512_224, SHA_512_256,
@@ -222,6 +223,7 @@ namespace Org.BouncyCastle.Security
case DigestAlgorithm.MD2: return new MD2Digest();
case DigestAlgorithm.MD4: return new MD4Digest();
case DigestAlgorithm.MD5: return new MD5Digest();
+ case DigestAlgorithm.NONE: return new NullDigest();
case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest();
case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest();
case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest();
diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs
index 6107bf878..ae8d21f0a 100644
--- a/crypto/src/security/SignerUtilities.cs
+++ b/crypto/src/security/SignerUtilities.cs
@@ -3,7 +3,9 @@ using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Bsi;
using Org.BouncyCastle.Asn1.CryptoPro;
+using Org.BouncyCastle.Asn1.Eac;
using Org.BouncyCastle.Asn1.EdEC;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
@@ -222,6 +224,108 @@ namespace Org.BouncyCastle.Security
algorithms["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA";
algorithms[TeleTrusTObjectIdentifiers.ECSignWithRipeMD160.Id] = "RIPEMD160withECDSA";
+ algorithms["NONEWITHCVC-ECDSA"] = "NONEwithCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHNONE"] = "NONEwithCVC-ECDSA";
+
+ algorithms["SHA1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+ algorithms["SHA-1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA1"] = "SHA-1withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA-1"] = "SHA-1withCVC-ECDSA";
+ algorithms["SHA1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+ algorithms["SHA-1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA";
+ algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_1.Id] = "SHA-1withCVC-ECDSA";
+
+ algorithms["SHA224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+ algorithms["SHA-224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA224"] = "SHA-224withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA-224"] = "SHA-224withCVC-ECDSA";
+ algorithms["SHA224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+ algorithms["SHA-224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA";
+ algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_224.Id] = "SHA-224withCVC-ECDSA";
+
+ algorithms["SHA256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+ algorithms["SHA-256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA256"] = "SHA-256withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA-256"] = "SHA-256withCVC-ECDSA";
+ algorithms["SHA256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+ algorithms["SHA-256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA";
+ algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_256.Id] = "SHA-256withCVC-ECDSA";
+
+ algorithms["SHA384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+ algorithms["SHA-384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA384"] = "SHA-384withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA-384"] = "SHA-384withCVC-ECDSA";
+ algorithms["SHA384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+ algorithms["SHA-384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA";
+ algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_384.Id] = "SHA-384withCVC-ECDSA";
+
+ algorithms["SHA512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+ algorithms["SHA-512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA512"] = "SHA-512withCVC-ECDSA";
+ algorithms["CVC-ECDSAWITHSHA-512"] = "SHA-512withCVC-ECDSA";
+ algorithms["SHA512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+ algorithms["SHA-512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA";
+ algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_512.Id] = "SHA-512withCVC-ECDSA";
+
+ algorithms["NONEWITHPLAIN-ECDSA"] = "NONEwithPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHNONE"] = "NONEwithPLAIN-ECDSA";
+
+ algorithms["SHA1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+ algorithms["SHA-1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA1"] = "SHA-1withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA-1"] = "SHA-1withPLAIN-ECDSA";
+ algorithms["SHA1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+ algorithms["SHA-1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA";
+ algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA1.Id] = "SHA-1withPLAIN-ECDSA";
+
+ algorithms["SHA224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+ algorithms["SHA-224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA224"] = "SHA-224withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA-224"] = "SHA-224withPLAIN-ECDSA";
+ algorithms["SHA224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+ algorithms["SHA-224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA";
+ algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA224.Id] = "SHA-224withPLAIN-ECDSA";
+
+ algorithms["SHA256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+ algorithms["SHA-256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA256"] = "SHA-256withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA-256"] = "SHA-256withPLAIN-ECDSA";
+ algorithms["SHA256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+ algorithms["SHA-256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA";
+ algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA256.Id] = "SHA-256withPLAIN-ECDSA";
+
+ algorithms["SHA384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+ algorithms["SHA-384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA384"] = "SHA-384withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA-384"] = "SHA-384withPLAIN-ECDSA";
+ algorithms["SHA384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+ algorithms["SHA-384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA";
+ algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA384.Id] = "SHA-384withPLAIN-ECDSA";
+
+ algorithms["SHA512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+ algorithms["SHA-512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA512"] = "SHA-512withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHSHA-512"] = "SHA-512withPLAIN-ECDSA";
+ algorithms["SHA512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+ algorithms["SHA-512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA";
+ algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA512.Id] = "SHA-512withPLAIN-ECDSA";
+
+ algorithms["RIPEMD160/PLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA";
+ algorithms["PLAIN-ECDSAWITHRIPEMD160"] = "RIPEMD160withPLAIN-ECDSA";
+ algorithms["RIPEMD160WITHPLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA";
+ algorithms[BsiObjectIdentifiers.ecdsa_plain_RIPEMD160.Id] = "RIPEMD160withPLAIN-ECDSA";
+
+ algorithms["SHA1WITHECNR"] = "SHA-1withECNR";
+ algorithms["SHA-1WITHECNR"] = "SHA-1withECNR";
+ algorithms["SHA224WITHECNR"] = "SHA-224withECNR";
+ algorithms["SHA-224WITHECNR"] = "SHA-224withECNR";
+ algorithms["SHA256WITHECNR"] = "SHA-256withECNR";
+ algorithms["SHA-256WITHECNR"] = "SHA-256withECNR";
+ algorithms["SHA384WITHECNR"] = "SHA-384withECNR";
+ algorithms["SHA-384WITHECNR"] = "SHA-384withECNR";
+ algorithms["SHA512WITHECNR"] = "SHA-512withECNR";
+ algorithms["SHA-512WITHECNR"] = "SHA-512withECNR";
+
algorithms["GOST-3410"] = "GOST3410";
algorithms["GOST-3410-94"] = "GOST3410";
algorithms["GOST3411WITHGOST3410"] = "GOST3410";
@@ -268,6 +372,20 @@ namespace Org.BouncyCastle.Security
oids["SHA-256withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256;
oids["SHA-384withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384;
oids["SHA-512withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512;
+ oids["RIPEMD160withECDSA"] = TeleTrusTObjectIdentifiers.ECSignWithRipeMD160;
+
+ oids["SHA-1withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1;
+ oids["SHA-224withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224;
+ oids["SHA-256withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256;
+ oids["SHA-384withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384;
+ oids["SHA-512withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512;
+
+ oids["SHA-1withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1;
+ oids["SHA-224withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224;
+ oids["SHA-256withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256;
+ oids["SHA-384withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384;
+ oids["SHA-512withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512;
+ oids["RIPEMD160withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160;
oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
@@ -399,51 +517,6 @@ namespace Org.BouncyCastle.Security
{
return (new RsaDigestSigner(new NullDigest(), (AlgorithmIdentifier)null));
}
- if (mechanism.Equals("MD2withRSA"))
- {
- return (new RsaDigestSigner(new MD2Digest()));
- }
- if (mechanism.Equals("MD4withRSA"))
- {
- return (new RsaDigestSigner(new MD4Digest()));
- }
- if (mechanism.Equals("MD5withRSA"))
- {
- return (new RsaDigestSigner(new MD5Digest()));
- }
- if (mechanism.Equals("SHA-1withRSA"))
- {
- return (new RsaDigestSigner(new Sha1Digest()));
- }
- if (mechanism.Equals("SHA-224withRSA"))
- {
- return (new RsaDigestSigner(new Sha224Digest()));
- }
- if (mechanism.Equals("SHA-256withRSA"))
- {
- return (new RsaDigestSigner(new Sha256Digest()));
- }
- if (mechanism.Equals("SHA-384withRSA"))
- {
- return (new RsaDigestSigner(new Sha384Digest()));
- }
- if (mechanism.Equals("SHA-512withRSA"))
- {
- return (new RsaDigestSigner(new Sha512Digest()));
- }
- if (mechanism.Equals("RIPEMD128withRSA"))
- {
- return (new RsaDigestSigner(new RipeMD128Digest()));
- }
- if (mechanism.Equals("RIPEMD160withRSA"))
- {
- return (new RsaDigestSigner(new RipeMD160Digest()));
- }
- if (mechanism.Equals("RIPEMD256withRSA"))
- {
- return (new RsaDigestSigner(new RipeMD256Digest()));
- }
-
if (mechanism.Equals("RAWRSASSA-PSS"))
{
// TODO Add support for other parameter settings
@@ -455,101 +528,46 @@ namespace Org.BouncyCastle.Security
// to be used can be overridden by subsequent parameter settings.
return (new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
}
- if (mechanism.Equals("SHA-1withRSAandMGF1"))
- {
- return (new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
- }
- if (mechanism.Equals("SHA-224withRSAandMGF1"))
- {
- return (new PssSigner(new RsaBlindedEngine(), new Sha224Digest()));
- }
- if (mechanism.Equals("SHA-256withRSAandMGF1"))
+ if (Platform.EndsWith(mechanism, "withRSA"))
{
- return (new PssSigner(new RsaBlindedEngine(), new Sha256Digest()));
+ string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+ return new RsaDigestSigner(digest);
}
- if (mechanism.Equals("SHA-384withRSAandMGF1"))
- {
- return (new PssSigner(new RsaBlindedEngine(), new Sha384Digest()));
- }
- if (mechanism.Equals("SHA-512withRSAandMGF1"))
+ if (Platform.EndsWith(mechanism, "withRSAandMGF1"))
{
- return (new PssSigner(new RsaBlindedEngine(), new Sha512Digest()));
+ string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+ return new PssSigner(new RsaBlindedEngine(), digest);
}
- if (mechanism.Equals("NONEwithDSA"))
- {
- return (new DsaDigestSigner(new DsaSigner(), new NullDigest()));
- }
- if (mechanism.Equals("SHA-1withDSA"))
- {
- return (new DsaDigestSigner(new DsaSigner(), new Sha1Digest()));
- }
- if (mechanism.Equals("SHA-224withDSA"))
- {
- return (new DsaDigestSigner(new DsaSigner(), new Sha224Digest()));
- }
- if (mechanism.Equals("SHA-256withDSA"))
- {
- return (new DsaDigestSigner(new DsaSigner(), new Sha256Digest()));
- }
- if (mechanism.Equals("SHA-384withDSA"))
- {
- return (new DsaDigestSigner(new DsaSigner(), new Sha384Digest()));
- }
- if (mechanism.Equals("SHA-512withDSA"))
+ if (Platform.EndsWith(mechanism, "withDSA"))
{
- return (new DsaDigestSigner(new DsaSigner(), new Sha512Digest()));
+ string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+ return new DsaDigestSigner(new DsaSigner(), digest);
}
- if (mechanism.Equals("NONEwithECDSA"))
- {
- return (new DsaDigestSigner(new ECDsaSigner(), new NullDigest()));
- }
- if (mechanism.Equals("SHA-1withECDSA"))
+ if (Platform.EndsWith(mechanism, "withECDSA"))
{
- return (new DsaDigestSigner(new ECDsaSigner(), new Sha1Digest()));
- }
- if (mechanism.Equals("SHA-224withECDSA"))
- {
- return (new DsaDigestSigner(new ECDsaSigner(), new Sha224Digest()));
- }
- if (mechanism.Equals("SHA-256withECDSA"))
- {
- return (new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest()));
- }
- if (mechanism.Equals("SHA-384withECDSA"))
- {
- return (new DsaDigestSigner(new ECDsaSigner(), new Sha384Digest()));
- }
- if (mechanism.Equals("SHA-512withECDSA"))
- {
- return (new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()));
+ string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+ return new DsaDigestSigner(new ECDsaSigner(), digest);
}
- if (mechanism.Equals("RIPEMD160withECDSA"))
+ if (Platform.EndsWith(mechanism, "withCVC-ECDSA")
+ || Platform.EndsWith(mechanism, "withPLAIN-ECDSA"))
{
- return (new DsaDigestSigner(new ECDsaSigner(), new RipeMD160Digest()));
+ string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+ return new DsaDigestSigner(new ECDsaSigner(), digest, PlainDsaEncoding.Instance);
}
- if (mechanism.Equals("SHA1WITHECNR"))
- {
- return (new DsaDigestSigner(new ECNRSigner(), new Sha1Digest()));
- }
- if (mechanism.Equals("SHA224WITHECNR"))
- {
- return (new DsaDigestSigner(new ECNRSigner(), new Sha224Digest()));
- }
- if (mechanism.Equals("SHA256WITHECNR"))
- {
- return (new DsaDigestSigner(new ECNRSigner(), new Sha256Digest()));
- }
- if (mechanism.Equals("SHA384WITHECNR"))
- {
- return (new DsaDigestSigner(new ECNRSigner(), new Sha384Digest()));
- }
- if (mechanism.Equals("SHA512WITHECNR"))
+ if (Platform.EndsWith(mechanism, "withECNR"))
{
- return (new DsaDigestSigner(new ECNRSigner(), new Sha512Digest()));
+ string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
+ IDigest digest = DigestUtilities.GetDigest(digestName);
+ return new DsaDigestSigner(new ECNRSigner(), digest);
}
if (mechanism.Equals("GOST3410"))
diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index a9a574dbf..4a8c65e88 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -469,6 +469,14 @@ namespace Org.BouncyCastle.Utilities
}
}
+ public static void Fill(byte[] buf, int from, int to, byte b)
+ {
+ for (int i = from; i < to; ++i)
+ {
+ buf[i] = b;
+ }
+ }
+
public static byte[] CopyOf(byte[] data, int newLength)
{
byte[] tmp = new byte[newLength];
diff --git a/crypto/src/util/BigIntegers.cs b/crypto/src/util/BigIntegers.cs
index f2d0425cc..df78d1d86 100644
--- a/crypto/src/util/BigIntegers.cs
+++ b/crypto/src/util/BigIntegers.cs
@@ -86,5 +86,10 @@ namespace Org.BouncyCastle.Utilities
// fall back to a faster (restricted) method
return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min);
}
+
+ public static int GetUnsignedByteLength(BigInteger n)
+ {
+ return (n.BitLength + 7) / 8;
+ }
}
}
diff --git a/crypto/test/src/security/test/TestSignerUtil.cs b/crypto/test/src/security/test/TestSignerUtil.cs
index afd85ff4d..fb359d79d 100644
--- a/crypto/test/src/security/test/TestSignerUtil.cs
+++ b/crypto/test/src/security/test/TestSignerUtil.cs
@@ -140,7 +140,9 @@ namespace Org.BouncyCastle.Security.Tests
signParams = rsaPrivate;
verifyParams = rsaPublic;
}
- else if (cipherName == "ECDSA")
+ else if (cipherName == "ECDSA"
+ || cipherName == "CVC-ECDSA"
+ || cipherName == "PLAIN-ECDSA")
{
signParams = ecPriv;
verifyParams = ecPub;
|