// 
// Decompiled by Procyon v0.6.0
// 

package com.nimbusds.jose.util;

import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.Key;
import java.util.UUID;
import java.security.PrivateKey;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
import java.security.cert.CertificateEncodingException;
import java.security.cert.Certificate;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.Provider;

public class X509CertUtils
{
    public static final String PEM_BEGIN_MARKER = "-----BEGIN CERTIFICATE-----";
    public static final String PEM_END_MARKER = "-----END CERTIFICATE-----";
    private static Provider jcaProvider;
    
    public static Provider getProvider() {
        return X509CertUtils.jcaProvider;
    }
    
    public static void setProvider(final Provider provider) {
        X509CertUtils.jcaProvider = provider;
    }
    
    public static X509Certificate parse(final byte[] derEncodedCert) {
        try {
            return parseWithException(derEncodedCert);
        }
        catch (final CertificateException e) {
            return null;
        }
    }
    
    public static X509Certificate parseWithException(final byte[] derEncodedCert) throws CertificateException {
        if (derEncodedCert == null || derEncodedCert.length == 0) {
            return null;
        }
        final CertificateFactory cf = (X509CertUtils.jcaProvider != null) ? CertificateFactory.getInstance("X.509", X509CertUtils.jcaProvider) : CertificateFactory.getInstance("X.509");
        final Certificate cert = cf.generateCertificate(new ByteArrayInputStream(derEncodedCert));
        if (!(cert instanceof X509Certificate)) {
            throw new CertificateException("Not a X.509 certificate: " + cert.getType());
        }
        return (X509Certificate)cert;
    }
    
    public static X509Certificate parse(final String pemEncodedCert) {
        if (pemEncodedCert == null || pemEncodedCert.isEmpty()) {
            return null;
        }
        final int markerStart = pemEncodedCert.indexOf("-----BEGIN CERTIFICATE-----");
        if (markerStart < 0) {
            return null;
        }
        String buf = pemEncodedCert.substring(markerStart + "-----BEGIN CERTIFICATE-----".length());
        final int markerEnd = buf.indexOf("-----END CERTIFICATE-----");
        if (markerEnd < 0) {
            return null;
        }
        buf = buf.substring(0, markerEnd);
        buf = buf.replaceAll("\\s", "");
        return parse(new Base64(buf).decode());
    }
    
    public static X509Certificate parseWithException(final String pemEncodedCert) throws CertificateException {
        if (pemEncodedCert == null || pemEncodedCert.isEmpty()) {
            return null;
        }
        final int markerStart = pemEncodedCert.indexOf("-----BEGIN CERTIFICATE-----");
        if (markerStart < 0) {
            throw new CertificateException("PEM begin marker not found");
        }
        String buf = pemEncodedCert.substring(markerStart + "-----BEGIN CERTIFICATE-----".length());
        final int markerEnd = buf.indexOf("-----END CERTIFICATE-----");
        if (markerEnd < 0) {
            throw new CertificateException("PEM end marker not found");
        }
        buf = buf.substring(0, markerEnd);
        buf = buf.replaceAll("\\s", "");
        return parseWithException(new Base64(buf).decode());
    }
    
    public static String toPEMString(final X509Certificate cert) {
        return toPEMString(cert, true);
    }
    
    public static String toPEMString(final X509Certificate cert, final boolean withLineBreaks) {
        final StringBuilder sb = new StringBuilder();
        sb.append("-----BEGIN CERTIFICATE-----");
        if (withLineBreaks) {
            sb.append('\n');
        }
        try {
            sb.append(Base64.encode(cert.getEncoded()));
        }
        catch (final CertificateEncodingException e) {
            return null;
        }
        if (withLineBreaks) {
            sb.append('\n');
        }
        sb.append("-----END CERTIFICATE-----");
        return sb.toString();
    }
    
    public static Base64URL computeSHA256Thumbprint(final X509Certificate cert) {
        try {
            final byte[] derEncodedCert = cert.getEncoded();
            final MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
            return Base64URL.encode(sha256.digest(derEncodedCert));
        }
        catch (final NoSuchAlgorithmException | CertificateEncodingException e) {
            return null;
        }
    }
    
    public static UUID store(final KeyStore keyStore, final PrivateKey privateKey, final char[] keyPassword, final X509Certificate cert) throws KeyStoreException {
        final UUID alias = UUID.randomUUID();
        keyStore.setKeyEntry(alias.toString(), privateKey, keyPassword, new Certificate[] { cert });
        return alias;
    }
}
