Blame SOURCES/jss-PBE-padded-block-cipher-enhancements.patch

762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504894163 25200
762105
#      Fri Sep 08 11:09:23 2017 -0700
762105
# Node ID 3629b598a9ce73e83c7896407e3ca820f6383750
762105
# Parent  eec15518fd61f1d988c25b4de589555796f9e65f
762105
Bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
  patch jss-ftweedal-0006-PBEKeyGenParams-allow-specifying-encryption-algorith.patch
762105
762105
Allow specifying an target encryption algorithm in PBEKeyGenParams;
762105
 if the PBE algorithm does not imply a particular cipher, this is needed
762105
 to determine the size of the key to generate
762105
762105
cfu for ftweedale
762105
762105
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/crypto/PBEKeyGenParams.java
762105
--- a/org/mozilla/jss/crypto/PBEKeyGenParams.java	Fri Sep 01 16:15:54 2017 -0700
762105
+++ b/org/mozilla/jss/crypto/PBEKeyGenParams.java	Fri Sep 08 11:09:23 2017 -0700
762105
@@ -13,6 +13,7 @@
762105
     private Password pass;
762105
     private byte[] salt;
762105
     private int iterations;
762105
+    private EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC;
762105
 
762105
     private PBEKeyGenParams() { }
762105
 
762105
@@ -40,7 +41,8 @@
762105
     }
762105
 
762105
     /**
762105
-     * Creates PBE parameters.
762105
+     * Creates PBE parameters using default encryption algorithm
762105
+     * (DES3_EDE3_CBC).
762105
      *
762105
      * @param pass The password. It will be cloned, so the
762105
      *      caller is still responsible for clearing it. It must not be null.
762105
@@ -60,6 +62,33 @@
762105
     }
762105
 
762105
     /**
762105
+     * Creates PBE parameters using default encryption algorithm
762105
+     * (DES3_EDE3_CBC).
762105
+     *
762105
+     * @param pass The password. It will be cloned, so the
762105
+     *      caller is still responsible for clearing it. It must not be null.
762105
+     * @param salt The salt for the PBE algorithm. Will not be cloned.
762105
+     *      Must not be null. It is the responsibility of the caller to
762105
+     *      use the right salt length for the algorithm. Most algorithms
762105
+     *      use 8 bytes of salt.
762105
+     * @param iterations The iteration count for the PBE algorithm.
762105
+     * @param encAlg The encryption algorithm.  This is used with SOME
762105
+     *      PBE algorithms for determining the KDF output length.
762105
+     */
762105
+    public PBEKeyGenParams(
762105
+            char[] pass, byte[] salt, int iterations,
762105
+            EncryptionAlgorithm encAlg) {
762105
+        if (pass == null || salt == null) {
762105
+            throw new NullPointerException();
762105
+        }
762105
+        this.pass = new Password((char[]) pass.clone());
762105
+        this.salt = salt;
762105
+        this.iterations = iterations;
762105
+        if (encAlg != null)
762105
+            this.encryptionAlgorithm = encAlg;
762105
+    }
762105
+
762105
+    /**
762105
      * Returns a reference to the password, not a copy.
762105
      */
762105
     public Password getPassword() {
762105
@@ -81,6 +110,14 @@
762105
     }
762105
 
762105
     /**
762105
+     * The encryption algorithm is used with SOME PBE algorithms for
762105
+     * determining the KDF output length.
762105
+     */
762105
+    public EncryptionAlgorithm getEncryptionAlgorithm() {
762105
+        return encryptionAlgorithm;
762105
+    }
762105
+
762105
+    /**
762105
      * Clears the password. This should be called when this object is no
762105
      * longer needed so the password is not left around in memory.
762105
      */
762105
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/pkcs11/PK11KeyGenerator.c
762105
--- a/org/mozilla/jss/pkcs11/PK11KeyGenerator.c	Fri Sep 01 16:15:54 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11KeyGenerator.c	Fri Sep 08 11:09:23 2017 -0700
762105
@@ -246,9 +246,9 @@
762105
  *
