diff --git a/crypto/src/asn1/Asn1OctetString.cs b/crypto/src/asn1/Asn1OctetString.cs
index d8a7bf27a..9104c9ad3 100644
--- a/crypto/src/asn1/Asn1OctetString.cs
+++ b/crypto/src/asn1/Asn1OctetString.cs
@@ -110,15 +110,17 @@ namespace Org.BouncyCastle.Asn1
return contents;
}
+ public virtual int GetOctetsLength() => GetOctets().Length;
+
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
internal ReadOnlyMemory<byte> GetOctetsMemory()
{
- return contents.AsMemory();
+ return GetOctets().AsMemory();
}
internal ReadOnlySpan<byte> GetOctetsSpan()
{
- return contents.AsSpan();
+ return GetOctets().AsSpan();
}
#endif
diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
index 8d767c477..9535dbcae 100644
--- a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
+++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
@@ -170,10 +170,15 @@ namespace Org.BouncyCastle.Asn1.Pkcs
get { return privateKeyAlgorithm; }
}
+ public virtual Asn1OctetString PrivateKey => privateKey;
+
+ [Obsolete("Use 'PrivateKey' instead")]
public virtual Asn1OctetString PrivateKeyData
{
get { return privateKey; }
- }
+ }
+
+ public virtual int PrivateKeyLength => privateKey.GetOctetsLength();
public virtual Asn1Object ParsePrivateKey()
{
@@ -186,7 +191,10 @@ namespace Org.BouncyCastle.Asn1.Pkcs
return publicKey == null ? null : Asn1Object.FromByteArray(publicKey.GetOctets());
}
+ public virtual DerBitString PublicKey => publicKey;
+
/// <summary>Return the public key as a raw bit string.</summary>
+ [Obsolete("Use 'PublicKey' instead")]
public virtual DerBitString PublicKeyData
{
get { return publicKey; }
diff --git a/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs b/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs
index d140bb4a2..c1e3feb1b 100644
--- a/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs
@@ -57,7 +57,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
if (algOid.Equals(PkcsObjectIdentifiers.IdAlgHssLmsHashsig))
{
byte[] keyEnc = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
- DerBitString pubKey = keyInfo.PublicKeyData;
+ DerBitString pubKey = keyInfo.PublicKey;
if (Pack.BE_To_UInt32(keyEnc, 0) == 1)
{
@@ -169,7 +169,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
byte[] t1 = null;
- DerBitString publicKeyData = keyInfo.PublicKeyData;
+ DerBitString publicKeyData = keyInfo.PublicKey;
if (publicKeyData != null)
{
var pubParams = PqcPublicKeyFactory.DilithiumConverter.GetPublicKeyParameters(spParams,
@@ -192,29 +192,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
{
Asn1Sequence keyEnc = Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey());
FalconParameters spParams = PqcUtilities.FalconParamsLookup(algOid);
-
- DerBitString publicKeyData = keyInfo.PublicKeyData;
+
int version = DerInteger.GetInstance(keyEnc[0]).IntValueExact;
if (version != 1)
throw new IOException("unknown private key version: " + version);
- if (keyInfo.PublicKeyData != null)
- {
- //ASN1Sequence pubKey = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getOctets());
- return new FalconPrivateKeyParameters(spParams,
- Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(),
- Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(),
- Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(),
- publicKeyData.GetOctets()); // encT1
- }
- else
- {
- return new FalconPrivateKeyParameters(spParams,
- Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(),
- Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(),
- Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(),
- null);
- }
+ return new FalconPrivateKeyParameters(spParams,
+ Asn1OctetString.GetInstance(keyEnc[1]).GetOctets(),
+ Asn1OctetString.GetInstance(keyEnc[2]).GetOctets(),
+ Asn1OctetString.GetInstance(keyEnc[3]).GetOctets(),
+ keyInfo.PublicKey?.GetOctets()); // encT1
}
throw new Exception("algorithm identifier in private key not recognised");
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index d6fa87943..205a604a8 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -148,10 +148,11 @@ namespace Org.BouncyCastle.Security
gostParams.DigestParamSet,
gostParams.EncryptionParamSet);
- Asn1OctetString privEnc = keyInfo.PrivateKeyData;
- if (privEnc.GetOctets().Length == 32 || privEnc.GetOctets().Length == 64)
+ int privateKeyLength = keyInfo.PrivateKeyLength;
+
+ if (privateKeyLength == 32 || privateKeyLength == 64)
{
- d = new BigInteger(1, privEnc.GetOctets(), bigEndian: false);
+ d = new BigInteger(1, keyInfo.PrivateKey.GetOctets(), bigEndian: false);
}
else
{
@@ -241,10 +242,18 @@ namespace Org.BouncyCastle.Security
else if (algOid.Equals(EdECObjectIdentifiers.id_X25519)
|| algOid.Equals(CryptlibObjectIdentifiers.curvey25519))
{
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X25519PrivateKeyParameters.KeySize == keyInfo.PrivateKeyLength)
+ return new X25519PrivateKeyParameters(keyInfo.PrivateKey.GetOctets());
+
return new X25519PrivateKeyParameters(GetRawKey(keyInfo));
}
else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
{
+ // Java 11 bug: exact length of X25519/X448 secret used in Java 11
+ if (X448PrivateKeyParameters.KeySize == keyInfo.PrivateKeyLength)
+ return new X448PrivateKeyParameters(keyInfo.PrivateKey.GetOctets());
+
return new X448PrivateKeyParameters(GetRawKey(keyInfo));
}
else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519)
@@ -277,10 +286,11 @@ namespace Org.BouncyCastle.Security
gostParams.DigestParamSet,
gostParams.EncryptionParamSet);
- Asn1OctetString privEnc = keyInfo.PrivateKeyData;
- if (privEnc.GetOctets().Length == 32 || privEnc.GetOctets().Length == 64)
+ int privateKeyLength = keyInfo.PrivateKeyLength;
+
+ if (privateKeyLength == 32 || privateKeyLength == 64)
{
- d = new BigInteger(1, privEnc.GetOctets(), bigEndian: false);
+ d = new BigInteger(1, keyInfo.PrivateKey.GetOctets(), bigEndian: false);
}
else
{
diff --git a/crypto/test/src/asn1/test/PrivateKeyInfoTest.cs b/crypto/test/src/asn1/test/PrivateKeyInfoTest.cs
index 6d197ccc6..21928407a 100644
--- a/crypto/test/src/asn1/test/PrivateKeyInfoTest.cs
+++ b/crypto/test/src/asn1/test/PrivateKeyInfoTest.cs
@@ -39,7 +39,8 @@ namespace Org.BouncyCastle.Asn1.Tests
IsTrue(privInfo1.HasPublicKey);
- privInfo2 = new PrivateKeyInfo(privInfo1.PrivateKeyAlgorithm, privInfo1.ParsePrivateKey(), privInfo1.Attributes, privInfo1.PublicKeyData.GetOctets());
+ privInfo2 = new PrivateKeyInfo(privInfo1.PrivateKeyAlgorithm, privInfo1.ParsePrivateKey(),
+ privInfo1.Attributes, privInfo1.PublicKey.GetOctets());
IsTrue("enc 2 failed", AreEqual(privWithPub, privInfo2.GetEncoded()));
}
|