|
54 | 54 | import java.security.cert.X509CRL;
|
55 | 55 | import java.security.interfaces.DSAPublicKey;
|
56 | 56 | import java.security.interfaces.DSAPrivateKey;
|
| 57 | +import java.security.interfaces.ECPrivateKey; |
| 58 | +import java.security.interfaces.ECPublicKey; |
57 | 59 | import java.security.interfaces.RSAPublicKey;
|
58 | 60 | import java.security.interfaces.RSAPrivateCrtKey;
|
| 61 | +import java.security.spec.ECParameterSpec; |
59 | 62 | import java.security.spec.InvalidKeySpecException;
|
60 | 63 | import java.security.spec.KeySpec;
|
61 | 64 | import java.security.spec.PKCS8EncodedKeySpec;
|
@@ -335,8 +338,13 @@ else if ( line.indexOf(BEG_STRING_DSA) != -1 ) {
|
335 | 338 | throw mapReadException("problem creating DSA private key: ", e);
|
336 | 339 | }
|
337 | 340 | }
|
338 |
| - else if ( line.indexOf(BEG_STRING_ECPRIVATEKEY) != -1) { // TODO EC! |
339 |
| - throw new UnsupportedOperationException("EC private key not supported"); |
| 341 | + else if ( line.indexOf(BEG_STRING_ECPRIVATEKEY) != -1) { |
| 342 | + try { |
| 343 | + return readKeyPair(reader, passwd, "ECDSA", BEF_E + PEM_STRING_ECPRIVATEKEY); |
| 344 | + } |
| 345 | + catch (Exception e) { |
| 346 | + throw mapReadException("problem creating DSA private key: ", e); |
| 347 | + } |
340 | 348 | }
|
341 | 349 | else if ( line.indexOf(BEG_STRING_PKCS8INF) != -1) {
|
342 | 350 | try {
|
@@ -448,9 +456,8 @@ private static CipherParameters extractPBES2CipherParams(char[] password, PBES2P
|
448 | 456 | // PEM_read_bio_PUBKEY
|
449 | 457 | public static PublicKey readPubKey(Reader in) throws IOException {
|
450 | 458 | PublicKey pubKey = readRSAPubKey(in);
|
451 |
| - if (pubKey == null) { |
452 |
| - pubKey = readDSAPubKey(in); |
453 |
| - } |
| 459 | + if (pubKey == null) pubKey = readDSAPubKey(in); |
| 460 | + if (pubKey == null) pubKey = readECPubKey(in); |
454 | 461 | return pubKey;
|
455 | 462 | }
|
456 | 463 |
|
@@ -584,6 +591,55 @@ public static KeyPair readRSAPrivateKey(Reader in, char[] f)
|
584 | 591 | return null;
|
585 | 592 | }
|
586 | 593 |
|
| 594 | + public static ECPublicKey readECPubKey(Reader in) throws IOException { |
| 595 | + final String BEG_STRING_EC_PUBLIC = BEF_G + "EC PUBLIC KEY"; |
| 596 | + final BufferedReader reader = makeBuffered(in); String line; |
| 597 | + while ( ( line = reader.readLine() ) != null ) { |
| 598 | + if ( line.indexOf(BEG_STRING_EC_PUBLIC) != -1 ) { |
| 599 | + try { |
| 600 | + return (ECPublicKey) readPublicKey(reader, "ECDSA", BEF_E + "EC PUBLIC KEY"); |
| 601 | + } |
| 602 | + catch (Exception e) { |
| 603 | + throw mapReadException("problem creating ECDSA public key: ", e); |
| 604 | + } |
| 605 | + } |
| 606 | + } |
| 607 | + return null; |
| 608 | + } |
| 609 | + |
| 610 | + public static ECPublicKey readECPublicKey(final Reader in, final char[] passwd) throws IOException { |
| 611 | + // final String BEG_STRING_EC = BEF_G + "EC PUBLIC KEY"; |
| 612 | + final BufferedReader reader = makeBuffered(in); String line; |
| 613 | + while ( ( line = reader.readLine() ) != null ) { |
| 614 | + if ( line.indexOf(BEG_STRING_PUBLIC) != -1 ) { |
| 615 | + try { |
| 616 | + return (ECPublicKey) readPublicKey(reader, "ECDSA", BEF_E + PEM_STRING_PUBLIC); |
| 617 | + } |
| 618 | + catch (Exception e) { |
| 619 | + throw mapReadException("problem creating ECDSA public key: ", e); |
| 620 | + } |
| 621 | + } |
| 622 | + } |
| 623 | + return null; |
| 624 | + } |
| 625 | + |
| 626 | + public static KeyPair readECPrivateKey(final Reader in, final char[] passwd) |
| 627 | + throws PasswordRequiredException, IOException { |
| 628 | + final String BEG_STRING_EC = BEF_G + "EC PRIVATE KEY"; |
| 629 | + final BufferedReader reader = makeBuffered(in); String line; |
| 630 | + while ( ( line = reader.readLine() ) != null ) { |
| 631 | + if ( line.indexOf(BEG_STRING_EC) != -1 ) { |
| 632 | + try { |
| 633 | + return readKeyPair(reader, passwd, "ECDSA", BEF_E + "EC PRIVATE KEY"); |
| 634 | + } |
| 635 | + catch (Exception e) { |
| 636 | + throw mapReadException("problem creating ECDSA private key: ", e); |
| 637 | + } |
| 638 | + } |
| 639 | + } |
| 640 | + return null; |
| 641 | + } |
| 642 | + |
587 | 643 | public static CMSSignedData readPKCS7(Reader in, char[] f) throws IOException {
|
588 | 644 | final String BEG_STRING_PKCS7 = BEF_G + PEM_STRING_PKCS7;
|
589 | 645 | final BufferedReader reader = makeBuffered(in); String line;
|
@@ -810,6 +866,18 @@ public static void writeRSAPublicKey(Writer _out, RSAPublicKey obj) throws IOExc
|
810 | 866 | out.newLine();
|
811 | 867 | out.flush();
|
812 | 868 | }
|
| 869 | + |
| 870 | + public static void writeECPublicKey(Writer _out, ECPublicKey obj) throws IOException { |
| 871 | + BufferedWriter out = makeBuffered(_out); |
| 872 | + byte[] encoding = getEncoded(obj); |
| 873 | + out.write(BEF_G); out.write(PEM_STRING_PUBLIC); out.write(AFT); |
| 874 | + out.newLine(); |
| 875 | + writeEncoded(out, encoding); |
| 876 | + out.write(BEF_E); out.write(PEM_STRING_PUBLIC); out.write(AFT); |
| 877 | + out.newLine(); |
| 878 | + out.flush(); |
| 879 | + } |
| 880 | + |
813 | 881 | public static void writePKCS7(Writer _out, ContentInfo obj) throws IOException {
|
814 | 882 | BufferedWriter out = makeBuffered(_out);
|
815 | 883 | byte[] encoding = getEncoded(obj);
|
@@ -966,6 +1034,29 @@ public static void writeRSAPrivateKey(Writer _out, RSAPrivateCrtKey obj, CipherS
|
966 | 1034 | }
|
967 | 1035 | }
|
968 | 1036 |
|
| 1037 | + public static void writeECPrivateKey(Writer _out, ECPrivateKey obj, CipherSpec cipher, char[] passwd) throws IOException { |
| 1038 | + assert (obj != null); |
| 1039 | + final String PEM_STRING_EC = "EC PRIVATE KEY"; |
| 1040 | + BufferedWriter out = makeBuffered(_out); |
| 1041 | + org.bouncycastle.asn1.sec.ECPrivateKey keyStruct = new org.bouncycastle.asn1.sec.ECPrivateKey(obj.getS()); |
| 1042 | + if (cipher != null && passwd != null) { |
| 1043 | + writePemEncrypted(out, PEM_STRING_EC, keyStruct.getEncoded(), cipher, passwd); |
| 1044 | + } else { |
| 1045 | + writePemPlain(out, PEM_STRING_EC, keyStruct.getEncoded()); |
| 1046 | + } |
| 1047 | + } |
| 1048 | + |
| 1049 | + public static void writeECParameters(Writer _out, ASN1ObjectIdentifier obj, CipherSpec cipher, char[] passwd) throws IOException { |
| 1050 | + assert (obj != null); |
| 1051 | + final String PEM_STRING_EC = "EC PARAMETERS"; |
| 1052 | + BufferedWriter out = makeBuffered(_out); |
| 1053 | + if (cipher != null && passwd != null) { |
| 1054 | + writePemEncrypted(out, PEM_STRING_EC, obj.getEncoded(), cipher, passwd); |
| 1055 | + } else { |
| 1056 | + writePemPlain(out, PEM_STRING_EC, obj.getEncoded()); |
| 1057 | + } |
| 1058 | + } |
| 1059 | + |
969 | 1060 | private static void writePemPlain(final BufferedWriter out,
|
970 | 1061 | final String PEM_ID, final byte[] encoding) throws IOException {
|
971 | 1062 | out.write(BEF_G); out.write(PEM_ID); out.write(AFT);
|
@@ -1099,7 +1190,7 @@ private static PublicKey readPublicKey(BufferedReader in, String alg, String end
|
1099 | 1190 |
|
1100 | 1191 | private static PublicKey readPublicKey(BufferedReader in, String endMarker) throws IOException {
|
1101 | 1192 | byte[] input = readBase64Bytes(in, endMarker);
|
1102 |
| - String[] algs = { "RSA", "DSA" }; |
| 1193 | + String[] algs = { "RSA", "DSA", "ECDSA" }; |
1103 | 1194 | for (int i = 0; i < algs.length; i++) {
|
1104 | 1195 | PublicKey key = readPublicKey(input, algs[i], endMarker);
|
1105 | 1196 | if (key != null) {
|
|
0 commit comments