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