Skip to content

Commit

Permalink
Add CertificateChain converters
Browse files Browse the repository at this point in the history
The CertificateChain class has been modified to support
importing/exporting certificates from/to a series of PEM
certificates or PKCS #7 data.
  • Loading branch information
edewata committed Feb 17, 2021
1 parent 92911e7 commit e818df1
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions org/mozilla/jss/netscape/security/x509/CertificateChain.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.mozilla.jss.netscape.security.pkcs.PKCS7;
import org.mozilla.jss.netscape.security.util.Cert;
import org.mozilla.jss.netscape.security.util.Utils;

public class CertificateChain implements Serializable {

Expand Down Expand Up @@ -150,6 +153,89 @@ private void readObject(java.io.ObjectInputStream in)
decode(in);
}

public void addCertificate(X509Certificate cert) {
certs.add(cert);
}

public void addCertificateChain(CertificateChain certChain) {
certs.addAll(certChain.certs);
}

public void addPKCS7(PKCS7 pkcs7) {
certs.addAll(Arrays.asList(pkcs7.getCertificates()));
}

/**
* Convert a series of PEM certificates or a PKCS #7 data into a certificate chain.
* This method will only accept a single chain, so it cannot be used to load CA bundle.
*/
public static CertificateChain fromPEMString(String input) throws Exception {

CertificateChain certChain = new CertificateChain();

StringBuilder sb = new StringBuilder();
String[] lines = input.split("\\r?\\n");

for (String line : lines) {
line = line.trim();

if (Cert.HEADER.equals(line)) {
sb.setLength(0);

} else if (Cert.FOOTER.equals(line)) {
byte[] bytes = Utils.base64decode(sb.toString());
certChain.addCertificate(new X509CertImpl(bytes));

} else if (PKCS7.HEADER.equals(line)) {
sb.setLength(0);

} else if (PKCS7.FOOTER.equals(line)) {
byte[] bytes = Utils.base64decode(sb.toString());
PKCS7 pkcs7 = new PKCS7(bytes);
certChain.addPKCS7(pkcs7);

} else {
sb.append(line);
}
}

// sort and validate the certificate chain
certChain.sort();

return certChain;
}

/**
* Convert the certificate chain into a series of PEM certificates.
*/
public String toPEMString() throws Exception {

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);

for (X509Certificate cert : certs) {
pw.println(Cert.HEADER);
pw.print(Utils.base64encodeMultiLine(cert.getEncoded()));
pw.println(Cert.FOOTER);
}

return sw.toString();
}

/**
* Convert the certificate chain into a PKCS #7 object.
*/
public PKCS7 toPKCS7() throws Exception {

// convert X509Certificate into X509CertImpl
List<X509CertImpl> certImpls = new ArrayList<>();
for (X509Certificate cert : certs) {
certImpls.add(new X509CertImpl(cert.getEncoded()));
}

return new PKCS7(certImpls.toArray(new X509CertImpl[0]));
}

/**
* Converts the certificate chain to a readable string.
*/
Expand Down

0 comments on commit e818df1

Please sign in to comment.