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

Java tutorial

Introduction

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

Source

/*
 * Copyright (c) 2015 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.FileInputStream;
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 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.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 ODLKeyTool {

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

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

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

    public boolean addCertificate(final String keyStoreName, final String keyStorePwd, final String certificate,
            final String alias) {
        try {
            final X509Certificate newCert = getCertificate(certificate);
            final KeyStore keyStore = KeyStore.getInstance("JKS");
            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
            keyStore.load(fInputStream, keyStorePwd.toCharArray());
            if (keyStore.isCertificateEntry(alias)) {
                keyStore.deleteEntry(alias);
            }
            keyStore.setCertificateEntry(alias, newCert);
            keyStore.store(new FileOutputStream(workingDir + keyStoreName), keyStorePwd.toCharArray());
            LOG.info("Certificate {}  Added to keyStore {}", alias, keyStoreName);
            return true;
        } catch (CertificateException | KeyStoreException | NoSuchAlgorithmException | IOException e) {
            LOG.error("failed to add certificate", e);
            return false;
        }
    }

    public boolean createKeyStoreImportCert(final String keyStoreName, final String keyStorePwd,
            final String certFile, final String alias) {
        KeyStore trustKeyStore;
        try {
            trustKeyStore = KeyStore.getInstance("JKS");
            trustKeyStore.load(null, keyStorePwd.toCharArray());
            if (KeyStoreConstant.checkKeyStoreFile(certFile)) {
                final String certificate = KeyStoreConstant.readFile(certFile);
                final X509Certificate newCert = getCertificate(certificate);
                trustKeyStore.setCertificateEntry(alias, newCert);
            }
            trustKeyStore.store(new FileOutputStream(workingDir + keyStoreName), keyStorePwd.toCharArray());
            LOG.info("{} is created", keyStoreName);
            return true;
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
            LOG.error("Failed to create keystore {}", keyStoreName, e);
            return false;
        }
    }

    public boolean createKeyStoreWithSelfSignCert(final String keyStoreName, final String keyStorePwd,
            final String dName, final String keyAlias, final int validity) {
        try {
            final KeyPairGenerator keyPairGenerator = KeyPairGenerator
                    .getInstance(KeyStoreConstant.DEFAULT_KEY_ALG);
            keyPairGenerator.initialize(KeyStoreConstant.DEFAULT_KEY_SIZE);
            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(KeyStoreConstant.DEFAULT_SIGN_ALG);
            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 });
            final FileOutputStream fOutputStream = new FileOutputStream(workingDir + keyStoreName);
            ctlKeyStore.store(fOutputStream, keyStorePwd.toCharArray());
            LOG.info("{} is created", keyStoreName);
            return true;
        } catch (NoSuchAlgorithmException | InvalidKeyException | SecurityException | SignatureException
                | KeyStoreException | CertificateException | IOException e) {
            LOG.error("Fatal error creating key", e);
            return false;
        }
    }

    public String generateCertificateReq(final String keyStoreName, final String keyStorePwd, final String keyAlias,
            final String signAlg, final boolean withTag) {
        try {
            final KeyStore ctlKeyStore = KeyStore.getInstance("JKS");
            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
            ctlKeyStore.load(fInputStream, keyStorePwd.toCharArray());
            if (ctlKeyStore.containsAlias(keyAlias)) {
                final X509Certificate odlCert = (X509Certificate) ctlKeyStore.getCertificate(keyAlias);
                final PublicKey pubKey = odlCert.getPublicKey();
                final PrivateKey privKey = (PrivateKey) ctlKeyStore.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 {}", keyStoreName, keyAlias);
            return null;
        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException
                | UnrecoverableKeyException | InvalidKeyException | NoSuchProviderException
                | SignatureException e) {
            LOG.error("Failed to generate certificate request {}", e.getMessage());
            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.getMessage());
            return null;
        }
    }

    public String getCertificate(final String keyStoreName, final String keyStorePwd, final String certAlias,
            final boolean withTag) {
        try {
            final KeyStore ctlKeyStore = KeyStore.getInstance("JKS");
            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
            ctlKeyStore.load(fInputStream, keyStorePwd.toCharArray());
            if (ctlKeyStore.containsAlias(certAlias)) {
                final X509Certificate odlCert = (X509Certificate) ctlKeyStore.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 {}", keyStoreName, certAlias);
            return null;
        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
            LOG.error("Failed to get Certificate {}", e.getMessage());
            return null;
        }
    }

    public KeyStore getKeyStore(final String keyStoreName, final String keyStorePwd) {
        try {
            final KeyStore keyStore = KeyStore.getInstance("JKS");
            final FileInputStream fInputStream = new FileInputStream(workingDir + keyStoreName);
            keyStore.load(fInputStream, keyStorePwd.toCharArray());
            return keyStore;
        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
            LOG.error("failed to get keystore {}", e.getMessage());
            return null;
        }
    }

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