762105
  */
762105
 JNIEXPORT jobject JNICALL
762105
-Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE
762105
-    (JNIEnv *env, jclass clazz, jobject token, jobject alg, jbyteArray passBA,
762105
-    jbyteArray saltBA, jint iterationCount)
762105
+Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE(
762105
+    JNIEnv *env, jclass clazz, jobject token, jobject alg, jobject encAlg,
762105
+    jbyteArray passBA, jbyteArray saltBA, jint iterationCount)
762105
 {
762105
     PK11SlotInfo *slot=NULL;
762105
     PK11SymKey *skey=NULL;
762105
@@ -299,12 +299,15 @@
762105
         oidTag = JSS_getOidTagFromAlg(env, alg);
762105
         PR_ASSERT(oidTag != SEC_OID_UNKNOWN);
762105
 
762105
+        SECOidTag encAlgOidTag = JSS_getOidTagFromAlg(env, encAlg);
762105
+        PR_ASSERT(encAlgOidTag != SEC_OID_UNKNOWN);
762105
+
762105
         /* create algid */
762105
         algid = PK11_CreatePBEV2AlgorithmID(
762105
             oidTag,
762105
-            SEC_OID_DES_EDE3_CBC,
762105
+            encAlgOidTag,
762105
             SEC_OID_HMAC_SHA1,
762105
-            168/8,
762105
+            0,
762105
             iterationCount,
762105
             salt);
762105
 
762105
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/pkcs11/PK11KeyGenerator.java
762105
--- a/org/mozilla/jss/pkcs11/PK11KeyGenerator.java	Fri Sep 01 16:15:54 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11KeyGenerator.java	Fri Sep 08 11:09:23 2017 -0700
762105
@@ -178,8 +178,9 @@
762105
             byte[] pwbytes=null;
762105
             try {
762105
                 pwbytes = charToByte.convert( kgp.getPassword().getChars() );
762105
-                return generatePBE(token, algorithm, pwbytes,
762105
-                    kgp.getSalt(), kgp.getIterations());
762105
+                return generatePBE(
762105
+                    token, algorithm, kgp.getEncryptionAlgorithm(),
762105
+                    pwbytes, kgp.getSalt(), kgp.getIterations());
762105
             } finally {
762105
                 if( pwbytes!=null ) {
762105
                     Password.wipeBytes(pwbytes);
762105
@@ -296,7 +297,9 @@
762105
      *  be null.
762105
      */
762105
     private static native SymmetricKey
762105
-    generatePBE(PK11Token token, KeyGenAlgorithm algorithm, byte[] pass,
762105
-        byte[] salt, int iterationCount) throws TokenException;
762105
+    generatePBE(
762105
+        PK11Token token, KeyGenAlgorithm algorithm, EncryptionAlgorithm encAlg,
762105
+        byte[] pass, byte[] salt, int iterationCount)
762105
+        throws TokenException;
762105
 
762105
 }
762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504894529 25200
762105
#      Fri Sep 08 11:15:29 2017 -0700
762105
# Node ID bada1409d2bb67cd92c3b7c292b8bb4ae6388513
762105
# Parent  3629b598a9ce73e83c7896407e3ca820f6383750
762105
Bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
patch jss-ftweedal-0007-Support-the-CKK_GENERIC_SECRET-symmetric-key-type.patch
762105
Subject: Support the CKK_GENERIC_SECRET symmetric key type
762105
From: Fraser Tweedale <ftweedal@redhat.com>
762105
Content-Type: text/plain
762105
found patch at byte 873
762105
message:
762105
Support the CKK_GENERIC_SECRET symmetric key type
762105
The NSS PBKDF2 generation produces a key with the CKK_GENERIC_SECRET
762105
key type.  The underlying PKCS #11 object *does* record the intended
762105
encryption algorithm that was specified when generating the key via
762105
PK11_PBEKeyGen, but this information is not exposed via the PKCS #11
762105
interface.  When initialising a cipher, JSS checks the key type
762105
against the encryption algorithm and fails if they do not match,
762105
which is always the case with PBKDF2-derived keys.
762105
762105
To work around this problem, properly record the key type for
762105
CKK_GENERIC_SECRET keys, and update the cipher initialisation key
762105
type check to always accept such keys.
762105
762105
cfu for ftweedal
762105
762105
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/KeyType.java
762105
--- a/org/mozilla/jss/pkcs11/KeyType.java	Fri Sep 08 11:09:23 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/KeyType.java	Fri Sep 08 11:15:29 2017 -0700
762105
@@ -242,4 +242,7 @@
762105
                             "SHA1_HMAC"
762105
                         );
762105
 
762105
+    static public final KeyType GENERIC_SECRET =
762105
+        new KeyType(new Algorithm[] { }, "GENERIC_SECRET");
762105
+
762105
 }
