/* * Copyright (C) 2013 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.tag.setup.cmd; import com.intel.mtwilson.tag.setup.TagCommand; import com.intel.mtwilson.tag.model.File; import com.intel.dcsg.cpg.crypto.RsaUtil; import com.intel.dcsg.cpg.util.ByteArray; import com.intel.dcsg.cpg.io.UUID; import com.intel.dcsg.cpg.validation.Fault; import com.intel.dcsg.cpg.x509.X509Builder; import com.intel.dcsg.cpg.x509.X509Util; import com.intel.mtwilson.My; import com.intel.mtwilson.tag.dao.TagJdbi; import java.io.FileOutputStream; import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; import org.apache.commons.configuration.MapConfiguration; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This command exports a file from the database to the filesystem * * Usage: create-ca-key "CN=mykey,O=myorg,C=US" * * Use double-quotes; on Windows especially do not use single quotes around the argument because it will be a part of it * * If a distinguished name is not provided, a default name will be used * * @author jbuhacoff */ public class TagCreateCaKey extends TagCommand { private static Logger log = LoggerFactory.getLogger(TagCreateCaKey.class); public static final String PRIVATEKEY_FILE = "cakey"; public static final String CACERTS_FILE = "cacerts"; @Override public void execute(String[] args) throws Exception { // file name, and either outfile or stdout String dn; if( args.length > 0 ) { dn = args[0]; } else { dn = "CN=asset-tag-service,OU=mtwilson"; } // create a new key pair KeyPair cakey = RsaUtil.generateRsaKeyPair(2048); X509Builder builder = X509Builder.factory(); X509Certificate cacert = builder.selfSigned(dn, cakey).expires(3650, TimeUnit.DAYS).build(); if( cacert == null ) { // log.error("Failed to create certificate"); // no need to print this, if the build failed there are guaranteed to be faults to print... List<Fault> faults = builder.getFaults(); for(Fault fault : faults) { log.error(String.format("%s%s", fault.toString(), fault.getCause() == null ? "" : ": "+fault.getCause().getMessage())); } return; } String privateKeyPem = RsaUtil.encodePemPrivateKey(cakey.getPrivate()); String cacertPem = X509Util.encodePemCertificate(cacert); String combinedPrivateKeyAndCertPem = privateKeyPem + cacertPem; byte[] combinedPrivateKeyAndCertPemBytes = combinedPrivateKeyAndCertPem.getBytes("UTF-8"); byte[] cacertPemContent = cacertPem.getBytes("UTF-8"); // for now... there can only be ONE CA private key in the database (but we support storing multiple certs) File cakeyFile = TagJdbi.fileDao().findByName(PRIVATEKEY_FILE); if( cakeyFile == null ) { // create new private key file TagJdbi.fileDao().insert(new UUID(), PRIVATEKEY_FILE, "text/plain", combinedPrivateKeyAndCertPemBytes); } else { // replace existing private key... TagJdbi.fileDao().update(cakeyFile.getId(), PRIVATEKEY_FILE, "text/plain", combinedPrivateKeyAndCertPemBytes); } // add the ca cert to the list of approved certs File cacertsFile = TagJdbi.fileDao().findByName(CACERTS_FILE); if( cacertsFile == null ) { // create new cacerts file TagJdbi.fileDao().insert(new UUID(), CACERTS_FILE, "text/plain", cacertPemContent); } else { // append new cacert to existing file in database byte[] content = ByteArray.concat(cacertsFile.getContent(), cacertPemContent); TagJdbi.fileDao().update(cacertsFile.getId(), CACERTS_FILE, "text/plain", content); // and write to disk also for easy sharing with mtwilson: tag-cacerts.pem try(FileOutputStream out = new FileOutputStream(My.configuration().getAssetTagCaCertificateFile())) { IOUtils.write(content, out); } } } public static void main(String args[]) throws Exception { TagCreateCaKey cmd = new TagCreateCaKey(); cmd.setOptions(new MapConfiguration(new Properties())); cmd.execute(new String[] { "CN=Asset CA,OU=Datacenter,C=US" }); } }