summaryrefslogtreecommitdiffstats
path: root/base/java-tools
diff options
context:
space:
mode:
Diffstat (limited to 'base/java-tools')
-rw-r--r--base/java-tools/src/com/netscape/cmstools/PKCS12Export.java468
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);
}
}