762105
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/PK11Cipher.java
762105
--- a/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:09:23 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:15:29 2017 -0700
762105
@@ -243,8 +243,11 @@
762105
         }
762105
 
762105
         try {
762105
-            if( ((PK11SymKey)key).getKeyType() !=
762105
-                    KeyType.getKeyTypeFromAlgorithm(algorithm) ) {
762105
+            KeyType keyType = ((PK11SymKey) key).getKeyType();
762105
+            if (
762105
+                keyType != KeyType.GENERIC_SECRET
762105
+                && keyType != KeyType.getKeyTypeFromAlgorithm(algorithm)
762105
+            ) {
762105
                 throw new InvalidKeyException("Key is not the right type for"+
762105
                     " this algorithm: " + ((PK11SymKey)key).getKeyType() + ":" + KeyType.getKeyTypeFromAlgorithm(algorithm) +";");
762105
             }
762105
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/PK11SymKey.c
762105
--- a/org/mozilla/jss/pkcs11/PK11SymKey.c	Fri Sep 08 11:09:23 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11SymKey.c	Fri Sep 08 11:15:29 2017 -0700
762105
@@ -305,6 +305,9 @@
762105
           case CKK_DES2:
762105
              typeFieldName = DES3_KEYTYPE_FIELD;
762105
              break;
762105
+          case CKK_GENERIC_SECRET:
762105
+             typeFieldName = GENERIC_SECRET_KEYTYPE_FIELD;
762105
+             break;
762105
           default:
762105
             PR_ASSERT(PR_FALSE);
762105
             typeFieldName = DES_KEYTYPE_FIELD;
762105
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/util/java_ids.h
762105
--- a/org/mozilla/jss/util/java_ids.h	Fri Sep 08 11:09:23 2017 -0700
762105
+++ b/org/mozilla/jss/util/java_ids.h	Fri Sep 08 11:15:29 2017 -0700
762105
@@ -87,6 +87,7 @@
762105
 #define RC2_KEYTYPE_FIELD "RC2"
762105
 #define SHA1_HMAC_KEYTYPE_FIELD "SHA1_HMAC"
762105
 #define AES_KEYTYPE_FIELD "AES"
762105
+#define GENERIC_SECRET_KEYTYPE_FIELD "GENERIC_SECRET"
762105
 
762105
 /*
762105
  * NativeProxy
762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504894882 25200
762105
#      Fri Sep 08 11:21:22 2017 -0700
762105
# Node ID 890216599f21df4c6d07815604aaac526823a892
762105
# Parent  bada1409d2bb67cd92c3b7c292b8bb4ae6388513
762105
Bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
patch jss-ftweedal-0008-PK11Cipher-improve-error-reporting.patch
762105
Subject: PK11Cipher: improve error reporting
762105
From: Fraser Tweedale <ftweedal@redhat.com>
762105
message:
762105
PK11Cipher: improve error reporting
762105
762105
cfu for ftweedal
762105
762105
diff -r bada1409d2bb -r 890216599f21 org/mozilla/jss/pkcs11/PK11Cipher.c
762105
--- a/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:15:29 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:21:22 2017 -0700
762105
@@ -152,7 +152,9 @@
762105
     /* do the operation */
762105
     if( PK11_CipherOp(context, outbuf, (int*)&outlen, outlen,
762105
             (unsigned char*)inbuf, inlen) != SECSuccess) {
762105
-        JSS_throwMsg(env, TOKEN_EXCEPTION, "Cipher Operation failed");
762105
+        JSS_throwMsgPrErrArg(
762105
+            env, TOKEN_EXCEPTION, "Cipher context update failed",
762105
+            PR_GetError());
762105
         goto finish;
762105
     }
762105
     PR_ASSERT(outlen >= 0);
762105
@@ -209,7 +211,9 @@
762105
     /* perform the finalization */
762105
     status = PK11_DigestFinal(context, outBuf, &newOutLen, outLen);
762105
     if( (status != SECSuccess) ) {
762105
-        JSS_throwMsg(env, TOKEN_EXCEPTION, "Cipher operation failed on token");
762105
+        JSS_throwMsgPrErrArg(
762105
+            env, TOKEN_EXCEPTION, "Cipher context finalization failed",
762105
+            PR_GetError());
762105
         goto finish;
762105
     }
762105
 
762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504895552 25200
762105
#      Fri Sep 08 11:32:32 2017 -0700
762105
# Node ID d39e9b373798ea9d6ae7f35089b07143845b210e
762105
# Parent  890216599f21df4c6d07815604aaac526823a892
762105
Bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
patch jss-ftweedal-0009-Update-AES-CBC-PAD-cipher-definitions.patch
762105
Subject: Update AES-CBC-PAD cipher definitions
762105
From: Fraser Tweedale <ftweedal@redhat.com>
762105
message:
762105
Update AES-CBC-PAD cipher definitions
762105
The AES_{128,192,256}_CBC_PAD EncryptionAlgorithm definitions declare
762105
the correct PKCS #11 cipher mechanism and padding, but do not declare
762105
the relevant OIDs.  They are also unusable as target algorithms in
762105
PBE key generation because they declare a PK11_MECH instead of a
762105
SEC_OID_TAG.
762105
762105
Update these algorithms definitions to declare a SEC_OID_TAG instead
762105
of a PK11_MECH (JSS_getOidTagFromAlg() will still return the correct
762105
mechanism) and declare the associated OIDs.
762105
762105
cfu for ftweedal
762105
762105
diff -r 890216599f21 -r d39e9b373798 org/mozilla/jss/crypto/EncryptionAlgorithm.java
762105
--- a/org/mozilla/jss/crypto/EncryptionAlgorithm.java	Fri Sep 08 11:21:22 2017 -0700
762105
+++ b/org/mozilla/jss/crypto/EncryptionAlgorithm.java	Fri Sep 08 11:32:32 2017 -0700
762105
@@ -359,8 +359,10 @@
762105
         AES_ROOT_OID.subBranch(2), 128);
762105
 
762105
     public static final EncryptionAlgorithm
762105
-    AES_128_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
762105
-        Padding.PKCS5, IVParameterSpecClasses, 16, null, 128); // no oid
762105
+    AES_128_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_128_CBC,
762105
+        Alg.AES, Mode.CBC,
762105
+        Padding.PKCS5, IVParameterSpecClasses, 16,
762105
+        AES_ROOT_OID.subBranch(2), 128);
762105
     
