summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2012-02-07 22:40:06 -0500
committerAde Lee <alee@redhat.com>2012-02-13 22:05:39 -0500
commit55b94ef9235a7973564676c0b2580b7b243076a8 (patch)
treef7bdd5fc7ae092410c0af4b1f161aae08dfa8c30
parent2f1ae9843d7239e970effa5e4692f3c4ab2eff6f (diff)
downloadpki-55b94ef9235a7973564676c0b2580b7b243076a8.tar.gz
pki-55b94ef9235a7973564676c0b2580b7b243076a8.tar.xz
pki-55b94ef9235a7973564676c0b2580b7b243076a8.zip
Moved client functions to CryptoUtil.java and added GenPKIArchiveOptions tool
-rw-r--r--pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java248
-rw-r--r--pki/base/kra/functional/src/com/netscape/cms/servlet/test/GeneratePKIArchiveOptions.java222
-rw-r--r--pki/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java143
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