org.opendaylight.aaa.cert.impl.ODLMdsalKeyTool.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.aaa.cert.impl.ODLMdsalKeyTool.java

Source

/*
 * Copyright (c) 2016 Inocybe Technologies and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

package org.opendaylight.aaa.cert.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.List;

import javax.xml.bind.DatatypeConverter;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.mdsal.rev160321.keystore.Certificates;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ODLKeyTool has the basic operation to manage the Java keyStores such as generate, add and delete certificates
 *
 * @author mserngawy
 *
 */
public class ODLMdsalKeyTool {

    private final static Logger LOG = LoggerFactory.getLogger(ODLMdsalKeyTool.class);
    private final String workingDir;

    protected ODLMdsalKeyTool() {
        workingDir = KeyStoreConstant.KEY_STORE_PATH;
        KeyStoreConstant.createDir(workingDir);
    }

    public ODLMdsalKeyTool(final String workingDirectory) {
        workingDir = workingDirectory;
        KeyStoreConstant.createDir(workingDir);
    }

    public KeyStore addCertificate(final KeyStore keyStore, final String certificate, final String alias,
            final boolean deleteOld) {
        try {
            final X509Certificate newCert = getCertificate(certificate);
            if (keyStore.isCertificateEntry(alias) && deleteOld) {
                keyStore.deleteEntry(alias);
            }
            if (newCert != null) {
                keyStore.setCertificateEntry(alias, newCert);
            } else {
                LOG.warn("{} Not a valid certificate {}", alias, certificate);
                return null;
            }
            return keyStore;
        } catch (final KeyStoreException e) {
            LOG.error("failed to add certificate", e);
            return null;
        }
    }