762105
     public static final EncryptionAlgorithm
762105
     AES_192_ECB = new EncryptionAlgorithm(SEC_OID_AES_192_ECB,
762105
@@ -374,8 +376,10 @@
762105
         AES_ROOT_OID.subBranch(22), 192);
762105
     
762105
     public static final EncryptionAlgorithm
762105
-    AES_192_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
762105
-        Padding.PKCS5, IVParameterSpecClasses, 16, null, 192); // no oid
762105
+    AES_192_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_192_CBC,
762105
+        Alg.AES, Mode.CBC,
762105
+        Padding.PKCS5, IVParameterSpecClasses, 16,
762105
+        AES_ROOT_OID.subBranch(22), 192);
762105
 
762105
     public static final EncryptionAlgorithm
762105
     AES_256_ECB = new EncryptionAlgorithm(SEC_OID_AES_256_ECB,
762105
@@ -393,6 +397,9 @@
762105
         Padding.PKCS5, IVParameterSpecClasses, 16, null, 256); // no oid
762105
     
762105
     public static final EncryptionAlgorithm
762105
-    AES_256_CBC_PAD = AES_CBC_PAD;
762105
+    AES_256_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_256_CBC,
762105
+        Alg.AES, Mode.CBC,
762105
+        Padding.PKCS5, IVParameterSpecClasses, 16,
762105
+        AES_ROOT_OID.subBranch(42), 256);
762105
     
