diff options
author | Ade Lee <alee@redhat.com> | 2012-02-07 22:40:06 -0500 |
---|---|---|
committer | Ade Lee <alee@redhat.com> | 2012-02-13 22:05:39 -0500 |
commit | 55b94ef9235a7973564676c0b2580b7b243076a8 (patch) | |
tree | f7bdd5fc7ae092410c0af4b1f161aae08dfa8c30 | |
parent | 2f1ae9843d7239e970effa5e4692f3c4ab2eff6f (diff) | |
download | pki-55b94ef9235a7973564676c0b2580b7b243076a8.tar.gz pki-55b94ef9235a7973564676c0b2580b7b243076a8.tar.xz pki-55b94ef9235a7973564676c0b2580b7b243076a8.zip |
Moved client functions to CryptoUtil.java and added GenPKIArchiveOptions tool
3 files changed, 416 insertions, 197 deletions
diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java index 7890b96c8..fb2ef7799 100644 --- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java +++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java @@ -17,45 +17,18 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.CharConversionException; -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateEncodingException; import java.util.Calendar; import java.util.Collection; import java.util.Iterator; import java.util.Random; import org.mozilla.jss.CryptoManager; -import org.mozilla.jss.asn1.BIT_STRING; -import org.mozilla.jss.asn1.InvalidBERException; -import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; -import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.crypto.AlreadyInitializedException; -import org.mozilla.jss.crypto.BadPaddingException; -import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; -import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.KeyGenAlgorithm; -import org.mozilla.jss.crypto.KeyGenerator; -import org.mozilla.jss.crypto.KeyWrapAlgorithm; -import org.mozilla.jss.crypto.KeyWrapper; -import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.SymmetricKey; -import org.mozilla.jss.crypto.TokenException; -import org.mozilla.jss.crypto.X509Certificate; -import org.mozilla.jss.pkcs12.PasswordConverter; -import org.mozilla.jss.pkcs7.EncryptedContentInfo; -import org.mozilla.jss.pkix.crmf.EncryptedKey; -import org.mozilla.jss.pkix.crmf.EncryptedValue; -import org.mozilla.jss.pkix.crmf.PKIArchiveOptions; -import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.util.Password; import org.apache.commons.cli.CommandLine; @@ -70,8 +43,8 @@ import com.netscape.cms.servlet.key.model.KeyData; import com.netscape.cms.servlet.key.model.KeyDataInfo; import com.netscape.cms.servlet.request.KeyRequestResource; import com.netscape.cms.servlet.request.model.KeyRequestInfo; +import com.netscape.cmsutil.crypto.CryptoUtil; -@SuppressWarnings("deprecation") public class DRMTest { public static void usage(Options options) { @@ -128,20 +101,19 @@ public class DRMTest { } // used for crypto operations - byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; - IVParameterSpec ivSpec; - IVParameterSpec ivSpecServer; + byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec ivps = null; + IVParameterSpec ivps_server = null; try { - ivSpec = genIV(8); + ivps = genIV(8); } catch (Exception e) { - log("Can't generate initialization vector use default: " + e); - ivSpec = new IVParameterSpec(iv); + log("Can't generate initialization vector use default: " + e.toString()); + ivps = new IVParameterSpec(iv); } CryptoManager manager = null; CryptoToken token = null; - KeyGenerator kg1 = null; // used for wrapping to send data to DRM String transportCert = null; @@ -238,10 +210,9 @@ public class DRMTest { log("Archiving symmetric key"); clientId = "UUID: 123-45-6789 VEK " + Calendar.getInstance().getTime().toString(); try { - kg1 = token.getKeyGenerator(KeyGenAlgorithm.DES3); - vek = kg1.generate(); - - byte[] encoded = createPKIArchiveOptions(manager, token, transportCert, vek, null, kg1, ivSpec); + vek = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3); + byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, vek, null, + KeyGenAlgorithm.DES3, ivps); KeyRequestInfo info = client.archiveSecurityData(encoded, clientId, KeyRequestResource.SYMMETRIC_KEY_TYPE); log("Archival Results:"); @@ -272,9 +243,9 @@ public class DRMTest { // Test 6: Submit a recovery request for the symmetric key using a session key log("Submitting a recovery request for the symmetric key using session key"); try { - recoveryKey = kg1.generate(); - wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey); - KeyRequestInfo info = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivSpec.getIV()); + recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3); + wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey); + KeyRequestInfo info = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivps.getIV()); recoveryRequestId = getId(info.getRequestURL()); } catch (Exception e) { log("Exception in recovering symmetric key using session key: " + e.getMessage()); @@ -287,12 +258,14 @@ public class DRMTest { // Test 8: Get key log("Getting key: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivSpec.getIV()); + keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivps.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); - ivSpecServer = new IVParameterSpec( com.netscape.osutil.OSUtil.AtoB(keyData.getNonceData())); + ivps_server = new IVParameterSpec(com.netscape.osutil.OSUtil.AtoB(keyData.getNonceData())); try { - recoveredKey = unwrap(token, ivSpecServer,com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey), recoveryKey); + recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server, + com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey), + recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD); } catch (Exception e) { log("Exception in unwrapping key: " + e.toString()); e.printStackTrace(); @@ -309,11 +282,12 @@ public class DRMTest { recoveryPassphrase = "Gimme me keys please"; try { - recoveryKey = kg1.generate(); - wrappedRecoveryPassphrase = wrapPassphrase(token, recoveryPassphrase, ivSpec, recoveryKey); - wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey); + recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3); + wrappedRecoveryPassphrase = CryptoUtil.wrapPassphrase(token, recoveryPassphrase, ivps, recoveryKey, + EncryptionAlgorithm.DES3_CBC_PAD); + wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey); - requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); + requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV()); recoveryRequestId = getId(requestInfo.getRequestURL()); } catch (Exception e) { log("Exception in recovering symmetric key using passphrase" + e.toString()); @@ -326,11 +300,15 @@ public class DRMTest { // Test 11: Get key log("Getting key: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); + keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); - recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase); - + try { + recoveredKey = CryptoUtil.unwrapUsingPassphrase(wrappedRecoveredKey, recoveryPassphrase); + } catch (Exception e) { + log("Error: unable to unwrap key using passphrase"); + e.printStackTrace(); + } if (recoveredKey == null || !recoveredKey.equals(com.netscape.osutil.OSUtil.BtoA(vek.getEncoded()))) { log("Error: recovered and archived keys do not match!"); @@ -343,7 +321,8 @@ public class DRMTest { // Test 12: Generate and archive a passphrase clientId = "UUID: 123-45-6789 RKEK " + Calendar.getInstance().getTime().toString(); try { - byte[] encoded = createPKIArchiveOptions(manager, token, transportCert, null, passphrase, kg1, ivSpec); + byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, null, passphrase, + KeyGenAlgorithm.DES3, ivps); requestInfo = client.archiveSecurityData(encoded, clientId, KeyRequestResource.PASS_PHRASE_TYPE); log("Archival Results:"); printRequestInfo(requestInfo); @@ -375,10 +354,11 @@ public class DRMTest { recoveryRequestId = null; wrappedRecoveryKey = null; try { - recoveryKey = kg1.generate(); - wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey); - wrappedRecoveryPassphrase = wrapPassphrase(token, recoveryPassphrase, ivSpec, recoveryKey); - requestInfo = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivSpec.getIV()); + recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3); + wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey); + wrappedRecoveryPassphrase = CryptoUtil.wrapPassphrase(token, recoveryPassphrase, ivps, recoveryKey, + EncryptionAlgorithm.DES3_CBC_PAD); + requestInfo = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivps.getIV()); recoveryRequestId = getId(requestInfo.getRequestURL()); } catch (Exception e) { log("Exception in recovering passphrase using session key: " + e.getMessage()); @@ -391,11 +371,13 @@ public class DRMTest { // Test 16: Get key log("Getting passphrase: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivSpec.getIV()); + keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivps.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); - ivSpecServer = new IVParameterSpec( com.netscape.osutil.OSUtil.AtoB(keyData.getNonceData())); + ivps_server = new IVParameterSpec( com.netscape.osutil.OSUtil.AtoB(keyData.getNonceData())); try { - recoveredKey = unwrap(token, ivSpecServer, com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey), recoveryKey); + recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server, + com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey), + recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD); recoveredKey = new String(com.netscape.osutil.OSUtil.AtoB(recoveredKey), "UTF-8"); } catch (Exception e) { log("Exception in unwrapping key: " + e.toString()); @@ -410,7 +392,7 @@ public class DRMTest { // Test 17: Submit a recovery request for the passphrase using a passphrase log("Submitting a recovery request for the passphrase using a passphrase"); - requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); + requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV()); recoveryRequestId = getId(requestInfo.getRequestURL()); //Test 18: Approve recovery @@ -419,13 +401,14 @@ public class DRMTest { // Test 19: Get key log("Getting passphrase: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); + keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); - recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase); try { + recoveredKey = CryptoUtil.unwrapUsingPassphrase(wrappedRecoveredKey, recoveryPassphrase); recoveredKey = new String(com.netscape.osutil.OSUtil.AtoB(recoveredKey), "UTF-8"); } catch (Exception e) { - log("Error: Can't convert recovered passphrase from binary to ascii!"); + log("Error: cannot unwrap key using passphrase"); + e.printStackTrace(); } if (recoveredKey == null || !recoveredKey.equals(passphrase)) { @@ -447,13 +430,14 @@ public class DRMTest { // Test 22: Get key log("Getting passphrase: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); + keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivps.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); - recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase); try { + recoveredKey = CryptoUtil.unwrapUsingPassphrase(wrappedRecoveredKey, recoveryPassphrase); recoveredKey = new String(com.netscape.osutil.OSUtil.AtoB(recoveredKey), "UTF-8"); } catch (Exception e) { - log("Error: Can't convert recovered passphrase from binary to ascii!"); + log("Error: Can't unwrap recovered key using passphrase"); + e.printStackTrace(); } if (recoveredKey == null || !recoveredKey.equals(passphrase)) { @@ -463,145 +447,15 @@ public class DRMTest { } } - private static String unwrap(String wrappedRecoveredKey, String recoveryPassphrase) { - - EncryptedContentInfo cInfo = null; - String unwrappedData = null; - - //We have to do this to get the decoding to work. - PBEAlgorithm pbeAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC; - - log("pbeAlg: " + pbeAlg); - try { - Password pass = new Password(recoveryPassphrase.toCharArray()); - PasswordConverter passConverter = new - PasswordConverter(); - - byte[] encoded = com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey); - - ByteArrayInputStream inStream = new ByteArrayInputStream(encoded); - cInfo = (EncryptedContentInfo) - new EncryptedContentInfo.Template().decode(inStream); - - byte[] decodedData = cInfo.decrypt(pass, passConverter); - - unwrappedData = com.netscape.osutil.OSUtil.BtoA(decodedData); - - } catch (Exception e) { - log("Problem unwraping PBE wrapped datat! " + e.toString()); - - } - - return unwrappedData; - } - private static void log(String string) { // TODO Auto-generated method stub System.out.println(string); } - private static String unwrap(CryptoToken token, IVParameterSpec IV, byte[] wrappedRecoveredKey, - SymmetricKey recoveryKey) throws NoSuchAlgorithmException, TokenException, BadPaddingException, - IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException { - - Cipher decryptor = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); - decryptor.initDecrypt(recoveryKey, IV); - byte[] unwrappedData = decryptor.doFinal(wrappedRecoveredKey); - String unwrappedS = com.netscape.osutil.OSUtil.BtoA( unwrappedData); - - return unwrappedS; - } - private static String getId(String link) { return link.substring(link.lastIndexOf("/") + 1); } - private static byte[] createPKIArchiveOptions(CryptoManager manager, CryptoToken token, String transportCert, - SymmetricKey vek, String passphrase, KeyGenerator kg1, IVParameterSpec IV) throws TokenException, CharConversionException, - NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, - CertificateEncodingException, IOException, IllegalStateException, IllegalBlockSizeException, - BadPaddingException { - byte[] key_data = null; - - //generate session key - SymmetricKey sk = kg1.generate(); - - if (passphrase != null) { - key_data = wrapPassphrase(token, passphrase, IV, sk); - } else { - // wrap payload using session key - KeyWrapper wrapper1 = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); - wrapper1.initWrap(sk, IV); - key_data = wrapper1.wrap(vek); - } - - // wrap session key using transport key - byte[] session_data = wrapSymmetricKey(manager, token, transportCert, sk); - - // create PKIArchiveOptions structure - AlgorithmIdentifier algS = new AlgorithmIdentifier(new OBJECT_IDENTIFIER("1.2.840.113549.3.7"), - new OCTET_STRING(IV.getIV())); - EncryptedValue encValue = new EncryptedValue(null, algS, new BIT_STRING(session_data, 0), null, null, - new BIT_STRING(key_data, 0)); - EncryptedKey key = new EncryptedKey(encValue); - PKIArchiveOptions opt = new PKIArchiveOptions(key); - - byte[] encoded = null; - - try { - - //Let's make sure we can decode the encoded PKIArchiveOptions.. - ByteArrayOutputStream oStream = new ByteArrayOutputStream(); - - opt.encode(oStream); - - encoded = oStream.toByteArray(); - ByteArrayInputStream inStream = new ByteArrayInputStream( encoded); - PKIArchiveOptions options = (PKIArchiveOptions) - new PKIArchiveOptions.Template().decode(inStream); - log("Decoded PKIArchiveOptions: " + options); - } catch (IOException e) { - log("Problem with PKIArchiveOptions: " + e.toString()); - return null; - - } catch (InvalidBERException e) { - log("Problem with PKIArchiveOptions: " + e.toString()); - return null; - } - - return encoded; - } - - private static byte[] wrapPassphrase(CryptoToken token, String passphrase, IVParameterSpec IV, SymmetricKey sk) - throws NoSuchAlgorithmException, TokenException, InvalidKeyException, - InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException { - byte[] wrappedPassphrase = null; - Cipher encryptor = null; - - encryptor = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); - log("cipher " + encryptor); - - if (encryptor != null) { - encryptor.initEncrypt(sk, IV); - wrappedPassphrase = encryptor.doFinal(passphrase.getBytes("UTF-8")); - } else { - throw new IOException("Failed to create cipher"); - } - - return wrappedPassphrase; - } - - private static byte[] wrapSymmetricKey(CryptoManager manager, CryptoToken token, String transportCert, - SymmetricKey sk) throws CertificateEncodingException, TokenException, NoSuchAlgorithmException, - InvalidKeyException, InvalidAlgorithmParameterException { - byte transport[] = com.netscape.osutil.OSUtil.AtoB(transportCert); - X509Certificate tcert = manager.importCACertPackage(transport); - KeyWrapper rsaWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA); - rsaWrap.initWrap(tcert.getPublicKey(), null); - byte session_data[] = rsaWrap.wrap(sk); - return session_data; - } - private static void printRequestInfo(KeyRequestInfo info) { log("KeyRequestURL: " + info.getRequestURL()); log("Key URL: " + info.getKeyURL()); diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java new file mode 100644 index 000000000..0cfc685f3 --- /dev/null +++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java @@ -0,0 +1,222 @@ +package com.netscape.cms.servlet.test; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.CharConversionException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateEncodingException; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.asn1.InvalidBERException; +import org.mozilla.jss.crypto.AlreadyInitializedException; +import org.mozilla.jss.crypto.BadPaddingException; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.IVParameterSpec; +import org.mozilla.jss.crypto.IllegalBlockSizeException; +import org.mozilla.jss.crypto.KeyGenAlgorithm; +import org.mozilla.jss.crypto.SymmetricKey; +import org.mozilla.jss.crypto.SymmetricKey.NotExtractableException; +import org.mozilla.jss.crypto.TokenException; +import org.mozilla.jss.util.Password; + +import com.netscape.cmsutil.crypto.CryptoUtil; +import com.netscape.osutil.OSUtil; + +@SuppressWarnings("deprecation") +public class GeneratePKIArchiveOptions { + + public static void usage(Options options) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("GeneratePKIArchiveOptions", options); + System.exit(1); + } + + private static void log(String string) { + // TODO Auto-generated method stub + System.out.println(string); + } + + // read in byte array + // we must do this somewhere? + public static byte[] read(String fname) throws IOException { + File file = new File(fname); + byte[] result = new byte[(int) file.length()]; + try { + InputStream input = null; + try { + int totalBytesRead = 0; + input = new BufferedInputStream(new FileInputStream(file)); + while (totalBytesRead < result.length) { + int bytesRemaining = result.length - totalBytesRead; + //input.read() returns -1, 0, or more : + int bytesRead = input.read(result, totalBytesRead, bytesRemaining); + if (bytesRead > 0) { + totalBytesRead = totalBytesRead + bytesRead; + } + } + } finally { + input.close(); + } + } catch (Exception e) { + throw new IOException(e); + } + + return result; + } + + public static void write(byte[] aInput, String outFile) throws IOException { + try { + OutputStream output = null; + try { + output = new BufferedOutputStream(new FileOutputStream(outFile)); + output.write(aInput); + } finally { + output.close(); + } + } catch (Exception e) { + throw new IOException(e); + } + } + + private static void write_file(String data, String outFile) throws IOException { + FileWriter fstream = new FileWriter(outFile); + BufferedWriter out = new BufferedWriter(fstream); + out.write(data); + //Close the output stream + out.close(); + } + + public static void main(String args[]) throws InvalidKeyException, CertificateEncodingException, + CharConversionException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, + IllegalStateException, TokenException, IOException, IllegalBlockSizeException, BadPaddingException, + InvalidBERException, NotExtractableException { + String token_pwd = null; + String db_dir = "./"; + String out_file = "./options.out"; + String transport_file = "./transport.crt"; + String key_file = "./symkey.out"; + String passphrase = null; + boolean passphraseMode = false; + + // parse command line arguments + Options options = new Options(); + options.addOption("w", true, "Token password (required)"); + options.addOption("d", true, "Directory for tokendb"); + options.addOption("p", true, "Passphrase"); + options.addOption("t", true, "File with transport cert"); + options.addOption("o", true, "Output file"); + options.addOption("k", true, "Key file"); + + try { + CommandLineParser parser = new PosixParser(); + CommandLine cmd = parser.parse(options, args); + + if (cmd.hasOption("p")) { + passphrase = cmd.getOptionValue("p"); + passphraseMode = true; + } + + if (cmd.hasOption("o")) { + out_file = cmd.getOptionValue("o"); + } + + if (cmd.hasOption("k")) { + key_file = cmd.getOptionValue("k"); + } + + if (cmd.hasOption("t")) { + transport_file = cmd.getOptionValue("t"); + } + + if (cmd.hasOption("w")) { + token_pwd = cmd.getOptionValue("w"); + } else { + System.err.println("Error: no token password provided"); + usage(options); + } + + if (cmd.hasOption("d")) { + db_dir = cmd.getOptionValue("d"); + } + + } catch (ParseException e) { + System.err.println("Error in parsing command line options: " + e.getMessage()); + usage(options); + } + + // used for crypto operations + byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec ivps = new IVParameterSpec(iv); + CryptoManager manager = null; + CryptoToken token = null; + + // used for wrapping to send data to DRM + byte[] tcert = read(transport_file); + String transportCert = com.netscape.osutil.OSUtil.BtoA(tcert); + + // Initialize token + try { + CryptoManager.initialize(db_dir); + } catch (AlreadyInitializedException e) { + // it is ok if it is already initialized + } catch (Exception e) { + log("INITIALIZATION ERROR: " + e.toString()); + System.exit(1); + } + + // log into token + try { + manager = CryptoManager.getInstance(); + token = manager.getInternalKeyStorageToken(); + Password password = new Password(token_pwd.toCharArray()); + try { + token.login(password); + } catch (Exception e) { + log("login Exception: " + e.toString()); + if (!token.isLoggedIn()) { + token.initPassword(password, password); + } + } + } catch (Exception e) { + log("Exception in logging into token:" + e.toString()); + } + + // Data to be archived + SymmetricKey vek = null; + if (!passphraseMode) { + vek = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3); + // store vek in file + write_file(OSUtil.BtoA(vek.getKeyData()), key_file); + } + + byte[] encoded = null; + + if (passphraseMode) { + encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, null, passphrase, + KeyGenAlgorithm.DES3, ivps); + } else { + encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, vek, null, + KeyGenAlgorithm.DES3, ivps); + } + + // write encoded to file + write_file(OSUtil.BtoA(encoded), out_file); + + } +} diff --git a/pki/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/pki/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java index cad7d0ae3..38b405673 100644 --- a/pki/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java +++ b/pki/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java @@ -24,6 +24,7 @@ import java.io.FilterOutputStream; import java.io.IOException; import java.io.PrintStream; import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; @@ -64,35 +65,53 @@ import netscape.security.x509.X509CertInfo; import netscape.security.x509.X509Key; import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.CryptoManager.NotInitializedException; import org.mozilla.jss.NoSuchTokenException; import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; +import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.crypto.Algorithm; +import org.mozilla.jss.crypto.BadPaddingException; +import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.EncryptionAlgorithm; +import org.mozilla.jss.crypto.IVParameterSpec; +import org.mozilla.jss.crypto.IllegalBlockSizeException; import org.mozilla.jss.crypto.InternalCertificate; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; +import org.mozilla.jss.crypto.KeyWrapAlgorithm; +import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.NoSuchItemOnTokenException; import org.mozilla.jss.crypto.ObjectNotFoundException; +import org.mozilla.jss.crypto.PBEAlgorithm; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.pkcs12.PasswordConverter; +import org.mozilla.jss.pkcs7.EncryptedContentInfo; import org.mozilla.jss.pkix.crmf.CertReqMsg; import org.mozilla.jss.pkix.crmf.CertRequest; import org.mozilla.jss.pkix.crmf.CertTemplate; +import org.mozilla.jss.pkix.crmf.EncryptedKey; +import org.mozilla.jss.pkix.crmf.EncryptedValue; +import org.mozilla.jss.pkix.crmf.PKIArchiveOptions; +import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; import org.mozilla.jss.pkix.primitive.Name; import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.util.Base64OutputStream; +import org.mozilla.jss.util.Password; import com.netscape.cmsutil.util.Cert; import com.netscape.osutil.OSUtil; @@ -1128,6 +1147,130 @@ public class CryptoUtil { return certs; } + + @SuppressWarnings("deprecation") + public static String unwrapUsingPassphrase(String wrappedRecoveredKey, String recoveryPassphrase) + throws IOException, InvalidBERException, InvalidKeyException, IllegalStateException, + NoSuchAlgorithmException, InvalidAlgorithmParameterException, NotInitializedException, TokenException, + IllegalBlockSizeException, BadPaddingException { + EncryptedContentInfo cInfo = null; + String unwrappedData = null; + + //We have to do this to get the decoding to work. + @SuppressWarnings("unused") + PBEAlgorithm pbeAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC; + + Password pass = new Password(recoveryPassphrase.toCharArray()); + PasswordConverter passConverter = new + PasswordConverter(); + + byte[] encoded = com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey); + + ByteArrayInputStream inStream = new ByteArrayInputStream(encoded); + cInfo = (EncryptedContentInfo) + new EncryptedContentInfo.Template().decode(inStream); + + byte[] decodedData = cInfo.decrypt(pass, passConverter); + + unwrappedData = com.netscape.osutil.OSUtil.BtoA(decodedData); + + return unwrappedData; + } + + @SuppressWarnings("deprecation") + public static String unwrapUsingSymmetricKey(CryptoToken token, IVParameterSpec IV, byte[] wrappedRecoveredKey, + SymmetricKey recoveryKey, EncryptionAlgorithm alg) throws NoSuchAlgorithmException, TokenException, + BadPaddingException, + IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException { + + Cipher decryptor = token.getCipherContext(alg); + decryptor.initDecrypt(recoveryKey, IV); + byte[] unwrappedData = decryptor.doFinal(wrappedRecoveredKey); + String unwrappedS = com.netscape.osutil.OSUtil.BtoA(unwrappedData); + + return unwrappedS; + } + + @SuppressWarnings("deprecation") + public static byte[] wrapPassphrase(CryptoToken token, String passphrase, IVParameterSpec IV, SymmetricKey sk, + EncryptionAlgorithm alg) + throws NoSuchAlgorithmException, TokenException, InvalidKeyException, + InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException { + byte[] wrappedPassphrase = null; + Cipher encryptor = null; + + encryptor = token.getCipherContext(alg); + + if (encryptor != null) { + encryptor.initEncrypt(sk, IV); + wrappedPassphrase = encryptor.doFinal(passphrase.getBytes("UTF-8")); + } else { + throw new IOException("Failed to create cipher"); + } + + return wrappedPassphrase; + } + + @SuppressWarnings("deprecation") + public static byte[] wrapSymmetricKey(CryptoManager manager, CryptoToken token, String transportCert, + SymmetricKey sk) throws CertificateEncodingException, TokenException, NoSuchAlgorithmException, + InvalidKeyException, InvalidAlgorithmParameterException { + byte transport[] = com.netscape.osutil.OSUtil.AtoB(transportCert); + X509Certificate tcert = manager.importCACertPackage(transport); + KeyWrapper rsaWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA); + rsaWrap.initWrap(tcert.getPublicKey(), null); + byte session_data[] = rsaWrap.wrap(sk); + return session_data; + } + + @SuppressWarnings("deprecation") + public static byte[] createPKIArchiveOptions(CryptoManager manager, CryptoToken token, String transportCert, + SymmetricKey vek, String passphrase, KeyGenAlgorithm keyGenAlg, IVParameterSpec IV) throws TokenException, + CharConversionException, + NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, + CertificateEncodingException, IOException, IllegalStateException, IllegalBlockSizeException, + BadPaddingException, InvalidBERException { + byte[] key_data = null; + + //generate session key + SymmetricKey sk = CryptoUtil.generateKey(token, keyGenAlg); + + if (passphrase != null) { + key_data = wrapPassphrase(token, passphrase, IV, sk, EncryptionAlgorithm.DES3_CBC_PAD); + } else { + // wrap payload using session key + KeyWrapper wrapper1 = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); + wrapper1.initWrap(sk, IV); + key_data = wrapper1.wrap(vek); + } + + // wrap session key using transport key + byte[] session_data = wrapSymmetricKey(manager, token, transportCert, sk); + + // create PKIArchiveOptions structure + AlgorithmIdentifier algS = new AlgorithmIdentifier(new OBJECT_IDENTIFIER("1.2.840.113549.3.7"), + new OCTET_STRING(IV.getIV())); + EncryptedValue encValue = new EncryptedValue(null, algS, new BIT_STRING(session_data, 0), null, null, + new BIT_STRING(key_data, 0)); + EncryptedKey key = new EncryptedKey(encValue); + PKIArchiveOptions opt = new PKIArchiveOptions(key); + + byte[] encoded = null; + + //Let's make sure we can decode the encoded PKIArchiveOptions.. + ByteArrayOutputStream oStream = new ByteArrayOutputStream(); + + opt.encode(oStream); + + encoded = oStream.toByteArray(); + ByteArrayInputStream inStream = new ByteArrayInputStream(encoded); + + @SuppressWarnings("unused") + PKIArchiveOptions options = (PKIArchiveOptions) + (new PKIArchiveOptions.Template()).decode(inStream); + + return encoded; + } } // START ENABLE_ECC |