Blob Blame History Raw
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504894163 25200
#      Fri Sep 08 11:09:23 2017 -0700
# Node ID 3629b598a9ce73e83c7896407e3ca820f6383750
# Parent  eec15518fd61f1d988c25b4de589555796f9e65f
Bug 1370778 PBE and padded block cipher enhancements and fixes -
  patch jss-ftweedal-0006-PBEKeyGenParams-allow-specifying-encryption-algorith.patch

Allow specifying an target encryption algorithm in PBEKeyGenParams;
 if the PBE algorithm does not imply a particular cipher, this is needed
 to determine the size of the key to generate

cfu for ftweedale

diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/crypto/PBEKeyGenParams.java
--- a/org/mozilla/jss/crypto/PBEKeyGenParams.java	Fri Sep 01 16:15:54 2017 -0700
+++ b/org/mozilla/jss/crypto/PBEKeyGenParams.java	Fri Sep 08 11:09:23 2017 -0700
@@ -13,6 +13,7 @@
     private Password pass;
     private byte[] salt;
     private int iterations;
+    private EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC;
 
     private PBEKeyGenParams() { }
 
@@ -40,7 +41,8 @@
     }
 
     /**
-     * Creates PBE parameters.
+     * Creates PBE parameters using default encryption algorithm
+     * (DES3_EDE3_CBC).
      *
      * @param pass The password. It will be cloned, so the
      *      caller is still responsible for clearing it. It must not be null.
@@ -60,6 +62,33 @@
     }
 
     /**
+     * Creates PBE parameters using default encryption algorithm
+     * (DES3_EDE3_CBC).
+     *
+     * @param pass The password. It will be cloned, so the
+     *      caller is still responsible for clearing it. It must not be null.
+     * @param salt The salt for the PBE algorithm. Will <b>not</b> be cloned.
+     *      Must not be null. It is the responsibility of the caller to
+     *      use the right salt length for the algorithm. Most algorithms
+     *      use 8 bytes of salt.
+     * @param iterations The iteration count for the PBE algorithm.
+     * @param encAlg The encryption algorithm.  This is used with SOME
+     *      PBE algorithms for determining the KDF output length.
+     */
+    public PBEKeyGenParams(
+            char[] pass, byte[] salt, int iterations,
+            EncryptionAlgorithm encAlg) {
+        if (pass == null || salt == null) {
+            throw new NullPointerException();
+        }
+        this.pass = new Password((char[]) pass.clone());
+        this.salt = salt;
+        this.iterations = iterations;
+        if (encAlg != null)
+            this.encryptionAlgorithm = encAlg;
+    }
+
+    /**
      * Returns a <b>reference</b> to the password, not a copy.
      */
     public Password getPassword() {
@@ -81,6 +110,14 @@
     }
 
     /**
+     * The encryption algorithm is used with SOME PBE algorithms for
+     * determining the KDF output length.
+     */
+    public EncryptionAlgorithm getEncryptionAlgorithm() {
+        return encryptionAlgorithm;
+    }
+
+    /**
      * Clears the password. This should be called when this object is no
      * longer needed so the password is not left around in memory.
      */
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/pkcs11/PK11KeyGenerator.c
--- a/org/mozilla/jss/pkcs11/PK11KeyGenerator.c	Fri Sep 01 16:15:54 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11KeyGenerator.c	Fri Sep 08 11:09:23 2017 -0700
@@ -246,9 +246,9 @@
  *
  */
 JNIEXPORT jobject JNICALL
-Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE
-    (JNIEnv *env, jclass clazz, jobject token, jobject alg, jbyteArray passBA,
-    jbyteArray saltBA, jint iterationCount)
+Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE(
+    JNIEnv *env, jclass clazz, jobject token, jobject alg, jobject encAlg,
+    jbyteArray passBA, jbyteArray saltBA, jint iterationCount)
 {
     PK11SlotInfo *slot=NULL;
     PK11SymKey *skey=NULL;
@@ -299,12 +299,15 @@
         oidTag = JSS_getOidTagFromAlg(env, alg);
         PR_ASSERT(oidTag != SEC_OID_UNKNOWN);
 
+        SECOidTag encAlgOidTag = JSS_getOidTagFromAlg(env, encAlg);
+        PR_ASSERT(encAlgOidTag != SEC_OID_UNKNOWN);
+
         /* create algid */
         algid = PK11_CreatePBEV2AlgorithmID(
             oidTag,
-            SEC_OID_DES_EDE3_CBC,
+            encAlgOidTag,
             SEC_OID_HMAC_SHA1,
-            168/8,
+            0,
             iterationCount,
             salt);
 
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/pkcs11/PK11KeyGenerator.java
--- a/org/mozilla/jss/pkcs11/PK11KeyGenerator.java	Fri Sep 01 16:15:54 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11KeyGenerator.java	Fri Sep 08 11:09:23 2017 -0700
@@ -178,8 +178,9 @@
             byte[] pwbytes=null;
             try {
                 pwbytes = charToByte.convert( kgp.getPassword().getChars() );
-                return generatePBE(token, algorithm, pwbytes,
-                    kgp.getSalt(), kgp.getIterations());
+                return generatePBE(
+                    token, algorithm, kgp.getEncryptionAlgorithm(),
+                    pwbytes, kgp.getSalt(), kgp.getIterations());
             } finally {
                 if( pwbytes!=null ) {
                     Password.wipeBytes(pwbytes);
@@ -296,7 +297,9 @@
      *  be null.
      */
     private static native SymmetricKey
-    generatePBE(PK11Token token, KeyGenAlgorithm algorithm, byte[] pass,
-        byte[] salt, int iterationCount) throws TokenException;
+    generatePBE(
+        PK11Token token, KeyGenAlgorithm algorithm, EncryptionAlgorithm encAlg,
+        byte[] pass, byte[] salt, int iterationCount)
+        throws TokenException;
 
 }
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504894529 25200
#      Fri Sep 08 11:15:29 2017 -0700
# Node ID bada1409d2bb67cd92c3b7c292b8bb4ae6388513
# Parent  3629b598a9ce73e83c7896407e3ca820f6383750
Bug 1370778 PBE and padded block cipher enhancements and fixes -
patch jss-ftweedal-0007-Support-the-CKK_GENERIC_SECRET-symmetric-key-type.patch
Subject: Support the CKK_GENERIC_SECRET symmetric key type
From: Fraser Tweedale <ftweedal@redhat.com>
Content-Type: text/plain
found patch at byte 873
message:
Support the CKK_GENERIC_SECRET symmetric key type
The NSS PBKDF2 generation produces a key with the CKK_GENERIC_SECRET
key type.  The underlying PKCS #11 object *does* record the intended
encryption algorithm that was specified when generating the key via
PK11_PBEKeyGen, but this information is not exposed via the PKCS #11
interface.  When initialising a cipher, JSS checks the key type
against the encryption algorithm and fails if they do not match,
which is always the case with PBKDF2-derived keys.

To work around this problem, properly record the key type for
CKK_GENERIC_SECRET keys, and update the cipher initialisation key
type check to always accept such keys.

cfu for ftweedal

diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/KeyType.java
--- a/org/mozilla/jss/pkcs11/KeyType.java	Fri Sep 08 11:09:23 2017 -0700
+++ b/org/mozilla/jss/pkcs11/KeyType.java	Fri Sep 08 11:15:29 2017 -0700
@@ -242,4 +242,7 @@
                             "SHA1_HMAC"
                         );
 
+    static public final KeyType GENERIC_SECRET =
+        new KeyType(new Algorithm[] { }, "GENERIC_SECRET");
+
 }
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/PK11Cipher.java
--- a/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:09:23 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:15:29 2017 -0700
@@ -243,8 +243,11 @@
         }
 
         try {
-            if( ((PK11SymKey)key).getKeyType() !=
-                    KeyType.getKeyTypeFromAlgorithm(algorithm) ) {
+            KeyType keyType = ((PK11SymKey) key).getKeyType();
+            if (
+                keyType != KeyType.GENERIC_SECRET
+                && keyType != KeyType.getKeyTypeFromAlgorithm(algorithm)
+            ) {
                 throw new InvalidKeyException("Key is not the right type for"+
                     " this algorithm: " + ((PK11SymKey)key).getKeyType() + ":" + KeyType.getKeyTypeFromAlgorithm(algorithm) +";");
             }
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/PK11SymKey.c
--- a/org/mozilla/jss/pkcs11/PK11SymKey.c	Fri Sep 08 11:09:23 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11SymKey.c	Fri Sep 08 11:15:29 2017 -0700
@@ -305,6 +305,9 @@
           case CKK_DES2:
              typeFieldName = DES3_KEYTYPE_FIELD;
              break;
+          case CKK_GENERIC_SECRET:
+             typeFieldName = GENERIC_SECRET_KEYTYPE_FIELD;
+             break;
           default:
             PR_ASSERT(PR_FALSE);
             typeFieldName = DES_KEYTYPE_FIELD;
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/util/java_ids.h
--- a/org/mozilla/jss/util/java_ids.h	Fri Sep 08 11:09:23 2017 -0700
+++ b/org/mozilla/jss/util/java_ids.h	Fri Sep 08 11:15:29 2017 -0700
@@ -87,6 +87,7 @@
 #define RC2_KEYTYPE_FIELD "RC2"
 #define SHA1_HMAC_KEYTYPE_FIELD "SHA1_HMAC"
 #define AES_KEYTYPE_FIELD "AES"
+#define GENERIC_SECRET_KEYTYPE_FIELD "GENERIC_SECRET"
 
 /*
  * NativeProxy
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504894882 25200
#      Fri Sep 08 11:21:22 2017 -0700
# Node ID 890216599f21df4c6d07815604aaac526823a892
# Parent  bada1409d2bb67cd92c3b7c292b8bb4ae6388513
Bug 1370778 PBE and padded block cipher enhancements and fixes -
patch jss-ftweedal-0008-PK11Cipher-improve-error-reporting.patch
Subject: PK11Cipher: improve error reporting
From: Fraser Tweedale <ftweedal@redhat.com>
message:
PK11Cipher: improve error reporting

cfu for ftweedal

diff -r bada1409d2bb -r 890216599f21 org/mozilla/jss/pkcs11/PK11Cipher.c
--- a/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:15:29 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:21:22 2017 -0700
@@ -152,7 +152,9 @@
     /* do the operation */
     if( PK11_CipherOp(context, outbuf, (int*)&outlen, outlen,
             (unsigned char*)inbuf, inlen) != SECSuccess) {
-        JSS_throwMsg(env, TOKEN_EXCEPTION, "Cipher Operation failed");
+        JSS_throwMsgPrErrArg(
+            env, TOKEN_EXCEPTION, "Cipher context update failed",
+            PR_GetError());
         goto finish;
     }
     PR_ASSERT(outlen >= 0);
@@ -209,7 +211,9 @@
     /* perform the finalization */
     status = PK11_DigestFinal(context, outBuf, &newOutLen, outLen);
     if( (status != SECSuccess) ) {
-        JSS_throwMsg(env, TOKEN_EXCEPTION, "Cipher operation failed on token");
+        JSS_throwMsgPrErrArg(
+            env, TOKEN_EXCEPTION, "Cipher context finalization failed",
+            PR_GetError());
         goto finish;
     }
 
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504895552 25200
#      Fri Sep 08 11:32:32 2017 -0700
# Node ID d39e9b373798ea9d6ae7f35089b07143845b210e
# Parent  890216599f21df4c6d07815604aaac526823a892
Bug 1370778 PBE and padded block cipher enhancements and fixes -
patch jss-ftweedal-0009-Update-AES-CBC-PAD-cipher-definitions.patch
Subject: Update AES-CBC-PAD cipher definitions
From: Fraser Tweedale <ftweedal@redhat.com>
message:
Update AES-CBC-PAD cipher definitions
The AES_{128,192,256}_CBC_PAD EncryptionAlgorithm definitions declare
the correct PKCS #11 cipher mechanism and padding, but do not declare
the relevant OIDs.  They are also unusable as target algorithms in
PBE key generation because they declare a PK11_MECH instead of a
SEC_OID_TAG.

Update these algorithms definitions to declare a SEC_OID_TAG instead
of a PK11_MECH (JSS_getOidTagFromAlg() will still return the correct
mechanism) and declare the associated OIDs.

cfu for ftweedal

diff -r 890216599f21 -r d39e9b373798 org/mozilla/jss/crypto/EncryptionAlgorithm.java
--- a/org/mozilla/jss/crypto/EncryptionAlgorithm.java	Fri Sep 08 11:21:22 2017 -0700
+++ b/org/mozilla/jss/crypto/EncryptionAlgorithm.java	Fri Sep 08 11:32:32 2017 -0700
@@ -359,8 +359,10 @@
         AES_ROOT_OID.subBranch(2), 128);
 
     public static final EncryptionAlgorithm
-    AES_128_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
-        Padding.PKCS5, IVParameterSpecClasses, 16, null, 128); // no oid
+    AES_128_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_128_CBC,
+        Alg.AES, Mode.CBC,
+        Padding.PKCS5, IVParameterSpecClasses, 16,
+        AES_ROOT_OID.subBranch(2), 128);
     
     public static final EncryptionAlgorithm
     AES_192_ECB = new EncryptionAlgorithm(SEC_OID_AES_192_ECB,
@@ -374,8 +376,10 @@
         AES_ROOT_OID.subBranch(22), 192);
     
     public static final EncryptionAlgorithm