762105
 }
762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504896621 25200
762105
#      Fri Sep 08 11:50:21 2017 -0700
762105
# Node ID 0b8a6e84b6c736743f2184b2b858fda6be740544
762105
# Parent  d39e9b373798ea9d6ae7f35089b07143845b210e
762105
Bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
patch jss-ftweedal-0010-PK11Cipher-use-pad-mechanism-for-algorithms-that-use.patch
762105
Subject: PK11Cipher: use pad mechanism for algorithms that use padding
762105
From: Fraser Tweedale <ftweedal@redhat.com>
762105
message:
762105
PK11Cipher: use pad mechanism for algorithms that use padding
762105
The PK11Cipher implementation, when initialising a cipher context,
762105
uses JSS_getPK11MechFromAlg() to retrieve the PKCS #11 mechanism to
762105
use.  When a JSS EncryptionAlgorithm uses a SEC_OID_TAG, this will
762105
return the non-padded mechanism.  Then, if the size of the data is
762105
not a multiple of the cipher block size, a padding error occurs.
762105
762105
When the EncryptionAlgorithm indicates that padding is to be used,
762105
call PK11_GetPadMechanism() on the result of JSS_getPK11MechFromAlg()
762105
to get the padding variant of the mechanism.
762105
762105
cfu for ftweedal
762105
762105
diff -r d39e9b373798 -r 0b8a6e84b6c7 org/mozilla/jss/pkcs11/PK11Cipher.c
762105
--- a/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:32:32 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:50:21 2017 -0700
762105
@@ -24,16 +24,16 @@
762105
 JNIEXPORT jobject JNICALL
762105
 Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext
762105
     (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj,
762105
-        jobject algObj, jbyteArray ivBA)
762105
+        jobject algObj, jbyteArray ivBA, jboolean padded)
762105
 {
762105
     return Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits
762105
-        ( env, clazz, encrypt, keyObj, algObj, ivBA, 0);
762105
+        ( env, clazz, encrypt, keyObj, algObj, ivBA, 0, padded);
762105
 }
762105
 
762105
 JNIEXPORT jobject JNICALL
762105
 Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits
762105
     (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj,
762105
-        jobject algObj, jbyteArray ivBA, jint keyBits)
762105
+        jobject algObj, jbyteArray ivBA, jint keyBits, jboolean padded)
762105
 {
762105
     CK_MECHANISM_TYPE mech;
762105
     PK11SymKey *key=NULL;
762105
@@ -53,6 +53,9 @@
762105
         goto finish;
762105
     }
762105
 
762105
+    if (padded)
762105
+        mech = PK11_GetPadMechanism(mech);
762105
+
762105
     /* get operation type */
762105
     if( encrypt ) {
762105
         op = CKA_ENCRYPT;
762105
diff -r d39e9b373798 -r 0b8a6e84b6c7 org/mozilla/jss/pkcs11/PK11Cipher.java
762105
--- a/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:32:32 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:50:21 2017 -0700
762105
@@ -90,10 +90,13 @@
762105
         state = ENCRYPT;
762105
 
762105
         if( parameters instanceof RC2ParameterSpec ) {
762105
-            contextProxy = initContextWithKeyBits( true, key, algorithm, IV,
762105
-                ((RC2ParameterSpec)parameters).getEffectiveKeyBits() );
762105
+            contextProxy = initContextWithKeyBits(
762105
+                true, key, algorithm, IV,
762105
+                ((RC2ParameterSpec)parameters).getEffectiveKeyBits(),
762105
+                algorithm.isPadded());
762105
         } else {
762105
-            contextProxy = initContext( true, key, algorithm, IV );
762105
+            contextProxy = initContext(
762105
+                true, key, algorithm, IV, algorithm.isPadded());
762105
         }
762105
     }