    public byte[] convertKeystoreToBytes(final KeyStore keyStore, final String keyStorePwd) {
        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            keyStore.store(byteArrayOutputStream, keyStorePwd.toCharArray());
        } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            LOG.error("Fatal error convert keystore to bytes", e);
        }
        return byteArrayOutputStream.toByteArray();
    }

    public KeyStore createKeyStoreWithSelfSignCert(final String keyStoreName, final String keyStorePwd,
            final String dName, final String keyAlias, final int validity) {
        return createKeyStoreWithSelfSignCert(keyStoreName, keyStorePwd, dName, keyAlias, validity,
                KeyStoreConstant.DEFAULT_KEY_ALG, KeyStoreConstant.DEFAULT_KEY_SIZE,
                KeyStoreConstant.DEFAULT_SIGN_ALG);
    }

    public KeyStore createKeyStoreWithSelfSignCert(final String keyStoreName, final String keyStorePwd,
            final String dName, final String keyAlias, final int validity, final String keyAlg, final int keySize,
            final String signAlg) {
        try {
            final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlg);
            keyPairGenerator.initialize(keySize);
            final KeyPair keyPair = keyPairGenerator.generateKeyPair();
            final X509V3CertificateGenerator x509V3CertGen = new X509V3CertificateGenerator();
            x509V3CertGen.setSerialNumber(getSecureRandomeInt());
            x509V3CertGen.setIssuerDN(new X509Principal(dName));
            x509V3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
            x509V3CertGen
                    .setNotAfter(new Date(System.currentTimeMillis() + (KeyStoreConstant.DAY_TIME * validity)));
            x509V3CertGen.setSubjectDN(new X509Principal(dName));
            x509V3CertGen.setPublicKey(keyPair.getPublic());
            x509V3CertGen.setSignatureAlgorithm(signAlg);
            final X509Certificate x509Cert = x509V3CertGen.generateX509Certificate(keyPair.getPrivate());
            final KeyStore ctlKeyStore = KeyStore.getInstance("JKS");
            ctlKeyStore.load(null, keyStorePwd.toCharArray());
            ctlKeyStore.setKeyEntry(keyAlias, keyPair.getPrivate(), keyStorePwd.toCharArray(),
                    new java.security.cert.Certificate[] { x509Cert });
            LOG.info("{} is created", keyStoreName);
            return ctlKeyStore;
        } catch (final NoSuchAlgorithmException | InvalidKeyException | SecurityException | SignatureException
                | KeyStoreException | CertificateException | IOException e) {
            LOG.error("Fatal error creating keystore", e);
            return null;
        }
    }

    public KeyStore createTrustKeyStoreImportCert(final String keyStorePwd, final List<Certificates> certificates) {
        try {
            final KeyStore trustKeyStore = KeyStore.getInstance("JKS");
            trustKeyStore.load(null, keyStorePwd.toCharArray());
            for (final Certificates certificate : certificates) {
                final X509Certificate newCert = getCertificate(certificate.getX500Certificate());
                if (newCert != null) {
                    trustKeyStore.setCertificateEntry(certificate.getAlias(), newCert);
                }
            }
            LOG.info("trust keystore is created");
            return trustKeyStore;
        } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            LOG.error("Failed to create trust keystore", e);
            return null;
        }
    }

    public void exportKeystore(final KeyStore keystore, final String keystorePassword, final String fileName) {
        try (final FileOutputStream fOutputStream = new FileOutputStream(workingDir + fileName)) {
            keystore.store(fOutputStream, keystorePassword.toCharArray());
        } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            LOG.error("Fatal error export keystore", e);
        }
    }

    public String generateCertificateReq(final KeyStore odlKeyStore, final String keyStorePwd,
            final String keyAlias, final String signAlg, final boolean withTag) {
        try {
            if (odlKeyStore.containsAlias(keyAlias)) {
                final X509Certificate odlCert = (X509Certificate) odlKeyStore.getCertificate(keyAlias);
                final PublicKey pubKey = odlCert.getPublicKey();
                final PrivateKey privKey = (PrivateKey) odlKeyStore.getKey(keyAlias, keyStorePwd.toCharArray());
                final String subject = odlCert.getSubjectDN().getName();
                final X509Name xname = new X509Name(subject);
                final String signatureAlgorithm = signAlg;
                final PKCS10CertificationRequest csr = new PKCS10CertificationRequest(signatureAlgorithm, xname,
                        pubKey, null, privKey);
                final String certReq = DatatypeConverter.printBase64Binary(csr.getEncoded());
                if (withTag) {
                    final StringBuilder sb = new StringBuilder();
                    sb.append(KeyStoreConstant.BEGIN_CERTIFICATE_REQUEST);
                    sb.append("\n");
                    sb.append(certReq);
                    sb.append("\n");
                    sb.append(KeyStoreConstant.END_CERTIFICATE_REQUEST);
                    return sb.toString();
                }
                return certReq;
            }
            LOG.info("KeyStore does not contain alias {}", keyAlias);
            return null;
        } catch (final NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException
                | InvalidKeyException | NoSuchProviderException | SignatureException e) {
            LOG.error("Failed to generate certificate request", e);
            return null;
        }
    }

    public String getCertificate(final KeyStore keyStore, final String keyStorePwd, final String certAlias,
            final boolean withTag) {
        try {
            if (keyStore.containsAlias(certAlias)) {
                final X509Certificate odlCert = (X509Certificate) keyStore.getCertificate(certAlias);
                final String cert = DatatypeConverter.printBase64Binary(odlCert.getEncoded());
                if (withTag) {
                    final StringBuilder sb = new StringBuilder();
                    sb.append(KeyStoreConstant.BEGIN_CERTIFICATE);
                    sb.append("\n");
                    sb.append(cert);
                    sb.append("\n");
                    sb.append(KeyStoreConstant.END_CERTIFICATE);
                    return sb.toString();
                }
                return cert;
            }
            LOG.info("KeyStore does not contain alias {}", certAlias);
            return null;
        } catch (final CertificateException | KeyStoreException e) {
            LOG.error("Failed to get Certificate", e);
            return null;
        }
    }

    private X509Certificate getCertificate(String certificate) {
        if (certificate.isEmpty()) {
            return null;
        }

        if (certificate.contains(KeyStoreConstant.BEGIN_CERTIFICATE)) {
            final int fIdx = certificate.indexOf(KeyStoreConstant.BEGIN_CERTIFICATE)
                    + KeyStoreConstant.BEGIN_CERTIFICATE.length();
            final int sIdx = certificate.indexOf(KeyStoreConstant.END_CERTIFICATE);
            certificate = certificate.substring(fIdx, sIdx);
        }
        final byte[] byteCert = Base64.decodeBase64(certificate);
        final InputStream inputStreamCert = new ByteArrayInputStream(byteCert);
        CertificateFactory certFactory;
        try {
            certFactory = CertificateFactory.getInstance("X.509");
            final X509Certificate newCert = (X509Certificate) certFactory.generateCertificate(inputStreamCert);
            newCert.checkValidity();
            return newCert;
        } catch (final CertificateException e) {
            LOG.error("Failed to get certificate", e);
            return null;
        }
    }

    private BigInteger getSecureRandomeInt() {
        final SecureRandom secureRandom = new SecureRandom();
        final BigInteger bigInt = BigInteger.valueOf(secureRandom.nextInt());
        return new BigInteger(1, bigInt.toByteArray());
    }

    public KeyStore loadKeyStore(final byte[] keyStoreBytes, final String keyStorePwd) {
        try {
            final KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(new ByteArrayInputStream(keyStoreBytes), keyStorePwd.toCharArray());
            return keyStore;
        } catch (final KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            LOG.error("Fatal error load keystore", e);
            return null;
        }
    }
}