-    AES_192_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
-        Padding.PKCS5, IVParameterSpecClasses, 16, null, 192); // no oid
+    AES_192_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_192_CBC,
+        Alg.AES, Mode.CBC,
+        Padding.PKCS5, IVParameterSpecClasses, 16,
+        AES_ROOT_OID.subBranch(22), 192);
 
     public static final EncryptionAlgorithm
     AES_256_ECB = new EncryptionAlgorithm(SEC_OID_AES_256_ECB,
@@ -393,6 +397,9 @@
         Padding.PKCS5, IVParameterSpecClasses, 16, null, 256); // no oid
     
     public static final EncryptionAlgorithm
-    AES_256_CBC_PAD = AES_CBC_PAD;
+    AES_256_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_256_CBC,
+        Alg.AES, Mode.CBC,
+        Padding.PKCS5, IVParameterSpecClasses, 16,
+        AES_ROOT_OID.subBranch(42), 256);
     
 }
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504896621 25200
#      Fri Sep 08 11:50:21 2017 -0700
# Node ID 0b8a6e84b6c736743f2184b2b858fda6be740544
# Parent  d39e9b373798ea9d6ae7f35089b07143845b210e
Bug 1370778 PBE and padded block cipher enhancements and fixes -
patch jss-ftweedal-0010-PK11Cipher-use-pad-mechanism-for-algorithms-that-use.patch
Subject: PK11Cipher: use pad mechanism for algorithms that use padding
From: Fraser Tweedale <ftweedal@redhat.com>
message:
PK11Cipher: use pad mechanism for algorithms that use padding
The PK11Cipher implementation, when initialising a cipher context,
uses JSS_getPK11MechFromAlg() to retrieve the PKCS #11 mechanism to
use.  When a JSS EncryptionAlgorithm uses a SEC_OID_TAG, this will
return the non-padded mechanism.  Then, if the size of the data is
not a multiple of the cipher block size, a padding error occurs.