762105
 
762105
@@ -112,10 +115,13 @@
762105
         state = DECRYPT;
762105
 
762105
         if( parameters instanceof RC2ParameterSpec ) {
762105
-            contextProxy = initContextWithKeyBits(false, key, algorithm, IV,
762105
-                ((RC2ParameterSpec)parameters).getEffectiveKeyBits() );
762105
+            contextProxy = initContextWithKeyBits(
762105
+                false, key, algorithm, IV,
762105
+                ((RC2ParameterSpec)parameters).getEffectiveKeyBits(),
762105
+                algorithm.isPadded());
762105
         } else {
762105
-            contextProxy = initContext(false, key, algorithm, IV);
762105
+            contextProxy = initContext(
762105
+                false, key, algorithm, IV, algorithm.isPadded());
762105
         }
762105
     }
762105
 
762105
@@ -182,13 +188,13 @@
762105
 
762105
     private static native CipherContextProxy
762105
     initContext(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg,
762105
-                 byte[] IV)
762105
+                 byte[] IV, boolean padded)
762105
         throws TokenException;
762105
 
762105
     // This version accepts the number of effective key bits for RC2 CBC.
762105
     private static native CipherContextProxy
762105
     initContextWithKeyBits(boolean encrypt, SymmetricKey key,
762105
-                EncryptionAlgorithm alg, byte[] IV, int keyBits)
762105
+                EncryptionAlgorithm alg, byte[] IV, int keyBits, boolean padded)
762105
         throws TokenException;
762105
 
762105
     private static native byte[]
762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504896816 25200
762105
#      Fri Sep 08 11:53:36 2017 -0700
762105
# Node ID b3b653faef8475ae03c670766429fd4dfab37a5e
762105
# Parent  0b8a6e84b6c736743f2184b2b858fda6be740544
762105
bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
patch jss-ftweedal-0012-2-Add-method-EncryptedPrivateKeyInfo.createPBES2.patch
762105
Subject: Add method EncryptedPrivateKeyInfo.createPBES2
762105
From: Fraser Tweedale <ftweedal@redhat.com>
762105
Content-Type: text/plain
762105
found patch at byte 404
762105
message:
762105
Add method EncryptedPrivateKeyInfo.createPBES2
762105
The createPBE method does not support PBES2 (it is necessary to know
762105
the desired encrypted algorithm to derive the key and build the
762105
parameters data).  Add the createPBES2 method, which uses PBKDF2 to
762105
derive the symmetric key and allows the caller to specify the
762105
encryption algorithm.
762105
762105
cfu for ftweedal
762105
762105
diff -r 0b8a6e84b6c7 -r b3b653faef84 org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java
762105
--- a/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java	Fri Sep 08 11:50:21 2017 -0700
762105
+++ b/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java	Fri Sep 08 11:53:36 2017 -0700
762105
@@ -155,6 +155,100 @@
762105
 
762105
 
