Java tutorial
/* * Copyright 2014 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.overlord.commons.karaf.commands.saml; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.x509.X509V3CertificateGenerator; import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; import org.overlord.commons.karaf.commands.i18n.Messages; /** * Saml Keystore generator util. It generates a keystore file based on a * password. It is based on the KeyGen source code, but using the bouncy castle * keypair generation. * * * @author David Virgil Naranjo */ public class GenerateSamlKeystoreUtil { private final static int validity = 90; private char[] keyPass = null; private char[] storePass = null; private final String providerName = null; private KeyStore keyStore = null; private String storetype = null; private String srcstoretype = null; private String alias = null; private String dname = null; private String keyAlgName = null; private int keysize = -1; private final String startDate = null; /** * Instantiates a new generate saml keystore util. */ public GenerateSamlKeystoreUtil() { storetype = "jks"; //$NON-NLS-1$ alias = "overlord"; //$NON-NLS-1$ dname = "CN=Picketbox vault, OU=picketbox, O=Jboss, L=Westford, ST=Mass, C=US"; //$NON-NLS-1$ keysize = 2048; keyAlgName = "RSA"; //$NON-NLS-1$ } /** * Generate. * * @param password * the password * @param outputFile * the output file * @return true, if successful * @throws Exception * the exception */ public boolean generate(String password, File outputFile) throws Exception { storePass = password.toCharArray(); keyPass = password.toCharArray(); if (storetype == null) { storetype = KeyStore.getDefaultType(); } if (srcstoretype == null) { srcstoretype = KeyStore.getDefaultType(); } if (providerName == null) { keyStore = KeyStore.getInstance(storetype); } else { keyStore = KeyStore.getInstance(storetype, providerName); } keyStore.load(null, storePass); doGenKeyPair(alias, dname, keyAlgName, keysize, null); char[] pass = storePass; ByteArrayOutputStream bout = new ByteArrayOutputStream(); keyStore.store(bout, pass); if (!outputFile.exists()) { outputFile.createNewFile(); } FileOutputStream fout = new FileOutputStream(outputFile); try { fout.write(bout.toByteArray()); } finally { fout.close(); } return true; } /** * Creates a new key pair and self-signed certificate. * * @param alias * the alias * @param dname * the dname * @param keyAlgName * the key alg name * @param keysize * the keysize * @param sigAlgName * the sig alg name * @throws Exception * the exception */ private void doGenKeyPair(String alias, String dname, String keyAlgName, int keysize, String sigAlgName) throws Exception { if (keysize == -1) { if ("EC".equalsIgnoreCase(keyAlgName)) { //$NON-NLS-1$ keysize = 256; } else if ("RSA".equalsIgnoreCase(keyAlgName)) { //$NON-NLS-1$ keysize = 2048; } else { keysize = 1024; } } if (keyStore.containsAlias(alias)) { throw new Exception(Messages.getString("Key.pair.not.generated.alias.alias.already.exists")); //$NON-NLS-1$ } if (sigAlgName == null) { sigAlgName = getCompatibleSigAlgName(keyAlgName); } KeyPairGenerator generator = KeyPairGenerator.getInstance(keyAlgName); generator.initialize(keysize); KeyPair keypair = generator.generateKeyPair(); PrivateKey privKey = keypair.getPrivate(); X509Certificate[] chain = new X509Certificate[1]; Date date = getStartDate(startDate); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); // Configuramos la fecha que se recibe calendar.add(Calendar.DAY_OF_YEAR, validity); // time from which certificate is valid Date expiryDate = calendar.getTime(); // time after which certificate is not valid BigInteger serialNumber = new BigInteger("10"); // serial number for certificate //$NON-NLS-1$ // private key of the certifying authority (ca) certificate X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); X500Principal subjectName = new X500Principal(dname); certGen.setSerialNumber(serialNumber); certGen.setIssuerDN(subjectName); certGen.setNotBefore(date); certGen.setNotAfter(expiryDate); certGen.setSubjectDN(subjectName); certGen.setPublicKey(keypair.getPublic()); certGen.setSignatureAlgorithm("SHA256withRSA"); //$NON-NLS-1$ certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keypair.getPublic())); X509Certificate cert = certGen.generate(keypair.getPrivate(), providerName); chain[0] = cert; keyStore.setKeyEntry(alias, privKey, keyPass, chain); } /** * Gets the compatible sig alg name. * * @param keyAlgName * the key alg name * @return the compatible sig alg name * @throws Exception * the exception */ private static String getCompatibleSigAlgName(String keyAlgName) throws Exception { if ("DSA".equalsIgnoreCase(keyAlgName)) { //$NON-NLS-1$ return "SHA1WithDSA"; //$NON-NLS-1$ } else if ("RSA".equalsIgnoreCase(keyAlgName)) { //$NON-NLS-1$ return "SHA256WithRSA"; //$NON-NLS-1$ } else if ("EC".equalsIgnoreCase(keyAlgName)) { //$NON-NLS-1$ return "SHA256withECDSA"; //$NON-NLS-1$ } else { throw new Exception(Messages.getString("Cannot.derive.signature.algorithm")); //$NON-NLS-1$ } } /** * Returns the issue time that's specified the -startdate option. * * @param s * the value of -startdate option * @return the start date * @throws IOException * Signals that an I/O exception has occurred. */ private static Date getStartDate(String s) throws IOException { Calendar c = new GregorianCalendar(); return c.getTime(); } }