When the EncryptionAlgorithm indicates that padding is to be used,
call PK11_GetPadMechanism() on the result of JSS_getPK11MechFromAlg()
to get the padding variant of the mechanism.

cfu for ftweedal

diff -r d39e9b373798 -r 0b8a6e84b6c7 org/mozilla/jss/pkcs11/PK11Cipher.c
--- a/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:32:32 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:50:21 2017 -0700
@@ -24,16 +24,16 @@
 JNIEXPORT jobject JNICALL
 Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext
     (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj,
-        jobject algObj, jbyteArray ivBA)
+        jobject algObj, jbyteArray ivBA, jboolean padded)
 {
     return Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits
-        ( env, clazz, encrypt, keyObj, algObj, ivBA, 0);
+        ( env, clazz, encrypt, keyObj, algObj, ivBA, 0, padded);
 }
 
 JNIEXPORT jobject JNICALL
 Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits
     (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj,
-        jobject algObj, jbyteArray ivBA, jint keyBits)
+        jobject algObj, jbyteArray ivBA, jint keyBits, jboolean padded)
 {
     CK_MECHANISM_TYPE mech;
     PK11SymKey *key=NULL;
@@ -53,6 +53,9 @@
         goto finish;
     }
 
+    if (padded)
+        mech = PK11_GetPadMechanism(mech);
+
     /* get operation type */
     if( encrypt ) {
         op = CKA_ENCRYPT;
diff -r d39e9b373798 -r 0b8a6e84b6c7 org/mozilla/jss/pkcs11/PK11Cipher.java
--- a/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:32:32 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:50:21 2017 -0700
@@ -90,10 +90,13 @@
         state = ENCRYPT;
 
         if( parameters instanceof RC2ParameterSpec ) {
-            contextProxy = initContextWithKeyBits( true, key, algorithm, IV,
-                ((RC2ParameterSpec)parameters).getEffectiveKeyBits() );
+            contextProxy = initContextWithKeyBits(
+                true, key, algorithm, IV,
+                ((RC2ParameterSpec)parameters).getEffectiveKeyBits(),
+                algorithm.isPadded());
         } else {
-            contextProxy = initContext( true, key, algorithm, IV );
+            contextProxy = initContext(
+                true, key, algorithm, IV, algorithm.isPadded());
         }
     }
 