762105
     /**
762105
+     * Export a private key in PBES2 format, using a random PBKDF2 salt.
762105
+     *
762105
+     * Token must support the CKM_PKCS5_PBKD2 mechanism.
762105
+     *
762105
+     * @param saltLen Length of salt in bytes (default: 16)
762105
+     * @param kdfIterations PBKDF2 iterations (default: 2000)
762105
+     * @param encAlg The symmetric encryption algorithm for enciphering the
762105
+     *               private key.  Determines the size of derived key.
762105
+     * @param pwd Password
762105
+     * @param charToByteConverter The mechanism for converting the characters
762105
+     *      in the password into bytes.  If null, the default mechanism
762105
+     *      will be used, which is UTF8.
762105
+     * @param privateKeyInfo The encoded PrivateKeyInfo to be encrypted and
762105
+     *                       stored in the EncryptedContentInfo.
762105
+     */
762105
+    public static EncryptedPrivateKeyInfo createPBES2(
762105
+            int saltLen,
762105
+            int kdfIterations,
762105
+            EncryptionAlgorithm encAlg,
762105
+            Password pwd,
762105
+            KeyGenerator.CharToByteConverter charToByteConverter,
762105
+            PrivateKeyInfo privateKeyInfo)
762105
+        throws CryptoManager.NotInitializedException, NoSuchAlgorithmException,
762105
+        InvalidKeyException, InvalidAlgorithmParameterException, TokenException,
762105
+        CharConversionException
762105
+    {
762105
+        if (encAlg == null)
762105
+            throw new IllegalArgumentException("encAlg cannot be null");
762105
+        if (pwd == null)
762105
+            throw new IllegalArgumentException("pwd cannot be null");
762105
+        if (privateKeyInfo == null)
762105
+            throw new IllegalArgumentException("privateKeyInfo cannot be null");
762105
+
762105
+        if (kdfIterations < 1)
762105
+            kdfIterations = 2000;
762105
+        if (saltLen < 1)
762105
+            saltLen = 16;
762105
+
762105
+        try {
762105
+            // generate random PBKDF2 salt
762105
+            SecureRandom random = new SecureRandom();
762105
+            byte salt[] = new byte[saltLen];
762105
+            random.nextBytes(salt);
762105
+
762105
+            // derive symmetric key from passphrase using PBKDF2
762105
+            CryptoManager cm = CryptoManager.getInstance();
762105
+            CryptoToken token = cm.getInternalCryptoToken();
762105
+            KeyGenerator kg = token.getKeyGenerator(
762105
+                PBEAlgorithm.PBE_PKCS5_PBKDF2);
762105
+            PBEKeyGenParams pbekgParams = new PBEKeyGenParams(
762105
+                pwd.getChars(), salt, kdfIterations, encAlg);
762105
+            if (charToByteConverter != null)
762105
+                kg.setCharToByteConverter(charToByteConverter);
762105
+            kg.initialize(pbekgParams);
762105
+            SymmetricKey sk = kg.generate();
762105
+
762105
+            // encrypt PrivateKeyInfo
762105
+            byte iv[] = new byte[encAlg.getBlockSize()];
762105
+            random.nextBytes(iv);
762105
+            Cipher cipher = token.getCipherContext(encAlg);
762105
+            cipher.initEncrypt(sk, new IVParameterSpec(iv));
762105
+            byte[] encData = cipher.doFinal(ASN1Util.encode(privateKeyInfo));
762105
+
762105
+            // construct KDF AlgorithmIdentifier
762105
+            SEQUENCE paramsKdf = new SEQUENCE();
762105
+            paramsKdf.addElement(new OCTET_STRING(salt));
762105
+            paramsKdf.addElement(new INTEGER((long) kdfIterations));
762105
+            paramsKdf.addElement(new INTEGER((long) sk.getLength()));
762105
+            AlgorithmIdentifier algIdKdf = new AlgorithmIdentifier(
762105
+                PBEAlgorithm.PBE_PKCS5_PBKDF2.toOID(), paramsKdf);
762105
+
762105
+            // construct encryption AlgorithmIdentifier
762105
+            AlgorithmIdentifier algIdEnc = new AlgorithmIdentifier(
762105
+                encAlg.toOID(), new OCTET_STRING(iv));
762105
+
762105
+            // construct "composite" PBES2 AlgorithmIdentifier
762105
+            SEQUENCE paramsPBES2 = new SEQUENCE();
762105
+            paramsPBES2.addElement(algIdKdf);
762105
+            paramsPBES2.addElement(algIdEnc);
762105
+            AlgorithmIdentifier algIdPBES2 = new AlgorithmIdentifier(
762105
+                PBEAlgorithm.PBE_PKCS5_PBES2.toOID(), paramsPBES2);
762105
+
762105
+            // construct EncryptedPrivateKeyInfo
762105
+            return new EncryptedPrivateKeyInfo(algIdPBES2, new OCTET_STRING(encData));
762105
+        } catch (IllegalBlockSizeException e) {
762105
+            Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo.createPBES2");
762105
+        } catch (BadPaddingException e) {
762105
+            Assert.notReached("BadPaddingException in EncryptedContentInfo.createPBES2");
762105
+        }
762105
+        return null; // unreachable
762105
+    }
762105
+
762105
+
762105
+    /**
762105
      * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted
762105
      * with a password-based key- 
762105
      *       with wrapping/unwrapping happening on token.
762105
# HG changeset patch
762105
# User Fraser Tweedale<ftweedale@redhat.com>
762105
# Date 1504896964 25200
762105
#      Fri Sep 08 11:56:04 2017 -0700
762105
# Node ID 87dca07f7529463398734d1279bcfd7023a43d4c
762105
# Parent  b3b653faef8475ae03c670766429fd4dfab37a5e
762105
Bug 1370778 PBE and padded block cipher enhancements and fixes -
762105
patch  jss-ftweedal-0013-Improve-error-reporting.patch
762105
Subject: Improve error reporting
762105
From: Fraser Tweedale <ftweedal@redhat.com>
762105
Content-Type: text/plain
762105
found patch at byte 157
762105
message:
762105
Improve error reporting
762105
762105
cfu for ftweedal
762105
762105
diff -r b3b653faef84 -r 87dca07f7529 org/mozilla/jss/pkcs11/PK11KeyWrapper.c
762105
--- a/org/mozilla/jss/pkcs11/PK11KeyWrapper.c	Fri Sep 08 11:53:36 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11KeyWrapper.c	Fri Sep 08 11:56:04 2017 -0700
762105
@@ -251,9 +251,7 @@
762105
     status = PK11_WrapPrivKey(slot, wrapping, toBeWrapped, mech, param,
762105
                 &wrapped, NULL /* wincx */ );
