Skip to content

Commit

Permalink
End to End TLS SSL step #8 - Add support for PEM based certificates (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mnriem authored Nov 12, 2020
1 parent 12c9a67 commit c2dc73c
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@
import com.azure.security.keyvault.jca.model.CertificatePolicy;
import com.azure.security.keyvault.jca.model.KeyProperties;
import com.azure.security.keyvault.jca.model.SecretBundle;
import java.io.BufferedReader;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
Expand Down Expand Up @@ -249,16 +255,25 @@ Key getKey(String alias, char[] password) {
if (body != null) {
JsonConverter converter = JsonConverterFactory.createJsonConverter();
SecretBundle secretBundle = (SecretBundle) converter.fromJson(body, SecretBundle.class);
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(
new ByteArrayInputStream(Base64.getDecoder().decode(secretBundle.getValue())),
"".toCharArray()
);
alias = keyStore.aliases().nextElement();
key = keyStore.getKey(alias, "".toCharArray());
} catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException ex) {
LOGGER.log(WARNING, "Unable to decode key", ex);
if (secretBundle.getContentType().equals("application/x-pkcs12")) {
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(
new ByteArrayInputStream(Base64.getDecoder().decode(secretBundle.getValue())),
"".toCharArray()
);
alias = keyStore.aliases().nextElement();
key = keyStore.getKey(alias, "".toCharArray());
} catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException ex) {
LOGGER.log(WARNING, "Unable to decode key", ex);
}
}
if (secretBundle.getContentType().equals("application/x-pem-file")) {
try {
key = createPrivateKeyFromPem(secretBundle.getValue());
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException | IllegalArgumentException ex) {
LOGGER.log(WARNING, "Unable to decode key", ex);
}
}
}
}
Expand All @@ -271,4 +286,37 @@ Key getKey(String alias, char[] password) {
LOGGER.exiting("KeyVaultClient", "getKey", key);
return key;
}

/**
* Get the private key from the PEM string.
*
* @param pemString the PEM file in string format.
* @return the private key
* @throws IOException when an I/O error occurs.
* @throws NoSuchAlgorithmException when algorithm is unavailable.
* @throws InvalidKeySpecException when the private key cannot be generated.
*/
private PrivateKey createPrivateKeyFromPem(String pemString)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new StringReader(pemString))) {
String line = reader.readLine();
if (line == null || !line.contains("BEGIN PRIVATE KEY")) {
throw new IllegalArgumentException("No PRIVATE KEY found");
}
line = "";
while (line != null) {
if (line.contains("END PRIVATE KEY")) {
break;
}
builder.append(line);
line = reader.readLine();
}
}
byte[] bytes = Base64.getDecoder().decode(builder.toString());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePrivate(spec);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ public Key engineGetKey(String alias, char[] password) {
key = keyVaultClient.getKey(alias, password);
if (key != null) {
certificateKeys.put(alias, key);
if (aliases == null) {
aliases = keyVaultClient.getAliases();
}
if (!aliases.contains(alias)) {
aliases.add(alias);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,26 @@ public class SecretBundle implements Serializable {
* Stores the serial version UID.
*/
private static final long serialVersionUID = 1L;

/**
* Stores the content type.
*/
private String contentType;

/**
* Stores the value.
*/
private String value;

/**
* Get the content type.
*
* @return the content type.
*/
public String getContentType() {
return contentType;
}

/**
* Get the value.
*
Expand All @@ -28,6 +42,15 @@ public class SecretBundle implements Serializable {
public String getValue() {
return value;
}

/**
* Set the content type.
*
* @param contentType the content type.
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}

/**
* Set the value.
Expand Down

0 comments on commit c2dc73c

Please sign in to comment.