@@ -112,10 +115,13 @@
         state = DECRYPT;
 
         if( parameters instanceof RC2ParameterSpec ) {
-            contextProxy = initContextWithKeyBits(false, key, algorithm, IV,
-                ((RC2ParameterSpec)parameters).getEffectiveKeyBits() );
+            contextProxy = initContextWithKeyBits(
+                false, key, algorithm, IV,
+                ((RC2ParameterSpec)parameters).getEffectiveKeyBits(),
+                algorithm.isPadded());
         } else {
-            contextProxy = initContext(false, key, algorithm, IV);
+            contextProxy = initContext(
+                false, key, algorithm, IV, algorithm.isPadded());
         }
     }
 
@@ -182,13 +188,13 @@
 
     private static native CipherContextProxy
     initContext(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg,
-                 byte[] IV)
+                 byte[] IV, boolean padded)
         throws TokenException;
 
     // This version accepts the number of effective key bits for RC2 CBC.
     private static native CipherContextProxy
     initContextWithKeyBits(boolean encrypt, SymmetricKey key,
-                EncryptionAlgorithm alg, byte[] IV, int keyBits)
+                EncryptionAlgorithm alg, byte[] IV, int keyBits, boolean padded)
         throws TokenException;
 
     private static native byte[]
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504896816 25200
#      Fri Sep 08 11:53:36 2017 -0700
# Node ID b3b653faef8475ae03c670766429fd4dfab37a5e
# Parent  0b8a6e84b6c736743f2184b2b858fda6be740544
bug 1370778 PBE and padded block cipher enhancements and fixes -
patch jss-ftweedal-0012-2-Add-method-EncryptedPrivateKeyInfo.createPBES2.patch
Subject: Add method EncryptedPrivateKeyInfo.createPBES2
From: Fraser Tweedale <ftweedal@redhat.com>
Content-Type: text/plain
found patch at byte 404
message:
Add method EncryptedPrivateKeyInfo.createPBES2
The createPBE method does not support PBES2 (it is necessary to know
the desired encrypted algorithm to derive the key and build the
parameters data).  Add the createPBES2 method, which uses PBKDF2 to
derive the symmetric key and allows the caller to specify the
encryption algorithm.