762105
     if(status != SECSuccess) {
762105
-        char err[256] = {0};
762105
-        PR_snprintf(err, 256, "Wrapping operation failed on token:%d", PR_GetError());
762105
-        JSS_throwMsg(env, TOKEN_EXCEPTION, err);
762105
+        JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Wrapping operation failed on token");
762105
         goto finish;
762105
     }
762105
     PR_ASSERT(wrapped.len>0 && wrapped.data!=NULL);
762105
@@ -450,8 +448,8 @@
762105
                 attribs, numAttribs, NULL /*wincx*/);
762105
     if( privk == NULL ) {
762105
         char err[256] = {0};
762105
-        PR_snprintf(err, 256, "Key Unwrap failed on token:error=%d, keyType=%d", PR_GetError(), keyType);
762105
-        JSS_throwMsg(env, TOKEN_EXCEPTION, err);
762105
+        PR_snprintf(err, 256, "Key Unwrap failed on token; keyType=%d", keyType);
762105
+        JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, err);
762105
         goto finish;
762105
     }
762105
                 
762105
diff -r b3b653faef84 -r 87dca07f7529 org/mozilla/jss/pkcs11/PK11Store.c
762105
--- a/org/mozilla/jss/pkcs11/PK11Store.c	Fri Sep 08 11:53:36 2017 -0700
762105
+++ b/org/mozilla/jss/pkcs11/PK11Store.c	Fri Sep 08 11:56:04 2017 -0700
762105
@@ -734,7 +734,7 @@
762105
         PR_TRUE /* isperm */, PR_TRUE /* isprivate */,
762105
         pubKey->keyType, keyUsage, NULL /* wincx */);
762105
     if (result != SECSuccess) {
762105
-        JSS_throwMsg(
762105
+        JSS_throwMsgPrErr(
762105
             env, TOKEN_EXCEPTION,
762105
             "Failed to import EncryptedPrivateKeyInfo to token");
762105
         goto finish;