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