@@ -205,22 +205,25 @@ public static Object readPEM(final BufferedReader reader, final char[] passwd) t
205205 if ( line .indexOf (BEG_STRING_PUBLIC ) != -1 ) {
206206 try {
207207 return readPublicKey (reader ,BEF_E +PEM_STRING_PUBLIC );
208- } catch (Exception e ) {
209- throw new IOException ("problem creating public key: " + e .toString (), e );
208+ }
209+ catch (Exception e ) {
210+ throw mapReadException ("problem creating public key: " , e );
210211 }
211212 }
212213 else if ( line .indexOf (BEG_STRING_DSA ) != -1 ) {
213214 try {
214215 return readKeyPair (reader ,passwd , "DSA" , BEF_E +PEM_STRING_DSA );
215- } catch (Exception e ) {
216- throw new IOException ("problem creating DSA private key: " + e .toString (), e );
216+ }
217+ catch (Exception e ) {
218+ throw mapReadException ("problem creating DSA private key: " , e );
217219 }
218220 }
219221 else if ( line .indexOf (BEG_STRING_RSA_PUBLIC ) != -1 ) {
220222 try {
221223 return readPublicKey (reader ,BEF_E +PEM_STRING_RSA_PUBLIC );
222- } catch (Exception e ) {
223- throw new IOException ("problem creating RSA public key: " + e .toString (), e );
224+ }
225+ catch (Exception e ) {
226+ throw mapReadException ("problem creating RSA public key: " , e );
224227 }
225228 }
226229 else if ( line .indexOf (BEG_STRING_X509_OLD ) != -1 ) {
@@ -308,7 +311,8 @@ else if ( line.indexOf(BEG_STRING_X509_REQ) != -1 ) {
308311 * c: PEM_read_PrivateKey + PEM_read_bio_PrivateKey
309312 * CAUTION: KeyPair#getPublic() may be null.
310313 */
311- public static KeyPair readPrivateKey (final Reader in , char [] passwd ) throws IOException {
314+ public static KeyPair readPrivateKey (final Reader in , char [] passwd )
315+ throws PasswordRequiredException , IOException {
312316 final String BEG_STRING_ECPRIVATEKEY = BEF_G + PEM_STRING_ECPRIVATEKEY ;
313317 final String BEG_STRING_PKCS8INF = BEF_G + PEM_STRING_PKCS8INF ;
314318 final String BEG_STRING_PKCS8 = BEF_G + PEM_STRING_PKCS8 ;
@@ -318,15 +322,17 @@ public static KeyPair readPrivateKey(final Reader in, char[] passwd) throws IOEx
318322 if ( line .indexOf (BEG_STRING_RSA ) != -1 ) {
319323 try {
320324 return readKeyPair (reader , passwd , "RSA" , BEF_E + PEM_STRING_RSA );
321- } catch (Exception e ) {
322- throw new IOException ("problem creating RSA private key: " + e .toString (), e );
325+ }
326+ catch (Exception e ) {
327+ throw mapReadException ("problem creating RSA private key: " , e );
323328 }
324329 }
325330 else if ( line .indexOf (BEG_STRING_DSA ) != -1 ) {
326331 try {
327332 return readKeyPair (reader , passwd , "DSA" , BEF_E + PEM_STRING_DSA );
328- } catch (Exception e ) {
329- throw new IOException ("problem creating DSA private key: " + e .toString (), e );
333+ }
334+ catch (Exception e ) {
335+ throw mapReadException ("problem creating DSA private key: " , e );
330336 }
331337 }
332338 else if ( line .indexOf (BEG_STRING_ECPRIVATEKEY ) != -1 ) { // TODO EC!
@@ -340,7 +346,7 @@ else if ( line.indexOf(BEG_STRING_PKCS8INF) != -1) {
340346 return org .jruby .ext .openssl .impl .PKey .readPrivateKey (((ASN1Object ) info .parsePrivateKey ()).getEncoded (ASN1Encoding .DER ), type );
341347 }
342348 catch (Exception e ) {
343- throw new IOException ("problem creating private key: " + e . toString () , e );
349+ throw mapReadException ("problem creating private key: " , e );
344350 }
345351 }
346352 else if ( line .indexOf (BEG_STRING_PKCS8 ) != -1 ) {
@@ -355,14 +361,22 @@ else if ( line.indexOf(BEG_STRING_PKCS8) != -1 ) {
355361 privKey = derivePrivateKeyPBES1 (eIn , algId , passwd );
356362 }
357363 return new KeyPair (null , privKey );
358- } catch (Exception e ) {
359- throw new IOException ("problem creating private key: " + e .toString (), e );
364+ }
365+ catch (Exception e ) {
366+ throw mapReadException ("problem creating private key: " , e );
360367 }
361368 }
362369 }
363370 return null ;
364371 }
365372
373+ private static IOException mapReadException (final String message , final Exception ex ) {
374+ if ( ex instanceof PasswordRequiredException ) {
375+ return (PasswordRequiredException ) ex ;
376+ }
377+ return new IOException (message + ex , ex );
378+ }
379+
366380 private static PrivateKey derivePrivateKeyPBES1 (EncryptedPrivateKeyInfo eIn , AlgorithmIdentifier algId , char [] password )
367381 throws GeneralSecurityException , IOException {
368382 // From BC's PEMReader
@@ -452,7 +466,7 @@ public static DSAPublicKey readDSAPubKey(Reader in) throws IOException {
452466 return (DSAPublicKey ) readPublicKey (reader , "DSA" , BEF_E + PEM_STRING_DSA_PUBLIC );
453467 }
454468 catch (Exception e ) {
455- throw new IOException ("problem creating DSA public key: " + e . toString () , e );
469+ throw mapReadException ("problem creating DSA public key: " , e );
456470 }
457471 }
458472 }
@@ -470,7 +484,7 @@ public static DSAPublicKey readDSAPublicKey(final Reader in, final char[] passwd
470484 return (DSAPublicKey ) readPublicKey (reader , "DSA" , BEF_E + PEM_STRING_PUBLIC );
471485 }
472486 catch (Exception e ) {
473- throw new IOException ("problem creating DSA public key: " + e . toString () , e );
487+ throw mapReadException ("problem creating DSA public key: " , e );
474488 }
475489 }
476490 }
@@ -480,15 +494,16 @@ public static DSAPublicKey readDSAPublicKey(final Reader in, final char[] passwd
480494 /*
481495 * c: PEM_read_bio_DSAPrivateKey
482496 */
483- public static KeyPair readDSAPrivateKey (final Reader in , final char [] passwd ) throws IOException {
497+ public static KeyPair readDSAPrivateKey (final Reader in , final char [] passwd )
498+ throws PasswordRequiredException , IOException {
484499 final BufferedReader reader = makeBuffered (in ); String line ;
485500 while ( ( line = reader .readLine () ) != null ) {
486501 if ( line .indexOf (BEG_STRING_DSA ) != -1 ) {
487502 try {
488503 return readKeyPair (reader , passwd , "DSA" , BEF_E + PEM_STRING_DSA );
489504 }
490505 catch (Exception e ) {
491- throw new IOException ("problem creating DSA private key: " + e . toString () , e );
506+ throw mapReadException ("problem creating DSA private key: " , e );
492507 }
493508 }
494509 }
@@ -505,15 +520,17 @@ public static RSAPublicKey readRSAPubKey(Reader in) throws IOException {
505520 if ( line .indexOf (BEG_STRING_PUBLIC ) != -1 ) {
506521 try {
507522 return readRSAPublicKey (reader , BEF_E + PEM_STRING_PUBLIC );
508- } catch (Exception e ) {
509- throw new IOException ("problem creating RSA public key: " + e .toString (), e );
523+ }
524+ catch (Exception e ) {
525+ throw mapReadException ("problem creating RSA public key: " , e );
510526 }
511527 }
512528 else if ( line .indexOf (BEG_STRING_RSA_PUBLIC ) != -1 ) {
513529 try {
514530 return readRSAPublicKey (reader , BEF_E + PEM_STRING_RSA_PUBLIC );
515- } catch (Exception e ) {
516- throw new IOException ("problem creating RSA public key: " + e .toString (), e );
531+ }
532+ catch (Exception e ) {
533+ throw mapReadException ("problem creating RSA public key: " , e );
517534 }
518535 }
519536 }
@@ -524,23 +541,24 @@ else if ( line.indexOf(BEG_STRING_RSA_PUBLIC) != -1 ) {
524541 * reads an RSA public key encoded in an PKCS#1 RSA structure.
525542 * c: PEM_read_bio_RSAPublicKey
526543 */
527- public static RSAPublicKey readRSAPublicKey (Reader in , char [] f ) throws IOException {
544+ public static RSAPublicKey readRSAPublicKey (Reader in , char [] f )
545+ throws PasswordRequiredException , IOException {
528546 final BufferedReader reader = makeBuffered (in ); String line ;
529547 while ( ( line = reader .readLine () ) != null ) {
530548 if ( line .indexOf (BEG_STRING_PUBLIC ) != -1 ) {
531549 try {
532550 return (RSAPublicKey ) readPublicKey (reader , "RSA" , BEF_E + PEM_STRING_PUBLIC );
533551 }
534552 catch (Exception e ) {
535- throw new IOException ("problem creating RSA public key: " + e . toString () , e );
553+ throw mapReadException ("problem creating RSA public key: " , e );
536554 }
537555 }
538556 else if ( line .indexOf (BEF_G +PEM_STRING_RSA_PUBLIC ) != -1 ) {
539557 try {
540558 return (RSAPublicKey ) readPublicKey (reader , "RSA" , BEF_E + PEM_STRING_RSA_PUBLIC );
541559 }
542560 catch (Exception e ) {
543- throw new IOException ("problem creating RSA public key: " + e . toString () , e );
561+ throw mapReadException ("problem creating RSA public key: " , e );
544562 }
545563 }
546564 }
@@ -550,15 +568,16 @@ else if ( line.indexOf(BEF_G+PEM_STRING_RSA_PUBLIC) != -1 ) {
550568 /**
551569 * c: PEM_read_bio_RSAPrivateKey
552570 */
553- public static KeyPair readRSAPrivateKey (Reader in , char [] f ) throws IOException {
571+ public static KeyPair readRSAPrivateKey (Reader in , char [] f )
572+ throws PasswordRequiredException , IOException {
554573 final BufferedReader reader = makeBuffered (in ); String line ;
555574 while ( ( line = reader .readLine () ) != null ) {
556575 if ( line .indexOf (BEG_STRING_RSA ) != -1 ) {
557576 try {
558577 return readKeyPair (reader ,f , "RSA" , BEF_E + PEM_STRING_RSA );
559578 }
560579 catch (Exception e ) {
561- throw new IOException ("problem creating RSA private key: " + e . toString () , e );
580+ throw mapReadException ("problem creating RSA private key: " , e );
562581 }
563582 }
564583 }
@@ -1091,7 +1110,8 @@ private static PublicKey readPublicKey(BufferedReader in, String endMarker) thro
10911110 /**
10921111 * Read a Key Pair
10931112 */
1094- private static KeyPair readKeyPair (BufferedReader in , char [] passwd , String type , String endMarker ) throws Exception {
1113+ private static KeyPair readKeyPair (BufferedReader in , char [] passwd , String type , String endMarker )
1114+ throws PasswordRequiredException , IOException , GeneralSecurityException {
10951115 boolean isEncrypted = false ;
10961116 String dekInfo = null ;
10971117
@@ -1121,10 +1141,10 @@ else if ( line.contains(endMarker) ) {
11211141 return org .jruby .ext .openssl .impl .PKey .readPrivateKey (keyBytes , type );
11221142 }
11231143
1124- private static byte [] decrypt (byte [] decoded , String dekInfo , char [] passwd ) throws IOException , GeneralSecurityException {
1125- if ( passwd == null ) {
1126- throw new IOException ( "Password is null, but a password is required" );
1127- }
1144+ private static byte [] decrypt (byte [] decoded , String dekInfo , char [] passwd )
1145+ throws PasswordRequiredException , IOException , GeneralSecurityException {
1146+ if ( passwd == null ) throw new PasswordRequiredException ( );
1147+
11281148 StringTokenizer tknz = new StringTokenizer (dekInfo , "," );
11291149 String algorithm = tknz .nextToken ();
11301150 byte [] iv = Hex .decode (tknz .nextToken ());
@@ -1151,6 +1171,14 @@ private static byte[] decrypt(byte[] decoded, String dekInfo, char[] passwd) thr
11511171 return cipher .doFinal (decoded );
11521172 }
11531173
1174+ public static class PasswordRequiredException extends IOException {
1175+
1176+ PasswordRequiredException () {
1177+ super ();
1178+ }
1179+
1180+ }
1181+
11541182 /**
11551183 * Reads in a X509Certificate.
11561184 *
0 commit comments