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:
wchang0222%aol.com 2003-12-19 05:33:50 +00:00
parent 546a8a6e87
commit ec5678ff34
3 changed files with 312 additions and 0 deletions

View File

@ -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:
;+ *;
;+};

View File

@ -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)

View File

@ -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,