diff options
Diffstat (limited to 'base/java-tools/src/com/netscape')
-rw-r--r-- | base/java-tools/src/com/netscape/cmstools/PKCS12Export.java | 468 |
1 files changed, 262 insertions, 206 deletions
diff --git a/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java b/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java index 9ab2f8505..77e6b7cb8 100644 --- a/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java +++ b/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java @@ -21,7 +21,6 @@ import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.FileReader; -import java.io.IOException; import java.security.MessageDigest; import org.mozilla.jss.CryptoManager; @@ -62,262 +61,319 @@ import org.mozilla.jss.util.Password; */ public class PKCS12Export { - private static boolean debugMode = false; + boolean debug; - private static void debug(String s) { - if (debugMode) - System.out.println("PKCS12Export debug: " + s); + String databaseDirectory; + String databasePasswordFilename; + + String pkcs12PasswordFilename; + String pkcs12OutputFilename; + + public boolean isDebug() { + return debug; } - private static void printUsage() { - System.out.println( - "Usage: PKCS12Export -d <cert/key db directory> -p <file containing password for keydb> -w <file containing pkcs12 password> -o <output file for pkcs12>"); - System.out.println(""); - System.out.println("If you want to turn on debug, do the following:"); - System.out.println( - "Usage: PKCS12Export -debug -d <cert/key db directory> -p <file containing password for keydb> -w <file containing pkcs12 password> -o <output file for pkcs12>"); + public void setDebug(boolean debug) { + this.debug = debug; } - private static byte[] getEncodedKey(org.mozilla.jss.crypto.PrivateKey pkey) { - try { - CryptoManager cm = CryptoManager.getInstance(); - CryptoToken token = cm.getInternalKeyStorageToken(); - KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3); - SymmetricKey sk = kg.generate(); - KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); - byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; - IVParameterSpec param = new IVParameterSpec(iv); - wrapper.initWrap(sk, param); - byte[] enckey = wrapper.wrap(pkey); - Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); - c.initDecrypt(sk, param); - byte[] recovered = c.doFinal(enckey); - return recovered; - } catch (Exception e) { - debug("PKCS12Export getEncodedKey: Exception=" + e.toString()); - System.exit(1); - } + public String getDatabaseDirectory() { + return databaseDirectory; + } - return null; + public void setDatabaseDirectory(String databaseDirectory) { + this.databaseDirectory = databaseDirectory; + } + public String getDatabasePasswordFilename() { + return databasePasswordFilename; } - private static void addKeyBag(org.mozilla.jss.crypto.PrivateKey pkey, X509Certificate x509cert, - Password pass, byte[] localKeyId, SEQUENCE safeContents) { - try { - PasswordConverter passConverter = new PasswordConverter(); - byte salt[] = { 0x01, 0x01, 0x01, 0x01 }; - byte[] priData = getEncodedKey(pkey); - - PrivateKeyInfo pki = (PrivateKeyInfo) - ASN1Util.decode(PrivateKeyInfo.getTemplate(), priData); - ASN1Value key = EncryptedPrivateKeyInfo.createPBE( - PBEAlgorithm.PBE_SHA1_DES3_CBC, - pass, salt, 1, passConverter, pki); - SET keyAttrs = createBagAttrs( - x509cert.getSubjectDN().toString(), localKeyId); - SafeBag keyBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG, - key, keyAttrs); - safeContents.addElement(keyBag); - } catch (Exception e) { - debug("PKCS12Export addKeyBag: Exception=" + e.toString()); - System.exit(1); - } + public void setDatabasePasswordFilename(String databasePasswordFilename) { + this.databasePasswordFilename = databasePasswordFilename; } - private static byte[] addCertBag(X509Certificate x509cert, String nickname, - SEQUENCE safeContents) throws IOException { - byte[] localKeyId = null; - try { - ASN1Value cert = new OCTET_STRING(x509cert.getEncoded()); - localKeyId = createLocalKeyId(x509cert); - SET certAttrs = null; - if (nickname != null) - certAttrs = createBagAttrs(nickname, localKeyId); - SafeBag certBag = new SafeBag(SafeBag.CERT_BAG, - new CertBag(CertBag.X509_CERT_TYPE, cert), certAttrs); - safeContents.addElement(certBag); - } catch (Exception e) { - debug("PKCS12Export addCertBag: " + e.toString()); - System.exit(1); - } + public String getPkcs12PasswordFilename() { + return pkcs12PasswordFilename; + } + + public void setPkcs12PasswordFilename(String pkcs12PasswordFilename) { + this.pkcs12PasswordFilename = pkcs12PasswordFilename; + } + + public String getPkcs12OutputFilename() { + return pkcs12OutputFilename; + } + + public void setPkcs12OutputFilename(String pkcs12OutputFilename) { + this.pkcs12OutputFilename = pkcs12OutputFilename; + } + + void debug(String s) { + if (debug) + System.out.println("PKCS12Export: " + s); + } + + byte[] getEncodedKey(org.mozilla.jss.crypto.PrivateKey pkey) throws Exception { + + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken token = cm.getInternalKeyStorageToken(); + + KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3); + SymmetricKey sk = kg.generate(); + + KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); + byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec param = new IVParameterSpec(iv); + wrapper.initWrap(sk, param); + byte[] enckey = wrapper.wrap(pkey); + + Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); + c.initDecrypt(sk, param); + return c.doFinal(enckey); + } + + void addKeyBag(org.mozilla.jss.crypto.PrivateKey pkey, X509Certificate x509cert, + Password pass, byte[] localKeyId, SEQUENCE safeContents) throws Exception { + + PasswordConverter passConverter = new PasswordConverter(); + byte salt[] = { 0x01, 0x01, 0x01, 0x01 }; + byte[] priData = getEncodedKey(pkey); + + PrivateKeyInfo pki = (PrivateKeyInfo) + ASN1Util.decode(PrivateKeyInfo.getTemplate(), priData); + + ASN1Value key = EncryptedPrivateKeyInfo.createPBE( + PBEAlgorithm.PBE_SHA1_DES3_CBC, + pass, salt, 1, passConverter, pki); + + SET keyAttrs = createBagAttrs( + x509cert.getSubjectDN().toString(), localKeyId); + + SafeBag keyBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG, + key, keyAttrs); + + safeContents.addElement(keyBag); + } + + byte[] addCertBag(X509Certificate x509cert, String nickname, + SEQUENCE safeContents) throws Exception { + + ASN1Value cert = new OCTET_STRING(x509cert.getEncoded()); + byte[] localKeyId = createLocalKeyId(x509cert); + + SET certAttrs = null; + if (nickname != null) + certAttrs = createBagAttrs(nickname, localKeyId); + + SafeBag certBag = new SafeBag(SafeBag.CERT_BAG, + new CertBag(CertBag.X509_CERT_TYPE, cert), certAttrs); + + safeContents.addElement(certBag); return localKeyId; } - private static byte[] createLocalKeyId(X509Certificate cert) { - try { - // SHA1 hash of the X509Cert der encoding - byte certDer[] = cert.getEncoded(); + byte[] createLocalKeyId(X509Certificate cert) throws Exception { - MessageDigest md = MessageDigest.getInstance("SHA"); + // SHA1 hash of the X509Cert der encoding + byte certDer[] = cert.getEncoded(); - md.update(certDer); - return md.digest(); - } catch (Exception e) { - debug("PKCS12Export createLocalKeyId: Exception: " + e.toString()); - System.exit(1); + MessageDigest md = MessageDigest.getInstance("SHA"); + + md.update(certDer); + return md.digest(); + } + + SET createBagAttrs(String nickName, byte localKeyId[]) + throws Exception { + + SET attrs = new SET(); + SEQUENCE nickNameAttr = new SEQUENCE(); + + nickNameAttr.addElement(SafeBag.FRIENDLY_NAME); + SET nickNameSet = new SET(); + + nickNameSet.addElement(new BMPString(nickName)); + nickNameAttr.addElement(nickNameSet); + attrs.addElement(nickNameAttr); + SEQUENCE localKeyAttr = new SEQUENCE(); + + localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID); + SET localKeySet = new SET(); + + localKeySet.addElement(new OCTET_STRING(localKeyId)); + localKeyAttr.addElement(localKeySet); + attrs.addElement(localKeyAttr); + + return attrs; + } + + public byte[] generatePKCS12Data(Password password) throws Exception { + + debug("Generating PKCS #12 data"); + + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken token = cm.getInternalKeyStorageToken(); + CryptoStore store = token.getCryptoStore(); + + X509Certificate[] certs = store.getCertificates(); + + SEQUENCE encSafeContents = new SEQUENCE(); + SEQUENCE safeContents = new SEQUENCE(); + + for (int i = 0; i < certs.length; i++) { + String nickname = certs[i].getNickname(); + debug(" * Certificate: " + nickname); + org.mozilla.jss.crypto.PrivateKey prikey = cm.findPrivKeyByCert(certs[i]); + + if (prikey == null) { + debug(" Private key does not exist"); + addCertBag(certs[i], null, safeContents); + + } else { + debug(" Private key exists"); + byte localKeyId[] = + addCertBag(certs[i], nickname, safeContents); + addKeyBag(prikey, certs[i], password, localKeyId, encSafeContents); + } } - return null; + AuthenticatedSafes authSafes = new AuthenticatedSafes(); + authSafes.addSafeContents(safeContents); + authSafes.addSafeContents(encSafeContents); + + PFX pfx = new PFX(authSafes); + pfx.computeMacData(password, null, 5); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + pfx.encode(bos); + + return bos.toByteArray(); } - private static SET createBagAttrs(String nickName, byte localKeyId[]) - throws IOException { + public void initDatabase() throws Exception { + + debug("Initializing database in " + databaseDirectory); + + CryptoManager.InitializationValues vals = + new CryptoManager.InitializationValues( + databaseDirectory, "", "", "secmod.db"); + CryptoManager.initialize(vals); + + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken token = cm.getInternalKeyStorageToken(); + + debug("Reading database password from " + databasePasswordFilename); + + String line; + try (BufferedReader in = new BufferedReader(new FileReader(databasePasswordFilename))) { + line = in.readLine(); + if (line == null) { + line = ""; + } + } + Password password = new Password(line.toCharArray()); + + debug("Logging into security token"); + try { - SET attrs = new SET(); - SEQUENCE nickNameAttr = new SEQUENCE(); + token.login(password); + } finally { + password.clear(); + } + } - nickNameAttr.addElement(SafeBag.FRIENDLY_NAME); - SET nickNameSet = new SET(); + public void exportData() throws Exception { - nickNameSet.addElement(new BMPString(nickName)); - nickNameAttr.addElement(nickNameSet); - attrs.addElement(nickNameAttr); - SEQUENCE localKeyAttr = new SEQUENCE(); + debug("Reading PKCS #12 password from " + pkcs12PasswordFilename); - localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID); - SET localKeySet = new SET(); + String line; + try (BufferedReader in = new BufferedReader(new FileReader(pkcs12PasswordFilename))) { + line = in.readLine(); + if (line == null) { + line = ""; + } + } + Password password = new Password(line.toCharArray()); - localKeySet.addElement(new OCTET_STRING(localKeyId)); - localKeyAttr.addElement(localKeySet); - attrs.addElement(localKeyAttr); - return attrs; - } catch (Exception e) { - debug("PKCS12Export createBagAttrs: Exception=" + e.toString()); - System.exit(1); + byte[] data; + try { + data = generatePKCS12Data(password); + } finally { + password.clear(); + } + + debug("Storing PKCS #12 data into " + pkcs12OutputFilename); + + try (FileOutputStream fos = new FileOutputStream(pkcs12OutputFilename)) { + fos.write(data); } + } - return null; + public static void printUsage() { + System.out.println( + "Usage: PKCS12Export -d <cert/key db directory> -p <file containing password for keydb> -w <file containing pkcs12 password> -o <output file for pkcs12>"); + System.out.println(); + System.out.println("If you want to turn on debug, do the following:"); + System.out.println( + "Usage: PKCS12Export -debug -d <cert/key db directory> -p <file containing password for keydb> -w <file containing pkcs12 password> -o <output file for pkcs12>"); } - public static void main(String args[]) { + public static void main(String args[]) throws Exception { + if (args.length < 8) { printUsage(); System.exit(1); } - String pwdfile = null; - String dir = null; - String pk12pwdfile = null; - String pk12output = null; + boolean debug = false; + String databaseDirectory = null; + String databasePasswordFilename = null; + String pkcs12PasswordFilename = null; + String pkcs12OutputFilename = null; + + // TODO: get parameters using getopt + for (int i = 0; i < args.length; i++) { if (args[i].equals("-d")) { - dir = args[i + 1]; + databaseDirectory = args[i + 1]; + } else if (args[i].equals("-p")) { - pwdfile = args[i + 1]; + databasePasswordFilename = args[i + 1]; + } else if (args[i].equals("-s")) { // snickname = args[i + 1]; + } else if (args[i].equals("-w")) { - pk12pwdfile = args[i + 1]; + pkcs12PasswordFilename = args[i + 1]; + } else if (args[i].equals("-o")) { - pk12output = args[i + 1]; + pkcs12OutputFilename = args[i + 1]; + } else if (args[i].equals("-debug")) { - debugMode = true; + debug = true; } } - debug("The directory for certdb/keydb is " + dir); - debug("The password file for keydb is " + pwdfile); + // TODO: validate parameters - // get password - String pwd = null; - BufferedReader in = null; try { - in = new BufferedReader(new FileReader(pwdfile)); - pwd = in.readLine(); - if (pwd == null) { - pwd = ""; - } - } catch (Exception e) { - debug("Failed to read the keydb password from the file. Exception: " + e.toString()); - System.exit(1); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - String pk12pwd = null; + PKCS12Export tool = new PKCS12Export(); + tool.setDebug(debug); + tool.setDatabaseDirectory(databaseDirectory); + tool.setDatabasePasswordFilename(databasePasswordFilename); + tool.setPkcs12PasswordFilename(pkcs12PasswordFilename); + tool.setPkcs12OutputFilename(pkcs12OutputFilename); - try { - in = new BufferedReader(new FileReader(pk12pwdfile)); - pk12pwd = in.readLine(); - if (pk12pwd == null) { - pk12pwd = ""; - } - } catch (Exception e) { - debug("Failed to read the keydb password from the file. Exception: " + e.toString()); - System.exit(1); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + tool.initDatabase(); + tool.exportData(); - CryptoManager cm = null; - try { - CryptoManager.InitializationValues vals = - new CryptoManager.InitializationValues(dir, "", "", "secmod.db"); - CryptoManager.initialize(vals); - cm = CryptoManager.getInstance(); } catch (Exception e) { - debug("Failed to initialize the certdb."); - System.exit(1); - } - - SEQUENCE encSafeContents = new SEQUENCE(); - SEQUENCE safeContents = new SEQUENCE(); - try { - CryptoToken token = cm.getInternalKeyStorageToken(); - Password pass = new Password(pwd.toCharArray()); - token.login(pass); - CryptoStore store = token.getCryptoStore(); - X509Certificate[] certs = store.getCertificates(); - debug("Number of user certificates = " + certs.length); - Password pass12 = new Password(pk12pwd.toCharArray()); - for (int i = 0; i < certs.length; i++) { - String nickname = certs[i].getNickname(); - debug("Certificate nickname = " + nickname); - org.mozilla.jss.crypto.PrivateKey prikey = null; - try { - prikey = cm.findPrivKeyByCert(certs[i]); - } catch (Exception e) { - debug("PKCS12Export Exception: " + e.toString()); - } - - if (prikey == null) { - debug("Private key is null"); - addCertBag(certs[i], null, safeContents); - } else { - debug("Private key is not null"); - byte localKeyId[] = - addCertBag(certs[i], nickname, safeContents); - addKeyBag(prikey, certs[i], pass12, localKeyId, encSafeContents); - } + if (debug) { + e.printStackTrace(); + } else { + System.err.println("ERROR: " + e); } - - AuthenticatedSafes authSafes = new AuthenticatedSafes(); - authSafes.addSafeContents(safeContents); - authSafes.addSafeContents(encSafeContents); - PFX pfx = new PFX(authSafes); - pfx.computeMacData(pass12, null, 5); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - pfx.encode(bos); - FileOutputStream fos = new FileOutputStream(pk12output); - fos.write(bos.toByteArray()); - fos.flush(); - fos.close(); - pass.clear(); - pass12.clear(); - } catch (Exception e) { - debug("PKCS12Export Exception: " + e.toString()); System.exit(1); } } |