Blame SOURCES/jss-PBE-PKCS5-V2-secure-P12.patch

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