22
22
import java .security .AlgorithmParameters ;
23
23
import java .security .GeneralSecurityException ;
24
24
import java .security .KeyFactory ;
25
+ import java .security .NoSuchAlgorithmException ;
25
26
import java .security .PrivateKey ;
26
27
import java .security .spec .InvalidKeySpecException ;
27
28
import java .security .spec .PKCS8EncodedKeySpec ;
52
53
*/
53
54
final class PemPrivateKeyParser {
54
55
55
- private static final String PKCS1_HEADER = "-+BEGIN\\ s+RSA\\ s+PRIVATE\\ s+KEY[^-]*-+(?:\\ s|\\ r|\\ n)+" ;
56
+ private static final String PKCS1_RSA_HEADER = "-+BEGIN\\ s+RSA\\ s+PRIVATE\\ s+KEY[^-]*-+(?:\\ s|\\ r|\\ n)+" ;
56
57
57
- private static final String PKCS1_FOOTER = "-+END\\ s+RSA\\ s+PRIVATE\\ s+KEY[^-]*-+" ;
58
+ private static final String PKCS1_RSA_FOOTER = "-+END\\ s+RSA\\ s+PRIVATE\\ s+KEY[^-]*-+" ;
58
59
59
60
private static final String PKCS8_HEADER = "-+BEGIN\\ s+PRIVATE\\ s+KEY[^-]*-+(?:\\ s|\\ r|\\ n)+" ;
60
61
@@ -64,9 +65,9 @@ final class PemPrivateKeyParser {
64
65
65
66
private static final String PKCS8_ENCRYPTED_FOOTER = "-+END\\ s+ENCRYPTED\\ s+PRIVATE\\ s+KEY[^-]*-+" ;
66
67
67
- private static final String EC_HEADER = "-+BEGIN\\ s+EC\\ s+PRIVATE\\ s+KEY[^-]*-+(?:\\ s|\\ r|\\ n)+" ;
68
+ private static final String SEC1_EC_HEADER = "-+BEGIN\\ s+EC\\ s+PRIVATE\\ s+KEY[^-]*-+(?:\\ s|\\ r|\\ n)+" ;
68
69
69
- private static final String EC_FOOTER = "-+END\\ s+EC\\ s+PRIVATE\\ s+KEY[^-]*-+" ;
70
+ private static final String SEC1_EC_FOOTER = "-+END\\ s+EC\\ s+PRIVATE\\ s+KEY[^-]*-+" ;
70
71
71
72
private static final String BASE64_TEXT = "([a-z0-9+/=\\ r\\ n]+)" ;
72
73
@@ -75,12 +76,13 @@ final class PemPrivateKeyParser {
75
76
private static final List <PemParser > PEM_PARSERS ;
76
77
static {
77
78
List <PemParser > parsers = new ArrayList <>();
78
- parsers .add (new PemParser (PKCS1_HEADER , PKCS1_FOOTER , PemPrivateKeyParser ::createKeySpecForPkcs1 , "RSA" ));
79
- parsers .add (new PemParser (EC_HEADER , EC_FOOTER , PemPrivateKeyParser ::createKeySpecForEc , "EC" ));
80
- parsers .add (new PemParser (PKCS8_HEADER , PKCS8_FOOTER , PemPrivateKeyParser ::createKeySpecForPkcs8 , "RSA" , "EC" ,
81
- "DSA" , "Ed25519" ));
79
+ parsers .add (new PemParser (PKCS1_RSA_HEADER , PKCS1_RSA_FOOTER , PemPrivateKeyParser ::createKeySpecForPkcs1Rsa ,
80
+ "RSA" ));
81
+ parsers .add (new PemParser (SEC1_EC_HEADER , SEC1_EC_FOOTER , PemPrivateKeyParser ::createKeySpecForSec1Ec , "EC" ));
82
+ parsers .add (new PemParser (PKCS8_HEADER , PKCS8_FOOTER , PemPrivateKeyParser ::createKeySpecForPkcs8 , "RSA" ,
83
+ "RSASSA-PSS" , "EC" , "DSA" , "EdDSA" , "XDH" ));
82
84
parsers .add (new PemParser (PKCS8_ENCRYPTED_HEADER , PKCS8_ENCRYPTED_FOOTER ,
83
- PemPrivateKeyParser ::createKeySpecForPkcs8Encrypted , "RSA" , "EC" , "DSA" , "Ed25519 " ));
85
+ PemPrivateKeyParser ::createKeySpecForPkcs8Encrypted , "RSA" , "RSASSA-PSS" , " EC" , "DSA" , "EdDSA" , "XDH " ));
84
86
PEM_PARSERS = Collections .unmodifiableList (parsers );
85
87
}
86
88
@@ -102,11 +104,11 @@ final class PemPrivateKeyParser {
102
104
private PemPrivateKeyParser () {
103
105
}
104
106
105
- private static PKCS8EncodedKeySpec createKeySpecForPkcs1 (byte [] bytes , String password ) {
107
+ private static PKCS8EncodedKeySpec createKeySpecForPkcs1Rsa (byte [] bytes , String password ) {
106
108
return createKeySpecForAlgorithm (bytes , RSA_ALGORITHM , null );
107
109
}
108
110
109
- private static PKCS8EncodedKeySpec createKeySpecForEc (byte [] bytes , String password ) {
111
+ private static PKCS8EncodedKeySpec createKeySpecForSec1Ec (byte [] bytes , String password ) {
110
112
DerElement ecPrivateKey = DerElement .of (bytes );
111
113
Assert .state (ecPrivateKey .isType (ValueType .ENCODED , TagType .SEQUENCE ),
112
114
"Key spec should be an ASN.1 encoded sequence" );
@@ -228,21 +230,16 @@ private static byte[] decodeBase64(String content) {
228
230
}
229
231
230
232
private PrivateKey parse (byte [] bytes , String password ) {
231
- try {
232
- PKCS8EncodedKeySpec keySpec = this .keySpecFactory . apply ( bytes , password );
233
- for ( String algorithm : this . algorithms ) {
233
+ PKCS8EncodedKeySpec keySpec = this . keySpecFactory . apply ( bytes , password );
234
+ for ( String algorithm : this .algorithms ) {
235
+ try {
234
236
KeyFactory keyFactory = KeyFactory .getInstance (algorithm );
235
- try {
236
- return keyFactory .generatePrivate (keySpec );
237
- }
238
- catch (InvalidKeySpecException ex ) {
239
- }
237
+ return keyFactory .generatePrivate (keySpec );
238
+ }
239
+ catch (InvalidKeySpecException | NoSuchAlgorithmException ex ) {
240
240
}
241
- return null ;
242
- }
243
- catch (GeneralSecurityException ex ) {
244
- throw new IllegalArgumentException ("Unexpected key format" , ex );
245
241
}
242
+ return null ;
246
243
}
247
244
248
245
}
@@ -330,7 +327,7 @@ static final class DerElement {
330
327
331
328
private final long tagType ;
332
329
333
- private ByteBuffer contents ;
330
+ private final ByteBuffer contents ;
334
331
335
332
private DerElement (ByteBuffer bytes ) {
336
333
byte b = bytes .get ();
0 commit comments