mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 21:18:35 +00:00
Bugscape bug 54500: added some new methods to the SecretDecoderRing
KeyManager class. The patch is contributed by Matthew Harmsen of AOL. Modified Files: lib/jss.def org/mozilla/jss/SecretDecoderRing/KeyManager.c org/mozilla/jss/SecretDecoderRing/KeyManager.java
This commit is contained in:
parent
546a8a6e87
commit
ec5678ff34
@ -272,3 +272,10 @@ Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+JSS_3.5 { # JSS 3.5 release
|
||||
;+ global:
|
||||
Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateUniqueNamedKeyNative;
|
||||
Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupUniqueNamedKeyNative;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
@ -101,6 +101,80 @@ finish:
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateUniqueNamedKeyNative
|
||||
(JNIEnv *env, jobject this, jobject tokenObj, jobject algObj,
|
||||
jbyteArray keyIDba, jint keySize, jstring nickname)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_MECHANISM_TYPE mech;
|
||||
PK11SymKey *symk = NULL;
|
||||
SECItem *keyID = NULL;
|
||||
const char *keyname = NULL;
|
||||
SECStatus status;
|
||||
|
||||
/* get the slot */
|
||||
if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/)
|
||||
!= SECSuccess)
|
||||
{
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION,
|
||||
"Failed to login to token");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* get the key ID */
|
||||
keyID = JSS_ByteArrayToSECItem(env, keyIDba);
|
||||
if( keyID == NULL ) {
|
||||
ASSERT_OUTOFMEM(env);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* get the algorithm */
|
||||
mech = JSS_getPK11MechFromAlg(env, algObj);
|
||||
if( mech == CKM_INVALID_MECHANISM) {
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 "
|
||||
"mechanism for key generation algorithm");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* generate the key */
|
||||
symk = PK11_TokenKeyGen(slot, mech, NULL /*param*/, keySize, keyID,
|
||||
PR_TRUE /* isToken */, NULL /*wincx*/);
|
||||
if( symk == NULL ) {
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION,
|
||||
"Failed to generate token symmetric key");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* convert the Java String into a native "C" string */
|
||||
keyname = (*env)->GetStringUTFChars( env, nickname, 0 );
|
||||
|
||||
/* name the key */
|
||||
status = PK11_SetSymKeyNickname( symk, keyname );
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION,
|
||||
"Failed to name token symmetric key");
|
||||
}
|
||||
|
||||
|
||||
finish:
|
||||
if( symk != NULL ) {
|
||||
PK11_FreeSymKey(symk);
|
||||
}
|
||||
if( keyID != NULL ) {
|
||||
SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/);
|
||||
}
|
||||
if( keyname != NULL ) {
|
||||
/* free the native "C" string */
|
||||
(*env)->ReleaseStringUTFChars(env, nickname, keyname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupKeyNative
|
||||
(JNIEnv *env, jobject this, jobject tokenObj, jobject algObj,
|
||||
@ -155,6 +229,129 @@ finish:
|
||||
return symkObj;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupUniqueNamedKeyNative
|
||||
(JNIEnv *env, jobject this, jobject tokenObj, jobject algObj,
|
||||
jstring nickname)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_MECHANISM_TYPE mech;
|
||||
const char *keyname = NULL;
|
||||
char *name = NULL;
|
||||
int count = 0;
|
||||
int keys_found = 0;
|
||||
PK11SymKey *symKey = NULL;
|
||||
PK11SymKey *nextSymKey = NULL;
|
||||
jobject symKeyObj = NULL;
|
||||
|
||||
/* get the slot */
|
||||
if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/)
|
||||
!= SECSuccess)
|
||||
{
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION,
|
||||
"Failed to login to token");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* get the algorithm -- although this is not currently used */
|
||||
mech = JSS_getPK11MechFromAlg(env, algObj);
|
||||
if( mech == CKM_INVALID_MECHANISM) {
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 "
|
||||
"mechanism for key generation algorithm");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* convert the Java String into a native "C" string */
|
||||
keyname = (*env)->GetStringUTFChars( env, nickname, 0 );
|
||||
|
||||
/* initialize the symmetric key list. */
|
||||
symKey = PK11_ListFixedKeysInSlot(
|
||||
/* slot */ slot,
|
||||
/* nickname */ NULL,
|
||||
/* wincx */ NULL );
|
||||
|
||||
/* iterate through the symmetric key list. */
|
||||
while( symKey != NULL ) {
|
||||
name = PK11_GetSymKeyNickname( /* symmetric key */ symKey );
|
||||
if( name != NULL ) {
|
||||
if( keyname != NULL ) {
|
||||
if( PL_strcmp( keyname, name ) == 0 ) {
|
||||
keys_found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
|
||||
PK11_FreeSymKey( /* symmetric key */ symKey );
|
||||
symKey = nextSymKey;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
/* case 1: the token is empty */
|
||||
if( count == 0 ) {
|
||||
/* the specified token is empty */
|
||||
symKeyObj = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* case 2: the specified key is not on this token */
|
||||
if( ( keyname != NULL ) &&
|
||||
( keys_found == 0 ) ) {
|
||||
/* the key called "keyname" could not be found */
|
||||
symKeyObj = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* case 3: the specified key exists more than once on this token */
|
||||
if( keys_found != 1 ) {
|
||||
/* more than one key called "keyname" was found on this token */
|
||||
symKeyObj = NULL;
|
||||
JSS_throwMsgPrErr(env, TOKEN_EXCEPTION,
|
||||
"Duplicate named keys exist on this token");
|
||||
goto finish;
|
||||
} else {
|
||||
/* Re-initialize the symmetric key list. */
|
||||
symKey = PK11_ListFixedKeysInSlot(
|
||||
/* slot */ slot,
|
||||
/* nickname */ NULL,
|
||||
/* wincx */ NULL );
|
||||
|
||||
/* Reiterate through the symmetric key list once more, */
|
||||
/* this time returning an actual reference to the key. */
|
||||
while( symKey != NULL ) {
|
||||
name = PK11_GetSymKeyNickname( /* symmetric key */ symKey );
|
||||
if( name != NULL ) {
|
||||
if( keyname != NULL ) {
|
||||
if( PL_strcmp( keyname, name ) == 0 ) {
|
||||
symKeyObj = JSS_PK11_wrapSymKey(env, &symKey);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey );
|
||||
PK11_FreeSymKey( /* symmetric key */ symKey );
|
||||
symKey = nextSymKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finish:
|
||||
if( symKey != NULL ) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
}
|
||||
if( keyname != NULL ) {
|
||||
/* free the native "C" string */
|
||||
(*env)->ReleaseStringUTFChars(env, nickname, keyname);
|
||||
}
|
||||
return symKeyObj;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_SecretDecoderRing_KeyManager_deleteKeyNative
|
||||
(JNIEnv *env, jobject this, jobject tokenObj, jobject key)
|
||||
|
@ -115,6 +115,63 @@ public class KeyManager {
|
||||
private native void generateKeyNative(CryptoToken token,
|
||||
KeyGenAlgorithm alg, byte[] keyID, int keySize);
|
||||
|
||||
/**
|
||||
* Generates an SDR key with the default algorithm and key size.
|
||||
* and names it with the specified nickname.
|
||||
* The default algorithm is stored in the constant DEFAULT_KEYGEN_ALG.
|
||||
* The default key size is stored in the constant DEFAULT_KEYSIZE.
|
||||
* @param nickname the name of the symmetric key. Duplicate keynames
|
||||
* will be checked for, and are not allowed.
|
||||
* @return The keyID of the generated key. A random keyID will be chosen
|
||||
* that is not currently used on the token. The keyID must be stored
|
||||
* by the application in order to use this key for encryption in the
|
||||
* future.
|
||||
*/
|
||||
public byte[] generateUniqueNamedKey(String nickname)
|
||||
throws TokenException {
|
||||
return generateUniqueNamedKey(DEFAULT_KEYGEN_ALG, DEFAULT_KEYSIZE,
|
||||
nickname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an SDR key with the given algorithm, key size, and nickname.
|
||||
* @param alg The algorithm that this key will be used for.
|
||||
* This is necessary because it will be stored along with the
|
||||
* key for later use by the security library.
|
||||
* @param keySize Length of key in bytes. This is only relevant for
|
||||
* algorithms that take more than one key size. Otherwise it can just
|
||||
* be set to 0.
|
||||
* @param nickname the name of the symmetric key. Duplicate keynames
|
||||
* will be checked for, and are not allowed.
|
||||
* @return The keyID of the generated key. A random keyID will be chosen
|
||||
* that is not currently used on the token. The keyID must be stored
|
||||
* by the application in order to use this key for encryption in the
|
||||
* future.
|
||||
*/
|
||||
public byte[] generateUniqueNamedKey(KeyGenAlgorithm alg, int keySize,
|
||||
String nickname)
|
||||
throws TokenException
|
||||
{
|
||||
if( alg == null ) {
|
||||
throw new NullPointerException("alg is null");
|
||||
}
|
||||
// disallow duplicates (i. e. - symmetric keys with the same name)
|
||||
if( uniqueNamedKeyExists(nickname) ) {
|
||||
throw new NullPointerException("duplicate symmetric key");
|
||||
}
|
||||
byte[] keyID = generateUnusedKeyID();
|
||||
generateUniqueNamedKeyNative(token, alg, keyID, keySize, nickname);
|
||||
return keyID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keySize Key length in bytes.
|
||||
* @param nickname the name of the symmetric key. Duplicate keynames
|
||||
* will be checked for, and are not allowed.
|
||||
*/
|
||||
private native void generateUniqueNamedKeyNative(CryptoToken token,
|
||||
KeyGenAlgorithm alg, byte[] keyID, int keySize, String nickname);
|
||||
|
||||
/**
|
||||
* Generates a key ID that is currently unused on this token.
|
||||
* The caller is responsible for synchronization issues that may arise
|
||||
@ -166,6 +223,43 @@ public class KeyManager {
|
||||
private native SymmetricKey lookupKeyNative(CryptoToken token,
|
||||
EncryptionAlgorithm alg, byte[] keyid) throws TokenException;
|
||||
|
||||
private boolean uniqueNamedKeyExists(String nickname)
|
||||
throws TokenException
|
||||
{
|
||||
return (lookupUniqueNamedKey(Encryptor.DEFAULT_ENCRYPTION_ALG,
|
||||
nickname) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the key on this token with the given algorithm and nickname.
|
||||
* @param alg The algorithm that this key will be used for.
|
||||
* This is necessary because it will be stored along with the
|
||||
* key for later use by the security library. It should match
|
||||
* the actual algorithm of the key you are looking for. If you
|
||||
* pass in a different algorithm and try to use the key that is returned,
|
||||
* the results are undefined.
|
||||
* @param nickname the name of the symmetric key. Duplicate keynames
|
||||
* will be checked for, and are not allowed.
|
||||
* @return The key, or <tt>null</tt> if the key is not found.
|
||||
*/
|
||||
public SecretKey lookupUniqueNamedKey(EncryptionAlgorithm alg,
|
||||
String nickname)
|
||||
throws TokenException
|
||||
{
|
||||
if( alg == null || nickname == null || nickname.equals("") ) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
SymmetricKey k = lookupUniqueNamedKeyNative(token, alg, nickname);
|
||||
if( k == null ) {
|
||||
return null;
|
||||
} else {
|
||||
return new SecretKeyFacade(k);
|
||||
}
|
||||
}
|
||||
|
||||
private native SymmetricKey lookupUniqueNamedKeyNative(CryptoToken token,
|
||||
EncryptionAlgorithm alg, String nickname) throws TokenException;
|
||||
|
||||
/**
|
||||
* Deletes the key with the given keyID from this token.
|
||||
* @throws InvalidKeyException If the key does not exist on this token.
|
||||
@ -176,6 +270,20 @@ public class KeyManager {
|
||||
deleteKey(lookupKey(Encryptor.DEFAULT_ENCRYPTION_ALG, keyID));
|
||||
}
|
||||
|
||||
/**
|
||||
* If it exists, delete the key with the specified nickname from this
|
||||
* token.
|
||||
*/
|
||||
public void deleteUniqueNamedKey(String nickname) throws TokenException,
|
||||
InvalidKeyException
|
||||
{
|
||||
// only delete this symmetric key if it exists
|
||||
if( uniqueNamedKeyExists(nickname) ) {
|
||||
deleteKey(lookupUniqueNamedKey(Encryptor.DEFAULT_ENCRYPTION_ALG,
|
||||
nickname));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this key from this token.
|
||||
* @throws InvalidKeyException If the key does not reside on this token,
|
||||
|
Loading…
x
Reference in New Issue
Block a user