001package com.nimbusds.jose.util;
002
003
004import java.io.ByteArrayInputStream;
005import java.security.cert.Certificate;
006import java.security.cert.CertificateException;
007import java.security.cert.CertificateFactory;
008import java.security.cert.X509Certificate;
009
010import com.nimbusds.jose.util.Base64;
011
012
013/**
014 *  X.509 certificate utilities.
015 *
016 *  @author Vladimir Dzhuvinov
017 *  @version 2015-11-16
018 */
019public class X509CertUtils {
020
021
022        /**
023         * The PEM start marker.
024         */
025        private static final String PEM_BEGIN_MARKER = "-----BEGIN CERTIFICATE-----";
026
027
028        /**
029         * The PEM end marker.
030         */
031        private static final String PEM_END_MARKER = "-----END CERTIFICATE-----";
032
033
034        /**
035         * Parses a DER-encoded X.509 certificate.
036         *
037         * @param derEncodedCert The DER-encoded X.509 certificate, as a byte
038         *                       array. May be {@code null}.
039         *
040         * @return The X.509 certificate, {@code null} if parsing failed.
041         */
042        public static X509Certificate parse(final byte[] derEncodedCert) {
043
044                if (derEncodedCert == null || derEncodedCert.length == 0) {
045                        return null;
046                }
047
048                final Certificate cert;
049                try {
050                        CertificateFactory cf = CertificateFactory.getInstance("X.509");
051                        cert = cf.generateCertificate(new ByteArrayInputStream(derEncodedCert));
052                } catch (CertificateException e) {
053                        return null;
054                }
055
056                if (! (cert instanceof X509Certificate)) {
057                        return null;
058                }
059
060                return (X509Certificate)cert;
061        }
062
063
064        /**
065         * Parses a PEM-encoded X.509 certificate.
066         *
067         * @param pemEncodedCert The PEM-encoded X.509 certificate, as a
068         *                       string. May be {@code null}.
069         *
070         * @return The X.509 certificate, {@code null} if parsing failed.
071         */
072        public static X509Certificate parse(final String pemEncodedCert) {
073
074                if (pemEncodedCert == null || pemEncodedCert.isEmpty()) {
075                        return null;
076                }
077
078                final int markerStart = pemEncodedCert.indexOf(PEM_BEGIN_MARKER);
079
080                if (markerStart < 0) {
081                        return null;
082                }
083
084                String buf = pemEncodedCert.substring(markerStart + PEM_BEGIN_MARKER.length());
085
086                final int markerEnd = buf.indexOf(PEM_END_MARKER);
087
088                if (markerEnd < 0) {
089                        return null;
090                }
091
092                buf = buf.substring(0, markerEnd);
093
094                buf = buf.replaceAll("\\s", "");
095
096                return parse(new Base64(buf).decode());
097        }
098}