cfu for ftweedal

diff -r 0b8a6e84b6c7 -r b3b653faef84 org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java
--- a/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java	Fri Sep 08 11:50:21 2017 -0700
+++ b/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java	Fri Sep 08 11:53:36 2017 -0700
@@ -155,6 +155,100 @@
 
 
     /**
+     * Export a private key in PBES2 format, using a random PBKDF2 salt.
+     *
+     * Token must support the CKM_PKCS5_PBKD2 mechanism.
+     *
+     * @param saltLen Length of salt in bytes (default: 16)
+     * @param kdfIterations PBKDF2 iterations (default: 2000)
+     * @param encAlg The symmetric encryption algorithm for enciphering the
+     *               private key.  Determines the size of derived key.
+     * @param pwd Password
+     * @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 privateKeyInfo The encoded PrivateKeyInfo to be encrypted and
+     *                       stored in the EncryptedContentInfo.
+     */
+    public static EncryptedPrivateKeyInfo createPBES2(
+            int saltLen,
+            int kdfIterations,
+            EncryptionAlgorithm encAlg,
+            Password pwd,
+            KeyGenerator.CharToByteConverter charToByteConverter,
+            PrivateKeyInfo privateKeyInfo)
+        throws CryptoManager.NotInitializedException, NoSuchAlgorithmException,
+        InvalidKeyException, InvalidAlgorithmParameterException, TokenException,
+        CharConversionException
+    {
+        if (encAlg == null)
+            throw new IllegalArgumentException("encAlg cannot be null");
+        if (pwd == null)
+            throw new IllegalArgumentException("pwd cannot be null");
+        if (privateKeyInfo == null)
+            throw new IllegalArgumentException("privateKeyInfo cannot be null");
+
+        if (kdfIterations < 1)
+            kdfIterations = 2000;
+        if (saltLen < 1)
+            saltLen = 16;
+
+        try {
+            // generate random PBKDF2 salt
+            SecureRandom random = new SecureRandom();
+            byte salt[] = new byte[saltLen];
+            random.nextBytes(salt);
+
+            // derive symmetric key from passphrase using PBKDF2
+            CryptoManager cm = CryptoManager.getInstance();
+            CryptoToken token = cm.getInternalCryptoToken();
+            KeyGenerator kg = token.getKeyGenerator(
+                PBEAlgorithm.PBE_PKCS5_PBKDF2);
+            PBEKeyGenParams pbekgParams = new PBEKeyGenParams(
+                pwd.getChars(), salt, kdfIterations, encAlg);
+            if (charToByteConverter != null)
+                kg.setCharToByteConverter(charToByteConverter);
+            kg.initialize(pbekgParams);
+            SymmetricKey sk = kg.generate();
+
+            // encrypt PrivateKeyInfo
+            byte iv[] = new byte[encAlg.getBlockSize()];
+            random.nextBytes(iv);
+            Cipher cipher = token.getCipherContext(encAlg);
+            cipher.initEncrypt(sk, new IVParameterSpec(iv));
+            byte[] encData = cipher.doFinal(ASN1Util.encode(privateKeyInfo));
+
+            // construct KDF AlgorithmIdentifier
+            SEQUENCE paramsKdf = new SEQUENCE();
+            paramsKdf.addElement(new OCTET_STRING(salt));
+            paramsKdf.addElement(new INTEGER((long) kdfIterations));
+            paramsKdf.addElement(new INTEGER((long) sk.getLength()));
+            AlgorithmIdentifier algIdKdf = new AlgorithmIdentifier(
+                PBEAlgorithm.PBE_PKCS5_PBKDF2.toOID(), paramsKdf);
+
+            // construct encryption AlgorithmIdentifier
+            AlgorithmIdentifier algIdEnc = new AlgorithmIdentifier(
+                encAlg.toOID(), new OCTET_STRING(iv));
+
+            // construct "composite" PBES2 AlgorithmIdentifier
+            SEQUENCE paramsPBES2 = new SEQUENCE();
+            paramsPBES2.addElement(algIdKdf);
+            paramsPBES2.addElement(algIdEnc);
+            AlgorithmIdentifier algIdPBES2 = new AlgorithmIdentifier(
+                PBEAlgorithm.PBE_PKCS5_PBES2.toOID(), paramsPBES2);
+
+            // construct EncryptedPrivateKeyInfo
+            return new EncryptedPrivateKeyInfo(algIdPBES2, new OCTET_STRING(encData));
+        } catch (IllegalBlockSizeException e) {
+            Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo.createPBES2");
+        } catch (BadPaddingException e) {
+            Assert.notReached("BadPaddingException in EncryptedContentInfo.createPBES2");
+        }
+        return null; // unreachable
+    }
+
+
+    /**
      * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted
      * with a password-based key- 
      *       with wrapping/unwrapping happening on token.
# HG changeset patch
# User Fraser Tweedale<ftweedale@redhat.com>
# Date 1504896964 25200
#      Fri Sep 08 11:56:04 2017 -0700
# Node ID 87dca07f7529463398734d1279bcfd7023a43d4c
# Parent  b3b653faef8475ae03c670766429fd4dfab37a5e
Bug 1370778 PBE and padded block cipher enhancements and fixes -
patch  jss-ftweedal-0013-Improve-error-reporting.patch
Subject: Improve error reporting
From: Fraser Tweedale <ftweedal@redhat.com>
Content-Type: text/plain
found patch at byte 157
message:
Improve error reporting

cfu for ftweedal

diff -r b3b653faef84 -r 87dca07f7529 org/mozilla/jss/pkcs11/PK11KeyWrapper.c
--- a/org/mozilla/jss/pkcs11/PK11KeyWrapper.c	Fri Sep 08 11:53:36 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11KeyWrapper.c	Fri Sep 08 11:56:04 2017 -0700
@@ -251,9 +251,7 @@
     status = PK11_WrapPrivKey(slot, wrapping, toBeWrapped, mech, param,
                 &wrapped, NULL /* wincx */ );
     if(status != SECSuccess) {
-        char err[256] = {0};
-        PR_snprintf(err, 256, "Wrapping operation failed on token:%d", PR_GetError());
-        JSS_throwMsg(env, TOKEN_EXCEPTION, err);
+        JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Wrapping operation failed on token");
         goto finish;
     }
     PR_ASSERT(wrapped.len>0 && wrapped.data!=NULL);
@@ -450,8 +448,8 @@
                 attribs, numAttribs, NULL /*wincx*/);
     if( privk == NULL ) {
         char err[256] = {0};
-        PR_snprintf(err, 256, "Key Unwrap failed on token:error=%d, keyType=%d", PR_GetError(), keyType);
-        JSS_throwMsg(env, TOKEN_EXCEPTION, err);
+        PR_snprintf(err, 256, "Key Unwrap failed on token; keyType=%d", keyType);
+        JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, err);
         goto finish;
     }
                 
diff -r b3b653faef84 -r 87dca07f7529 org/mozilla/jss/pkcs11/PK11Store.c
--- a/org/mozilla/jss/pkcs11/PK11Store.c	Fri Sep 08 11:53:36 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11Store.c	Fri Sep 08 11:56:04 2017 -0700
@@ -734,7 +734,7 @@
         PR_TRUE /* isperm */, PR_TRUE /* isprivate */,
         pubKey->keyType, keyUsage, NULL /* wincx */);
     if (result != SECSuccess) {
-        JSS_throwMsg(
+        JSS_throwMsgPrErr(
             env, TOKEN_EXCEPTION,
             "Failed to import EncryptedPrivateKeyInfo to token");
         goto finish;