diff -rupN jss-4.2.5/mozilla/security/jss/lib/jss.def jss-4.2.6/mozilla/security/jss/lib/jss.def --- jss-4.2.5/mozilla/security/jss/lib/jss.def 2007-05-08 18:40:14.000000000 -0700 +++ jss-4.2.6/mozilla/security/jss/lib/jss.def 2009-05-30 01:57:48.000000000 -0700 @@ -316,3 +316,12 @@ Java_org_mozilla_jss_ssl_SSLSocket_isFip ;+ local: ;+ *; ;+}; +;+JSS_4.2.6 { # JSS 4.2.6 release +;+ global: +Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags; +Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags; +Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags; +;+ local: +;+ *; +;+}; + diff -rupN jss-4.2.5/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGenerator.java jss-4.2.6/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGenerator.java --- jss-4.2.5/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGenerator.java 2005-11-14 14:15:06.000000000 -0800 +++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGenerator.java 2009-05-22 07:40:14.000000000 -0700 @@ -81,7 +81,6 @@ public class KeyPairGenerator { genKeyPair() throws TokenException { return engine.generateKeyPair(); } - /** * @return The type of key that this generator generates. */ @@ -192,6 +191,15 @@ public class KeyPairGenerator { engine.extractablePairs(extractable); } + public void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages, + KeyPairGeneratorSpi.Usage[] usages_mask) { + engine.setKeyPairUsages(usages,usages_mask); + } + + + + + protected KeyPairAlgorithm algorithm; protected KeyPairGeneratorSpi engine; } diff -rupN jss-4.2.5/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java jss-4.2.6/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java --- jss-4.2.5/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java 2005-11-14 14:15:06.000000000 -0800 +++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java 2009-05-30 03:24:31.000000000 -0700 @@ -60,4 +60,38 @@ public abstract class KeyPairGeneratorSp public abstract void extractablePairs(boolean extractable); public abstract boolean keygenOnInternalToken(); + + /** + * In PKCS #11, each keypair can be marked with the operations it will + * be used to perform. Some tokens require that a key be marked for + * an operation before the key can be used to perform that operation; + * other tokens don't care. NSS provides a way to specify a set of + * flags and a corresponding mask for these flags. If a specific usage + * is desired set the value for that usage. If it is not set, let NSS + * behave in it's default fashion. If a behavior is desired, also set + * that behavior in the mask as well as the flags. + * + */ + public final static class Usage { + private Usage() { } + private Usage(int val) { this.val = val;} + private int val; + + public int getVal() { return val; } + + // these enums must match the + // and the opFlagForUsage list in PK11KeyPairGenerator.java + public static final Usage ENCRYPT = new Usage(0); + public static final Usage DECRYPT = new Usage(1); + public static final Usage SIGN = new Usage(2); + public static final Usage SIGN_RECOVER = new Usage(3); + public static final Usage VERIFY = new Usage(4); + public static final Usage VERIFY_RECOVER = new Usage(5); + public static final Usage WRAP = new Usage(6); + public static final Usage UNWRAP = new Usage(7); + public static final Usage DERIVE = new Usage(8); + } + + public abstract void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages, + KeyPairGeneratorSpi.Usage[] usages_mask); } diff -rupN jss-4.2.5/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.c jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.c --- jss-4.2.5/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.c 2006-02-22 17:21:42.000000000 -0800 +++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.c 2009-06-02 10:36:46.819581000 -0700 @@ -120,13 +120,11 @@ finish: int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); -/* - * make a common key gen function for both this file and PK11Token.c - */ SECStatus -JSS_PK11_generateKeyPair(JNIEnv *env, CK_MECHANISM_TYPE mechanism, +JSS_PK11_generateKeyPairWithOpFlags(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, - void *params, PRBool temporary, jint sensitive, jint extractable) + void *params, PRBool temporary, jint sensitive, jint extractable, + jint op_flags, jint op_flags_mask) { PK11AttrFlags attrFlags = 0; *privk=NULL; @@ -173,12 +171,16 @@ JSS_PK11_generateKeyPair(JNIEnv *env, CK } else { attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC); } - *privk = PK11_GenerateKeyPairWithFlags(slot, + + *privk = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubk, attrFlags, + (CK_FLAGS) op_flags, + (CK_FLAGS) op_flags_mask/* the ones we don't want*/, NULL /* default PW callback */ ); + if( *privk == NULL ) { int errLength; char *errBuf; @@ -217,13 +219,28 @@ finish: return SECFailure; } +/* + * make a common key gen function for both this file and PK11Token.c + */ +SECStatus +JSS_PK11_generateKeyPair(JNIEnv *env, CK_MECHANISM_TYPE mechanism, + PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, + void *params, PRBool temporary, jint sensitive, jint extractable) +{ + + return JSS_PK11_generateKeyPairWithOpFlags(env, mechanism, slot, pubk, privk, params, temporary, sensitive, extractable, 0, 0); +} + + /********************************************************************** - * Local generic helper + * Local generic helpers */ + static jobject -PK11KeyPairGenerator(JNIEnv *env, jobject this, jobject token, +PK11KeyPairGeneratorWithOpFlags(JNIEnv *env, jobject this, jobject token, CK_MECHANISM_TYPE mechanism, void *params, - jboolean temporary, jint sensitive, jint extractable) + jboolean temporary, jint sensitive, jint extractable, + jint op_flags, jint op_flags_mask) { PK11SlotInfo* slot; SECKEYPrivateKey *privk=NULL; @@ -242,8 +259,8 @@ PK11KeyPairGenerator(JNIEnv *env, jobjec } PR_ASSERT(slot != NULL); - rv = JSS_PK11_generateKeyPair(env, mechanism, slot, &pubk, &privk, - params, temporary, sensitive, extractable); + rv = JSS_PK11_generateKeyPairWithOpFlags(env, mechanism, slot, &pubk, &privk, + params, temporary, sensitive, extractable, op_flags, op_flags_mask); if (rv != SECSuccess) { goto finish; } @@ -267,6 +284,16 @@ finish: return keyPair; } +static jobject +PK11KeyPairGenerator(JNIEnv *env, jobject this, jobject token, + CK_MECHANISM_TYPE mechanism, void *params, + jboolean temporary, jint sensitive, jint extractable) +{ + return PK11KeyPairGeneratorWithOpFlags(env, this, token, mechanism, params, temporary, sensitive, extractable, 0, 0); +} + + + /********************************************************************** * PK11KeyPairGenerator.generateRSAKeyPair */ @@ -289,6 +316,30 @@ Java_org_mozilla_jss_pkcs11_PK11KeyPairG ¶ms, temporary, sensitive, extractable); } +/********************************************************************** + * PK11KeyPairGenerator.generateRSAKeyPairWithOpFlags + */ +JNIEXPORT jobject JNICALL +Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags + (JNIEnv *env, jobject this, jobject token, jint keySize, jlong publicExponent, + jboolean temporary, jint sensitive, jint extractable, + jint op_flags, jint op_flags_mask) +{ + PK11RSAGenParams params; + + PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); + + /************************************************** + * setup parameters + *************************************************/ + params.keySizeInBits = keySize; + params.pe = publicExponent; + + return PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_RSA_PKCS_KEY_PAIR_GEN, + ¶ms, temporary, sensitive, extractable, op_flags, op_flags_mask); +} + + #define ZERO_SECITEM(item) {(item).len=0; (item).data=NULL;} /********************************************************************** @@ -339,6 +390,57 @@ finish: return keyPair; } +/********************************************************************** + * + * PK11KeyPairGenerator.generateDSAKeyPair + * + */ +JNIEXPORT jobject JNICALL +Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags + (JNIEnv *env, jobject this, jobject token, jbyteArray P, jbyteArray Q, + jbyteArray G, jboolean temporary, jint sensitive, jint extractable, + jint op_flags, jint op_flags_mask) +{ + SECItem p, q, g; + PQGParams *params=NULL; + jobject keyPair=NULL; + + PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && P!=NULL && Q!=NULL + && G!=NULL); + + /* zero these so we can free them indiscriminately later */ + ZERO_SECITEM(p); + ZERO_SECITEM(q); + ZERO_SECITEM(g); + + /************************************************** + * Setup the parameters + *************************************************/ + if( JSS_ByteArrayToOctetString(env, P, &p) || + JSS_ByteArrayToOctetString(env, Q, &q) || + JSS_ByteArrayToOctetString(env, G, &g) ) + { + PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); + goto finish; + } + params = PK11_PQG_NewParams(&p, &q, &g); + if(params == NULL) { + JSS_throw(env, OUT_OF_MEMORY_ERROR); + goto finish; + } + keyPair = PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_DSA_KEY_PAIR_GEN, + params, temporary, sensitive, extractable, + op_flags, op_flags_mask); + +finish: + SECITEM_FreeItem(&p, PR_FALSE); + SECITEM_FreeItem(&q, PR_FALSE); + SECITEM_FreeItem(&g, PR_FALSE); + PK11_PQG_DestroyParams(params); + return keyPair; +} + + void DumpItem(SECItem *item) { @@ -361,6 +463,7 @@ Java_org_mozilla_jss_pkcs11_PK11KeyPairG (JNIEnv *env, jobject this, jobject token, jbyteArray Curve, jboolean temporary, jint sensitive, jint extractable) { + SECItem curve; jobject keyPair=NULL; @@ -385,3 +488,39 @@ finish: SECITEM_FreeItem(&curve, PR_FALSE); return keyPair; } + +/********************************************************************** + * + * PK11KeyPairGenerator.generateECKeyPairWithOpFlags + * + */ +JNIEXPORT jobject JNICALL +Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags + (JNIEnv *env, jobject this, jobject token, jbyteArray Curve, + jboolean temporary, jint sensitive, jint extractable, + jint op_flags, jint op_flags_mask) +{ + SECItem curve; + jobject keyPair=NULL; + + PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && Curve!=NULL ); + + /* zero these so we can free them indiscriminately later */ + ZERO_SECITEM(curve); + + /************************************************** + * Setup the parameters + *************************************************/ + if( JSS_ByteArrayToOctetString(env, Curve, &curve)) + { + PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); + goto finish; + } + keyPair = PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_EC_KEY_PAIR_GEN, + &curve, temporary, sensitive, extractable, + op_flags, op_flags_mask); + +finish: + SECITEM_FreeItem(&curve, PR_FALSE); + return keyPair; +} diff -rupN jss-4.2.5/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.java jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.java --- jss-4.2.5/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.java 2006-02-22 17:21:42.000000000 -0800 +++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.java 2009-05-30 05:30:25.000000000 -0700 @@ -55,6 +55,39 @@ public final class PK11KeyPairGenerator extends org.mozilla.jss.crypto.KeyPairGeneratorSpi { + // opFlag constants: each of these flags specifies a crypto operation + // the key will support. Their values must match the same-named C + // preprocessor macros defined in the PKCS #11 header pkcs11t.h. + private static final int CKF_ENCRYPT = 0x00000100; + private static final int CKF_DECRYPT = 0x00000200; + private static final int CKF_SIGN = 0x00000800; + private static final int CKF_SIGN_RECOVER = 0x00001000; + private static final int CKF_VERIFY = 0x00002000; + private static final int CKF_VERIFY_RECOVER = 0x00004000; + private static final int CKF_WRAP = 0x00020000; + private static final int CKF_UNWRAP = 0x00040000; + private static final int CKF_DERIVE = 0x00080000; + + // A table for mapping SymmetricKey.Usage to opFlag. This must be + // synchronized with SymmetricKey.Usage. + private static final int opFlagForUsage[] = { + CKF_ENCRYPT, /* 0 */ + CKF_DECRYPT, /* 1 */ + CKF_SIGN, /* 2 */ + CKF_SIGN_RECOVER, /* 3 */ + CKF_VERIFY, /* 4 */ + CKF_VERIFY_RECOVER, /* 5 */ + CKF_WRAP, /* 6 */ + CKF_UNWRAP, /* 7 */ + CKF_DERIVE /* 8 */ + }; + + // The crypto operations the key will support. It is the logical OR + // of the opFlag constants, each specifying a supported operation. + private int opFlags = 0; + private int opFlagsMask = 0; + + /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors @@ -189,41 +222,45 @@ public final class PK11KeyPairGenerator * Generates a key pair on a token. Uses parameters if they were passed * in through a call to initialize, otherwise uses defaults. */ + public KeyPair generateKeyPair() throws TokenException { if(algorithm == KeyPairAlgorithm.RSA) { if(params != null) { RSAParameterSpec rsaparams = (RSAParameterSpec)params; - return generateRSAKeyPair( + return generateRSAKeyPairWithOpFlags( token, rsaparams.getKeySize(), rsaparams.getPublicExponent().longValue(), temporaryPairMode, sensitivePairMode, - extractablePairMode); + extractablePairMode, + opFlags, opFlagsMask); } else { - return generateRSAKeyPair( + return generateRSAKeyPairWithOpFlags( token, DEFAULT_RSA_KEY_SIZE, DEFAULT_RSA_PUBLIC_EXPONENT.longValue(), temporaryPairMode, sensitivePairMode, - extractablePairMode); + extractablePairMode, + opFlags, opFlagsMask); } } else if(algorithm == KeyPairAlgorithm.DSA ) { if(params==null) { params = PQG1024; } DSAParameterSpec dsaParams = (DSAParameterSpec)params; - return generateDSAKeyPair( + return generateDSAKeyPairWithOpFlags( token, PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getP()), PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getQ()), PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getG()), temporaryPairMode, sensitivePairMode, - extractablePairMode); + extractablePairMode, + opFlags, opFlagsMask); } else { Assert._assert( algorithm == KeyPairAlgorithm.EC ); // requires JAVA 1.5 for ECParameters. @@ -233,12 +270,14 @@ public final class PK11KeyPairGenerator // ecParams.init(params); PK11ParameterSpec ecParams = (PK11ParameterSpec) params; - return generateECKeyPair( + return generateECKeyPairWithOpFlags( token, ecParams.getEncoded(), /* curve */ temporaryPairMode, sensitivePairMode, - extractablePairMode); + extractablePairMode, + opFlags, + opFlagsMask); } } @@ -266,6 +305,17 @@ public final class PK11KeyPairGenerator throws TokenException; /** + * Generates an RSA key pair with the given size and public exponent. + * Adds the ability to specify a set of flags and masks + * to control how NSS generates the key pair. + */ + private native KeyPair + generateRSAKeyPairWithOpFlags(PK11Token token, int keySize, long publicExponent, + boolean temporary, int sensitive, int extractable, + int op_flags, int op_flags_mask) + throws TokenException; + + /** * Generates a DSA key pair with the given P, Q, and G values. * P, Q, and G are stored as big-endian twos-complement octet strings. */ @@ -275,6 +325,19 @@ public final class PK11KeyPairGenerator throws TokenException; /** + * Generates a DSA key pair with the given P, Q, and G values. + * P, Q, and G are stored as big-endian twos-complement octet strings. + * Adds the ability to specify a set of flags and masks + * to control how NSS generates the key pair. + */ + private native KeyPair + generateDSAKeyPairWithOpFlags(PK11Token token, byte[] P, byte[] Q, byte[] G, + boolean temporary, int sensitive, int extractable, + int op_flags, int op_flags_mask) + throws TokenException; + + + /** * Generates a EC key pair with the given a curve. * Curves are stored as DER Encoded Parameters. */ @@ -282,6 +345,18 @@ public final class PK11KeyPairGenerator generateECKeyPair(PK11Token token, byte[] Curve, boolean temporary, int sensitive, int extractable) throws TokenException; + /** + * Generates a EC key pair with the given a curve. + * Curves are stored as DER Encoded Parameters. + * Adds the ability to specify a set of flags and masks + * to control how NSS generates the key pair. + */ + + private native KeyPair + generateECKeyPairWithOpFlags(PK11Token token, byte[] Curve, + boolean temporary, int sensitive, int extractable, + int op_flags, int op_flags_mask) + throws TokenException; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// @@ -397,6 +472,38 @@ public final class PK11KeyPairGenerator extractablePairMode = extractable ? 1 : 0; } + /** + * Sets the requested key usages desired for the + * generated key pair. + * This allows the caller to suggest how NSS generates the key pair. + * @param usages List of desired key usages. + * @param usages_mask Corresponding mask for the key usages. + * if a usages is desired, make sure it is in the mask as well. + */ + + public void setKeyPairUsages(org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usages, + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usages_mask) { + + this.opFlags = 0; + this.opFlagsMask = 0; + + if(usages != null) { + for( int i = 0; i < usages.length; i++ ) { + if( usages[i] != null ) { + this.opFlags |= opFlagForUsage[usages[i].getVal()]; + } + } + } + + if(usages_mask != null) { + for( int i = 0; i < usages_mask.length; i++ ) { + if( usages_mask[i] != null ) { + this.opFlagsMask |= opFlagForUsage[usages_mask[i].getVal()]; + } + } + } + } + // // requires JAVA 1.5 // diff -rupN jss-4.2.5/mozilla/security/jss/org/mozilla/jss/pkcs11/pk11util.h jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/pk11util.h --- jss-4.2.5/mozilla/security/jss/org/mozilla/jss/pkcs11/pk11util.h 2006-02-22 17:21:42.000000000 -0800 +++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/pk11util.h 2009-05-29 08:34:24.000000000 -0700 @@ -157,6 +157,12 @@ JSS_PK11_generateKeyPair(JNIEnv *env, CK PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privK, void *params, PRBool temporary, jint senstive, jint extractable); +SECStatus +JSS_PK11_generateKeyPair_withOpFlags(JNIEnv *env, CK_MECHANISM_TYPE mechanism, + PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, + void *params, PRBool temporary, jint sensitive, jint extractable, + jint op_flags, jint op_flags_mask); + /*===================================================================== C E R T I F I C A T E S =====================================================================*/