55import java .security .Key ;
66import java .security .PrivateKey ;
77import java .security .PublicKey ;
8+ import java .security .spec .EdECPrivateKeySpec ;
9+ import java .security .spec .EdECPublicKeySpec ;
810import java .security .spec .InvalidKeySpecException ;
911import java .security .spec .KeySpec ;
12+ import java .security .spec .NamedParameterSpec ;
1013import java .security .spec .X509EncodedKeySpec ;
1114
1215import org .bouncycastle .asn1 .ASN1Encoding ;
13- import org .bouncycastle .asn1 .ASN1InputStream ;
1416import org .bouncycastle .asn1 .ASN1ObjectIdentifier ;
1517import org .bouncycastle .asn1 .ASN1OctetString ;
1618import org .bouncycastle .asn1 .ASN1Primitive ;
1719import org .bouncycastle .asn1 .ASN1Sequence ;
18- import org .bouncycastle .asn1 .DEROctetString ;
19- import org .bouncycastle .internal .asn1 .edec .EdECObjectIdentifiers ;
2020import org .bouncycastle .asn1 .pkcs .PrivateKeyInfo ;
2121import org .bouncycastle .asn1 .x509 .AlgorithmIdentifier ;
2222import org .bouncycastle .asn1 .x509 .SubjectPublicKeyInfo ;
2323import org .bouncycastle .crypto .CipherParameters ;
24+ import org .bouncycastle .crypto .params .AsymmetricKeyParameter ;
2425import org .bouncycastle .crypto .params .Ed25519PrivateKeyParameters ;
2526import org .bouncycastle .crypto .params .Ed25519PublicKeyParameters ;
2627import org .bouncycastle .crypto .params .Ed448PublicKeyParameters ;
2728import org .bouncycastle .crypto .params .X25519PublicKeyParameters ;
2829import org .bouncycastle .crypto .params .X448PublicKeyParameters ;
2930import org .bouncycastle .crypto .util .OpenSSHPrivateKeyUtil ;
3031import org .bouncycastle .crypto .util .OpenSSHPublicKeyUtil ;
32+ import org .bouncycastle .internal .asn1 .edec .EdECObjectIdentifiers ;
3133import org .bouncycastle .jcajce .interfaces .EdDSAPublicKey ;
3234import org .bouncycastle .jcajce .interfaces .XDHPublicKey ;
3335import org .bouncycastle .jcajce .provider .asymmetric .util .BaseKeyFactorySpi ;
@@ -144,7 +146,32 @@ protected PrivateKey engineGeneratePrivate(
144146 {
145147 return new BC15EdDSAPrivateKey ((Ed25519PrivateKeyParameters )parameters );
146148 }
147- throw new IllegalStateException ("openssh private key not Ed25519 private key" );
149+ throw new InvalidKeySpecException ("openssh private key not Ed25519 private key" );
150+ }
151+ else if (keySpec instanceof EdECPrivateKeySpec )
152+ {
153+ EdECPrivateKeySpec edSpec = (EdECPrivateKeySpec )keySpec ;
154+ try
155+ {
156+ AsymmetricKeyParameter parameters ;
157+ if (NamedParameterSpec .ED448 .getName ().equalsIgnoreCase (edSpec .getParams ().getName ()))
158+ {
159+ parameters = SignatureSpi .getEd448PrivateKey (edSpec .getBytes ());
160+ }
161+ else if (NamedParameterSpec .ED25519 .getName ().equalsIgnoreCase (edSpec .getParams ().getName ()))
162+ {
163+ parameters = SignatureSpi .getEd25519PrivateKey (edSpec .getBytes ());
164+ }
165+ else
166+ {
167+ throw new InvalidKeySpecException ("unrecognized named parameters: " + edSpec .getParams ().getName ());
168+ }
169+ return new BC15EdDSAPrivateKey (parameters );
170+ }
171+ catch (InvalidKeyException e )
172+ {
173+ throw new InvalidKeySpecException (e .getMessage (), e );
174+ }
148175 }
149176
150177 return super .engineGeneratePrivate (keySpec );
@@ -210,6 +237,31 @@ else if (keySpec instanceof RawEncodedKeySpec)
210237 throw new InvalidKeySpecException ("factory not a specific type, cannot recognise raw encoding" );
211238 }
212239 }
240+ else if (keySpec instanceof EdECPublicKeySpec )
241+ {
242+ EdECPublicKeySpec edSpec = (EdECPublicKeySpec )keySpec ;
243+ try
244+ {
245+ AsymmetricKeyParameter parameters ;
246+ if (NamedParameterSpec .ED448 .getName ().equalsIgnoreCase (edSpec .getParams ().getName ()))
247+ {
248+ parameters = SignatureSpi .getEd448PublicKey (edSpec .getPoint ());
249+ }
250+ else if (NamedParameterSpec .ED25519 .getName ().equalsIgnoreCase (edSpec .getParams ().getName ()))
251+ {
252+ parameters = SignatureSpi .getEd25519PublicKey (edSpec .getPoint ());
253+ }
254+ else
255+ {
256+ throw new InvalidKeySpecException ("unrecognized named parameters: " + edSpec .getParams ().getName ());
257+ }
258+ return new BC15EdDSAPublicKey (parameters );
259+ }
260+ catch (InvalidKeyException e )
261+ {
262+ throw new InvalidKeySpecException (e .getMessage (), e );
263+ }
264+ }
213265 else if (keySpec instanceof OpenSSHPublicKeySpec )
214266 {
215267 CipherParameters parameters = OpenSSHPublicKeyUtil .parsePublicKey (((OpenSSHPublicKeySpec )keySpec ).getEncoded ());
@@ -218,7 +270,7 @@ else if (keySpec instanceof OpenSSHPublicKeySpec)
218270 return new BC15EdDSAPublicKey (new byte [0 ], ((Ed25519PublicKeyParameters )parameters ).getEncoded ());
219271 }
220272
221- throw new IllegalStateException ("openssh public key not Ed25519 public key" );
273+ throw new InvalidKeySpecException ("openssh public key not Ed25519 public key" );
222274 }
223275
224276 return super .engineGeneratePublic (keySpec );
0 commit comments