summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-07-18 11:16:50 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-07-18 11:16:50 +0700
commit24214b3eed3cc1b85ea228e88c42a29f14955f3a (patch)
tree35827d78fdea04902451715032f33a466c2bf7ec
parentRefactoring in Asn1 (diff)
downloadBouncyCastle.NET-ed25519-24214b3eed3cc1b85ea228e88c42a29f14955f3a.tar.xz
Refactoring around PrivateKeyInfo
-rw-r--r--crypto/src/asn1/Asn1OctetString.cs6
-rw-r--r--crypto/src/asn1/pkcs/PrivateKeyInfo.cs10
-rw-r--r--crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs29
-rw-r--r--crypto/src/security/PrivateKeyFactory.cs22
-rw-r--r--crypto/test/src/asn1/test/PrivateKeyInfoTest.cs3
5 files changed, 39 insertions, 31 deletions
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()));
         }