diff --git a/security/jss/org/mozilla/jss/crypto/KeyGenerator.java b/security/jss/org/mozilla/jss/crypto/KeyGenerator.java index bd77626ea7c3..548703d0ef3f 100644 --- a/security/jss/org/mozilla/jss/crypto/KeyGenerator.java +++ b/security/jss/org/mozilla/jss/crypto/KeyGenerator.java @@ -56,6 +56,27 @@ public interface KeyGenerator { public void initialize(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException; + /** + * @param usages The operations the key will be used for after it is + * generated. You have to specify these so that the key can be properly + * marked with the operations it supports. Some PKCS #11 tokens require + * that a key be marked for an operation before it can perform that + * operation. The default is SymmetricKey.Usage.SIGN and + * SymmetricKey.Usage.ENCRYPT. + */ + public void setKeyUsages(SymmetricKey.Usage[] usages); + + /** + * Tells the generator to generate temporary or permanent keys. + * Temporary keys are not written permanently to the token. They + * are destroyed by the garbage collector. If this method is not + * called, the default is temporary keys. + */ + public void temporaryKeys(boolean temp); + + /** + * Generates a symmetric key. + */ public SymmetricKey generate() throws IllegalStateException, TokenException, CharConversionException; diff --git a/security/jss/org/mozilla/jss/crypto/SymmetricKey.java b/security/jss/org/mozilla/jss/crypto/SymmetricKey.java index 7beac3d1db68..0553f168a771 100644 --- a/security/jss/org/mozilla/jss/crypto/SymmetricKey.java +++ b/security/jss/org/mozilla/jss/crypto/SymmetricKey.java @@ -132,6 +132,7 @@ public interface SymmetricKey { public int getVal() { return val; } // these enums must match the JSS_symkeyUsage list in Algorithm.c + // and the opFlagForUsage list in PK11KeyGenerator.java public static final Usage ENCRYPT = new Usage(0); public static final Usage DECRYPT = new Usage(1); public static final Usage WRAP = new Usage(2); diff --git a/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c b/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c index d1c33399d414..98ccc2cfa9f3 100644 --- a/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c +++ b/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c @@ -72,11 +72,13 @@ PBE_DestroyContext(PBEBitGenContext *context); */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateNormal - (JNIEnv *env, jclass clazz, jobject token, jobject alg, jint strength) + (JNIEnv *env, jclass clazz, jobject token, jobject alg, jint strength, + jint opFlags, jboolean temporary) { PK11SlotInfo *slot=NULL; PK11SymKey *skey=NULL; CK_MECHANISM_TYPE mech; + PK11AttrFlags attrFlags=0; jobject keyObj=NULL; PR_ASSERT( env!=NULL && clazz!=NULL && token!=NULL && alg!=NULL ); @@ -90,9 +92,14 @@ Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateNormal mech = JSS_getPK11MechFromAlg(env, alg); PR_ASSERT(mech != CKM_INVALID_MECHANISM); + if(!temporary) { + attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE); + } + /* generate the key */ - skey = PK11_KeyGen(slot, mech, NULL /*param*/, - strength/8 /*in bytes*/, NULL /*wincx*/ ); + skey = PK11_TokenKeyGenWithFlags(slot, mech, NULL /*param*/, + strength/8 /*in bytes*/, NULL /*keyid*/, + opFlags, attrFlags, NULL /*wincx*/ ); if(skey==NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "KeyGen failed on token"); diff --git a/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.java b/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.java index 15888b408f80..e072083b320b 100644 --- a/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.java +++ b/security/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.java @@ -46,6 +46,27 @@ import java.io.CharConversionException; public final class PK11KeyGenerator implements KeyGenerator { + // 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_VERIFY = 0x00002000; + private static final int CKF_WRAP = 0x00020000; + private static final int CKF_UNWRAP = 0x00040000; + + // 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_WRAP, /* 2 */ + CKF_UNWRAP, /* 3 */ + CKF_SIGN, /* 4 */ + CKF_VERIFY /* 5 */ + }; + // The token this key will be generated on. private PK11Token token; @@ -59,6 +80,13 @@ public final class PK11KeyGenerator implements KeyGenerator { // The parameters for this algorithm. May be null for some algorithms. private AlgorithmParameterSpec parameters; + // The crypto operations the key will support. It is the logical OR + // of the opFlag constants, each specifying a supported operation. + private int opFlags = CKF_SIGN | CKF_ENCRYPT; + + // Whether the key will be temporary or permanent + private boolean temporaryKeyMode = true; + // Used to convert Java Password into a byte[]. private KeyGenerator.CharToByteConverter charToByte; @@ -136,6 +164,21 @@ public final class PK11KeyGenerator implements KeyGenerator { this.parameters = parameters; } + public void setKeyUsages(SymmetricKey.Usage[] usages) + { + this.opFlags = 0; + for( int i = 0; i < usages.length; i++ ) { + if( usages[i] != null ) { + this.opFlags |= opFlagForUsage[usages[i].getVal()]; + } + } + } + + public void temporaryKeys(boolean temp) + { + this.temporaryKeyMode = temp; + } + /** * Generates the key. This is the public interface, the actual @@ -165,7 +208,8 @@ public final class PK11KeyGenerator implements KeyGenerator { } } } else { - return generateNormal(token, algorithm, strength); + return generateNormal(token, algorithm, strength, + opFlags, temporaryKeyMode); } } @@ -257,11 +301,16 @@ public final class PK11KeyGenerator implements KeyGenerator { /** * A native method to generate a non-PBE key. + * @param token The token where the key generation happens + * @param algorithm The algorithm to use * @param strength The key size in bits, should be 0 for fixed-length * key algorithms. + * @param opFlags The crypto operations the key will support + * @param temporary Whether the key will be temporary or permanent */ private static native SymmetricKey - generateNormal(PK11Token token, KeyGenAlgorithm algorithm, int strength) + generateNormal(PK11Token token, KeyGenAlgorithm algorithm, int strength, + int opFlags, boolean temporary) throws TokenException; /**