diff --git a/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs b/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs
index 477329b7e..ae44a451f 100644
--- a/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs
+++ b/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs
@@ -66,6 +66,18 @@ namespace Org.BouncyCastle.Asn1.X509
get { return algID; }
}
+ /**
+ * for when the public key is an encoded object - if the bitstring
+ * can't be decoded this routine raises an IOException.
+ *
+ * @exception IOException - if the bit string doesn't represent a Der
+ * encoded object.
+ */
+ public Asn1Object ParsePublicKey()
+ {
+ return Asn1Object.FromByteArray(keyData.GetOctets());
+ }
+
/**
* for when the public key is an encoded object - if the bitstring
* can't be decoded this routine raises an IOException.
@@ -73,6 +85,7 @@ namespace Org.BouncyCastle.Asn1.X509
* @exception IOException - if the bit string doesn't represent a Der
* encoded object.
*/
+ [Obsolete("Use 'ParsePublicKey' instead")]
public Asn1Object GetPublicKey()
{
return Asn1Object.FromByteArray(keyData.GetOctets());
diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs
index 7a34d71df..7b19f1c0f 100644
--- a/crypto/src/security/PublicKeyFactory.cs
+++ b/crypto/src/security/PublicKeyFactory.cs
@@ -17,6 +17,7 @@ using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Security
@@ -56,7 +57,7 @@ namespace Org.BouncyCastle.Security
|| algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
{
RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance(
- keyInfo.GetPublicKey());
+ keyInfo.ParsePublicKey());
return new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent);
}
@@ -64,7 +65,7 @@ namespace Org.BouncyCastle.Security
{
Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());
- DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.GetPublicKey());
+ DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.ParsePublicKey());
BigInteger y = dhPublicKey.Y.Value;
@@ -101,7 +102,7 @@ namespace Org.BouncyCastle.Security
{
Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());
- DerInteger derY = (DerInteger) keyInfo.GetPublicKey();
+ DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();
return ReadPkcsDHParam(algOid, derY.Value, seq);
}
@@ -109,7 +110,7 @@ namespace Org.BouncyCastle.Security
{
ElGamalParameter para = new ElGamalParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
- DerInteger derY = (DerInteger) keyInfo.GetPublicKey();
+ DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();
return new ElGamalPublicKeyParameters(
derY.Value,
@@ -118,7 +119,7 @@ namespace Org.BouncyCastle.Security
else if (algOid.Equals(X9ObjectIdentifiers.IdDsa)
|| algOid.Equals(OiwObjectIdentifiers.DsaWithSha1))
{
- DerInteger derY = (DerInteger) keyInfo.GetPublicKey();
+ DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();
Asn1Encodable ae = algID.Parameters;
DsaParameters parameters = null;
@@ -158,64 +159,57 @@ namespace Org.BouncyCastle.Security
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
{
- Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
- (Asn1Sequence) algID.Parameters);
+ Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
+ DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet;
+
+ ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(publicKeyParamSet);
+ if (ecP == null)
+ return null;
Asn1OctetString key;
try
{
- key = (Asn1OctetString) keyInfo.GetPublicKey();
+ key = (Asn1OctetString)keyInfo.ParsePublicKey();
}
- catch (IOException)
+ catch (IOException e)
{
- throw new ArgumentException("invalid info structure in GOST3410 public key");
+ throw new ArgumentException("error recovering GOST3410_2001 public key", e);
}
- byte[] keyEnc = key.GetOctets();
- byte[] x = new byte[32];
- byte[] y = new byte[32];
+ int fieldSize = 32;
+ int keySize = 2 * fieldSize;
- for (int i = 0; i != y.Length; i++)
- {
- x[i] = keyEnc[32 - 1 - i];
- }
+ byte[] keyEnc = key.GetOctets();
+ if (keyEnc.Length != keySize)
+ throw new ArgumentException("invalid length for GOST3410_2001 public key");
- for (int i = 0; i != x.Length; i++)
+ byte[] x9Encoding = new byte[1 + keySize];
+ x9Encoding[0] = 0x04;
+ for (int i = 1; i <= fieldSize; ++i)
{
- y[i] = keyEnc[64 - 1 - i];
+ x9Encoding[i] = keyEnc[fieldSize - i];
+ x9Encoding[i + fieldSize] = keyEnc[keySize - i];
}
- ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
-
- if (ecP == null)
- return null;
-
- ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y));
+ ECPoint q = ecP.Curve.DecodePoint(x9Encoding);
- return new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet);
+ return new ECPublicKeyParameters("ECGOST3410", q, publicKeyParamSet);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
{
- Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
- (Asn1Sequence) algID.Parameters);
+ Gost3410PublicKeyAlgParameters algParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
- DerOctetString derY;
+ Asn1OctetString key;
try
{
- derY = (DerOctetString) keyInfo.GetPublicKey();
+ key = (Asn1OctetString)keyInfo.ParsePublicKey();
}
- catch (IOException)
+ catch (IOException e)
{
- throw new ArgumentException("invalid info structure in GOST3410 public key");
+ throw new ArgumentException("error recovering GOST3410_94 public key", e);
}
- byte[] keyEnc = derY.GetOctets();
- byte[] keyBytes = new byte[keyEnc.Length];
-
- for (int i = 0; i != keyEnc.Length; i++)
- {
- keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian
- }
+ byte[] keyBytes = Arrays.Reverse(key.GetOctets()); // was little endian
BigInteger y = new BigInteger(1, keyBytes);
@@ -236,21 +230,40 @@ namespace Org.BouncyCastle.Security
else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
{
return new Ed448PublicKeyParameters(GetRawKey(keyInfo, Ed448PublicKeyParameters.KeySize), 0);
- } else if (
- algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) ||
- algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
+ }
+ else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256)
+ || algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
{
+ Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
+ DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet;
- byte[] keyEnc = ((DerOctetString)Asn1Object.FromByteArray(keyInfo.PublicKeyData.GetOctets())).str;
+ ECGost3410Parameters ecDomainParameters =new ECGost3410Parameters(
+ new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOid(publicKeyParamSet)),
+ publicKeyParamSet,
+ gostParams.DigestParamSet,
+ gostParams.EncryptionParamSet);
+
+ Asn1OctetString key;
+ try
+ {
+ key = (Asn1OctetString)keyInfo.ParsePublicKey();
+ }
+ catch (IOException e)
+ {
+ throw new ArgumentException("error recovering GOST3410_2012 public key", e);
+ }
int fieldSize = 32;
if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
{
fieldSize = 64;
}
-
int keySize = 2 * fieldSize;
+ byte[] keyEnc = key.GetOctets();
+ if (keyEnc.Length != keySize)
+ throw new ArgumentException("invalid length for GOST3410_2012 public key");
+
byte[] x9Encoding = new byte[1 + keySize];
x9Encoding[0] = 0x04;
for (int i = 1; i <= fieldSize; ++i)
@@ -259,17 +272,9 @@ namespace Org.BouncyCastle.Security
x9Encoding[i + fieldSize] = keyEnc[keySize - i];
}
- Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.AlgorithmID.Parameters);
-
- ECGost3410Parameters ecDomainParameters =
- new ECGost3410Parameters(
- new ECNamedDomainParameters(gostParams.PublicKeyParamSet, ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet)),
- gostParams.PublicKeyParamSet,
- gostParams.DigestParamSet,
- gostParams.EncryptionParamSet);
-
- return new ECPublicKeyParameters(ecDomainParameters.Curve.DecodePoint(x9Encoding), ecDomainParameters);
+ ECPoint q = ecDomainParameters.Curve.DecodePoint(x9Encoding);
+ return new ECPublicKeyParameters(q, ecDomainParameters);
}
else
{
diff --git a/crypto/test/src/crypto/test/OAEPTest.cs b/crypto/test/src/crypto/test/OAEPTest.cs
index 204784cee..0d4374db1 100644
--- a/crypto/test/src/crypto/test/OAEPTest.cs
+++ b/crypto/test/src/crypto/test/OAEPTest.cs
@@ -310,7 +310,7 @@ namespace Org.BouncyCastle.Crypto.Tests
//
Asn1Object pubKeyObj = Asn1Object.FromByteArray(pubKeyEnc);
RsaPublicKeyStructure pubStruct = RsaPublicKeyStructure.GetInstance(
- SubjectPublicKeyInfo.GetInstance(pubKeyObj).GetPublicKey());
+ SubjectPublicKeyInfo.GetInstance(pubKeyObj).ParsePublicKey());
//
// extract the private key info.
|