Skip to content

Commit

Permalink
Make CertificateUtils to use other key algorithms (#8609)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhenLian authored Oct 15, 2021
1 parent 0376de1 commit e9b0c2e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
18 changes: 15 additions & 3 deletions core/src/main/java/io/grpc/util/CertificateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public static X509Certificate[] getX509Certificates(InputStream inputStream)

/**
* Generates a {@link PrivateKey} from a PEM file.
* The key should be PKCS #8 formatted.
* The key should be PKCS #8 formatted. The key algorithm should be "RSA", "DiffieHellman",
* "DSA", or "EC".
* The PEM file should contain one item in Base64 encoding, with plain-text headers and footers
* (e.g. -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----).
*
Expand All @@ -80,9 +81,20 @@ public static PrivateKey getPrivateKey(InputStream inputStream)
keyContent.append(line);
}
byte[] decodedKeyBytes = BaseEncoding.base64().decode(keyContent.toString());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKeyBytes);
return keyFactory.generatePrivate(keySpec);
try {
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
} catch (InvalidKeySpecException ignore) {
try {
return KeyFactory.getInstance("DSA").generatePrivate(keySpec);
} catch (InvalidKeySpecException ignore2) {
try {
return KeyFactory.getInstance("EC").generatePrivate(keySpec);
} catch (InvalidKeySpecException e) {
throw new InvalidKeySpecException("Neither RSA, DSA nor EC worked", e);
}
}
}
}
}

10 changes: 10 additions & 0 deletions core/src/test/java/io/grpc/util/CertificateUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class CertificateUtilsTest {
public static final String BAD_PEM_CONTENT = "----BEGIN PRIVATE KEY-----\n"
+ "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvdzKDTYvRgjBO\n"
+ "-----END PRIVATE KEY-----";
public static final String ECDSA_KEY_FILE = "ecdsa.key";

@Test
public void readPemCertFile() throws CertificateException, IOException {
Expand Down Expand Up @@ -101,4 +102,13 @@ public void readBadContentKeyFile() {
}
}

@Test
public void readEcdsaKeyFile() throws Exception {
InputStream in = TestUtils.class.getResourceAsStream("/certs/" + ECDSA_KEY_FILE);
PrivateKey key = CertificateUtils.getPrivateKey(in);
// Checks some information on the test key.
assertThat(key.getAlgorithm()).isEqualTo("EC");
assertThat(key.getFormat()).isEqualTo("PKCS#8");
}

}
5 changes: 5 additions & 0 deletions testing/src/main/resources/certs/README
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ common name which is set to *.test.google.com.
$ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in server1.csr \
-out server1.pem -extensions req_ext -extfile server1-openssl.cnf -days 3650

ecdsa.key is used to test keys with algorithm other than RSA:
----------------------------------------------------------------------------
$ openssl ecparam -name secp256k1 -genkey -noout -out ecdsa.pem
$ openssl pkcs8 -topk8 -in ecdsa.pem -out ecdsa.key -nocrypt

Clean up:
---------
$ rm *.rsa
Expand Down
5 changes: 5 additions & 0 deletions testing/src/main/resources/certs/ecdsa.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgS0hDYghCuDnBobsToMW6
vGqwulbAGUX8Oku4ysWMa4qhRANCAAThAMij1tkl4/7RQpZg3w7z1McGSS9q01+4
3bDcF/Ge2gATx/SNYT5TqaSx7Rka/sJAGaX47ExWLca4gz9KGHih
-----END PRIVATE KEY-----

0 comments on commit e9b0c2e

Please sign in to comment.