diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c.old ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c
--- ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c.old 2011-09-23 10:14:24.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c 2011-09-22 18:39:15.000000000 -0700
@@ -111,6 +111,9 @@ JSS_AlgInfo JSS_AlgTable[NUM_ALGS] = {
/* 48 */ {SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, SEC_OID_TAG},
/* 49 */ {SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, SEC_OID_TAG},
/* 50 */ {SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, SEC_OID_TAG},
+/* 51 */ {SEC_OID_PKCS5_PBKDF2, SEC_OID_TAG},
+/* 52 */ {SEC_OID_PKCS5_PBES2, SEC_OID_TAG},
+/* 53 */ {SEC_OID_PKCS5_PBMAC1, SEC_OID_TAG},
/* REMEMBER TO UPDATE NUM_ALGS!!! */
};
diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h.old ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h
--- ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h.old 2011-09-23 10:14:08.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h 2011-09-22 20:31:12.000000000 -0700
@@ -56,7 +56,7 @@ typedef struct JSS_AlgInfoStr {
JSS_AlgType type;
} JSS_AlgInfo;
-#define NUM_ALGS 51
+#define NUM_ALGS 54
extern JSS_AlgInfo JSS_AlgTable[];
extern CK_ULONG JSS_symkeyUsage[];
diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java.old ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java
--- ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java.old 2011-09-23 10:14:42.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java 2011-09-22 18:39:15.000000000 -0700
@@ -233,5 +233,9 @@ public class Algorithm {
protected static final short SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE=48;
protected static final short SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE=49;
protected static final short SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST=50;
+ //PKCS5 V2
+ protected static final short SEC_OID_PKCS5_PBKDF2=51;
+ protected static final short SEC_OID_PKCS5_PBES2=52;
+ protected static final short SEC_OID_PKCS5_PBMAC1=53;
}
diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/PBEAlgorithm.java.old ./mozilla/security/jss/org/mozilla/jss/crypto/PBEAlgorithm.java
--- ./mozilla/security/jss/org/mozilla/jss/crypto/PBEAlgorithm.java.old 2011-09-23 10:15:04.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/crypto/PBEAlgorithm.java 2011-09-22 18:39:15.000000000 -0700
@@ -93,6 +93,27 @@ public class PBEAlgorithm extends KeyGen
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
+ // PKCS 5 v2
+ public static final PBEAlgorithm
+ PBE_PKCS5_PBKDF2 = new PBEAlgorithm(
+ SEC_OID_PKCS5_PBKDF2, "PBKDF2", 128,
+ PKCS5.subBranch(12), EncryptionAlgorithm.AES_128_CBC, 8 );
+
+ //////////////////////////////////////////////////////////////
+ // PKCS 5 v2
+ public static final PBEAlgorithm
+ PBE_PKCS5_PBES2 = new PBEAlgorithm(
+ SEC_OID_PKCS5_PBES2, "PBES2", 128,
+ PKCS5.subBranch(13), EncryptionAlgorithm.AES_128_CBC, 8 );
+
+ //////////////////////////////////////////////////////////////
+ // PKCS 5 v2
+ public static final PBEAlgorithm
+ PBE_PKCS5_PBMAC1 = new PBEAlgorithm(
+ SEC_OID_PKCS5_PBMAC1, "PBMAC1", 128,
+ PKCS5.subBranch(14), EncryptionAlgorithm.AES_128_CBC, 8 );
+
+ //////////////////////////////////////////////////////////////
public static final PBEAlgorithm
PBE_MD2_DES_CBC = new PBEAlgorithm(
SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC, "PBE/MD2/DES/CBC", 56,
diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c.old ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c
--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c.old 2011-09-23 10:12:09.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c 2011-09-27 10:35:19.000000000 -0700
@@ -324,7 +324,6 @@ Java_org_mozilla_jss_pkcs11_PK11KeyGener
}
/* print_secitem(pwitem); */
-
mech = JSS_getPK11MechFromAlg(env, alg);
if( mech == CKM_PBA_SHA1_WITH_SHA1_HMAC ) {
@@ -344,7 +343,14 @@ Java_org_mozilla_jss_pkcs11_PK11KeyGener
PR_ASSERT(oidTag != SEC_OID_UNKNOWN);
/* create algid */
- algid = PK11_CreatePBEAlgorithmID(oidTag, iterationCount, salt);
+ algid = PK11_CreatePBEV2AlgorithmID(
+ oidTag,
+ SEC_OID_DES_EDE3_CBC,
+ SEC_OID_HMAC_SHA1,
+ 168/8,
+ iterationCount,
+ salt);
+
if( algid == NULL ) {
JSS_throwMsg(env, TOKEN_EXCEPTION,
"Unable to process PBE parameters");
diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c.old ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c
--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c.old 2011-09-25 15:43:52.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c 2011-09-27 21:16:06.000000000 -0700
@@ -324,14 +324,34 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp
SECItem *wrapped=NULL, *iv=NULL, *param=NULL, *pubValue=NULL;
SECItem label; /* empty secitem, doesn't need to be freed */
PRBool token;
- CK_ATTRIBUTE_TYPE attribs[4];
- int numAttribs;
+ CK_ATTRIBUTE_TYPE attribs[4] = {0, 0, 0, 0};
+ int numAttribs = 0;
+ CK_TOKEN_INFO tokenInfo;
+
+ PRBool isSensitive = PR_TRUE;
+ PRBool isExtractable = PR_FALSE;
+ /* special case nethsm*/
+ CK_UTF8CHAR nethsmLabel[4] = {'N','H','S','M'};
+ PRBool isNethsm = PR_TRUE;
if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) {
/* exception was thrown */
goto finish;
}
+ if ( PK11_GetTokenInfo(slot, &tokenInfo) == PR_SUCCESS) {
+ int ix = 0;
+ for(ix=0; ix < 4; ix++) {
+ if (tokenInfo.label[ix] != nethsmLabel[ix]) {
+ isNethsm = PR_FALSE;
+ break;
+ }
+ }
+
+ } else {
+ isNethsm = PR_FALSE;
+ }
+
/* get unwrapping key */
if( JSS_PK11_getSymKeyPtr(env, unwrapperObj, &unwrappingKey)
!= PR_SUCCESS) {
@@ -392,14 +412,24 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp
}
keyType = PK11_GetKeyType(keyTypeMech, 0);
+ if( isNethsm ) {
+ isSensitive = PR_FALSE;
+ isExtractable = PR_FALSE;
+ }
+
+setAttrs:
/* figure out which operations to enable for this key */
switch (keyType) {
case CKK_RSA:
attribs[0] = CKA_SIGN;
- attribs[1] = CKA_DECRYPT;
- attribs[2] = CKA_SIGN_RECOVER;
- attribs[3] = CKA_UNWRAP;
- numAttribs = 4;
+ attribs[1] = CKA_SIGN_RECOVER;
+ attribs[2] = CKA_UNWRAP;
+ if (isExtractable) {
+ attribs[3] = CKA_EXTRACTABLE;
+ numAttribs = 4;
+ } else {
+ numAttribs = 3;
+ }
break;
case CKK_DSA:
attribs[0] = CKA_SIGN;
@@ -426,7 +456,7 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp
/* perform the unwrap */
privk = PK11_UnwrapPrivKey(slot, unwrappingKey, wrapType, param, wrapped,
- &label, pubValue, token, PR_TRUE /*sensitive*/, keyType,
+ &label, pubValue, token, isSensitive /*sensitive*/, keyType,
attribs, numAttribs, NULL /*wincx*/);
if( privk == NULL ) {
JSS_throwMsg(env, TOKEN_EXCEPTION, "Key Unwrap failed on token");
diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java.old ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java
--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java.old 2011-09-27 15:16:52.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java 2011-09-27 17:01:18.000000000 -0700
@@ -190,21 +190,23 @@ final class PK11KeyWrapper implements Ke
if( key==null ) {
throw new InvalidKeyException("Key is null");
}
- if( ! key.getOwningToken().equals(token) ) {
- throw new InvalidKeyException("Key does not reside on the "+
- "current token");
- }
- if( ! (key instanceof PK11SymKey) ) {
- throw new InvalidKeyException("Key is not a PKCS #11 key");
- }
try {
+ if( ! key.getOwningToken().equals(token) ) {
+ throw new InvalidKeyException("Key does not reside on the current token: key owning token="+
+ key.getOwningToken().getName());
+ }
+ if( ! (key instanceof PK11SymKey) ) {
+ throw new InvalidKeyException("Key is not a PKCS #11 key");
+ }
if( ((PK11SymKey)key).getKeyType() !=
- KeyType.getKeyTypeFromAlgorithm(algorithm) ) {
- throw new InvalidKeyException("Key is not the right type for"+
+ KeyType.getKeyTypeFromAlgorithm(algorithm) ) {
+ throw new InvalidKeyException("Key is not the right type for"+
" this algorithm");
}
} catch( NoSuchAlgorithmException e ) {
Assert.notReached("Unknown algorithm");
+ } catch (Exception e) {
+ Assert.notReached("Exception:"+ e.toString());
}
}
diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java.old ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java
--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java.old 2011-09-23 10:12:29.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java 2011-09-23 08:54:19.000000000 -0700
@@ -106,10 +106,13 @@ public final class PK11Token implements
getKeyGenerator(KeyGenAlgorithm algorithm)
throws NoSuchAlgorithmException, TokenException
{
+/* NSS is capable of finding the right token to do algorithm,
+ so this call is prematurely bailing
if( ! doesAlgorithm(algorithm) ) {
throw new NoSuchAlgorithmException(
algorithm+" is not supported by this token");
}
+*/
return new PK11KeyGenerator(this, algorithm);
}
diff -up ./mozilla/security/jss/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java.old ./mozilla/security/jss/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java
--- ./mozilla/security/jss/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java.old 2011-09-23 10:42:06.000000000 -0700
+++ ./mozilla/security/jss/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java 2011-09-27 14:31:41.000000000 -0700
@@ -43,6 +43,7 @@ import org.mozilla.jss.util.Assert;
import java.security.*;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.util.Password;
+import org.mozilla.jss.crypto.PrivateKey;
import java.security.spec.AlgorithmParameterSpec;
/**
@@ -184,6 +185,89 @@ public class EncryptedPrivateKeyInfo imp
return null;
}
+
+ /**
+ * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted
+ * with a password-based key-
+ * with wrapping/unwrapping happening on token.
+ *
+ * @param keyGenAlg The algorithm for generating a symmetric key from
+ * a password, salt, and iteration count.
+ * @param password The password to use in generating the key.
+ * @param salt The salt to use in generating the key.
+ * @param iterationCount The number of hashing iterations to perform
+ * while generating the key.
+ * @param charToByteConverter The mechanism for converting the characters
+ * in the password into bytes. If null, the default mechanism
+ * will be used, which is UTF8.
+ * @param pri The PrivateKey to be encrypted and stored in the
+ * EncryptedContentInfo.
+ */
+ public static EncryptedPrivateKeyInfo
+ createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt,
+ int iterationCount,
+ KeyGenerator.CharToByteConverter charToByteConverter,
+ PrivateKey pri, CryptoToken token)
+ throws CryptoManager.NotInitializedException, NoSuchAlgorithmException,
+ InvalidKeyException, InvalidAlgorithmParameterException, TokenException,
+ CharConversionException
+ {
+ try {
+
+ // check key gen algorithm
+
+ if( ! (keyGenAlg instanceof PBEAlgorithm) ) {
+ throw new NoSuchAlgorithmException("Key generation algorithm"+
+ " is not a PBE algorithm");
+ }
+
+ PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg;
+
+ // generate key
+
+ KeyGenerator kg = token.getKeyGenerator( keyGenAlg );
+ PBEKeyGenParams pbekgParams = new PBEKeyGenParams(
+ password, salt, iterationCount);
+ if( charToByteConverter != null ) {
+ kg.setCharToByteConverter( charToByteConverter );
+ }
+ kg.initialize(pbekgParams);
+ kg.temporaryKeys(true);
+ SymmetricKey key = kg.generate();
+
+ // generate IV
+ EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg();
+ AlgorithmParameterSpec params=null;
+ if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) {
+ params = new IVParameterSpec( kg.generatePBE_IV() );
+ }
+
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC);
+ wrapper.initWrap(key, params);
+ byte encrypted[] = wrapper.wrap(pri);
+
+ // make encryption algorithm identifier
+ PBEParameter pbeParam = new PBEParameter( salt, iterationCount );
+ AlgorithmIdentifier encAlgID = new AlgorithmIdentifier(
+ keyGenAlg.toOID(), pbeParam);
+
+ // create EncryptedPrivateKeyInfo
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo (
+ encAlgID,
+ new OCTET_STRING(encrypted) );
+
+ return epki;
+
+ } catch (Exception e) {
+ Assert.notReached("EncryptedPrivateKeyInfo exception:"
+ +".createPBE");
+ }
+
+ return null;
+ }
+
+
/**
* Decrypts an EncryptedPrivateKeyInfo that was encrypted with a PBE
* algorithm. The algorithm and its parameters are extracted from