pk11skey.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,251 行 · 第 1/5 页

C
2,251
字号
    CK_OBJECT_HANDLE objectID;    CK_ATTRIBUTE theTemplate[10];    CK_ATTRIBUTE *signedattr = NULL;    CK_ATTRIBUTE *attrs = theTemplate;    int signedcount = 0;    int templateCount = 0;    SECStatus rv;    /* if we already have an object in the desired slot, use it */    if (!isToken && pubKey->pkcs11Slot == slot) {	return pubKey->pkcs11ID;    }    /* free the existing key */    if (pubKey->pkcs11Slot != NULL) {	PK11SlotInfo *oSlot = pubKey->pkcs11Slot;	PK11_EnterSlotMonitor(oSlot);	(void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session,							pubKey->pkcs11ID);	PK11_ExitSlotMonitor(oSlot);	PK11_FreeSlot(oSlot);	pubKey->pkcs11Slot = NULL;    }    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;    PK11_SETATTRS(attrs, CKA_TOKEN, isToken ? &cktrue : &ckfalse,						 sizeof(CK_BBOOL) ); attrs++;    /* now import the key */    {        switch (pubKey->keyType) {        case rsaKey:	    keyType = CKK_RSA;	    PK11_SETATTRS(attrs, CKA_WRAP, &cktrue, sizeof(CK_BBOOL) ); attrs++;	    PK11_SETATTRS(attrs, CKA_ENCRYPT, &cktrue, 						sizeof(CK_BBOOL) ); attrs++;	    PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); attrs++; 	    signedattr = attrs;	    PK11_SETATTRS(attrs, CKA_MODULUS, pubKey->u.rsa.modulus.data,					 pubKey->u.rsa.modulus.len); attrs++;	    PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, 	     	pubKey->u.rsa.publicExponent.data,				 pubKey->u.rsa.publicExponent.len); attrs++;	    break;        case dsaKey:	    keyType = CKK_DSA;	    PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++; 	    signedattr = attrs;	    PK11_SETATTRS(attrs, CKA_PRIME,    pubKey->u.dsa.params.prime.data,				pubKey->u.dsa.params.prime.len); attrs++;	    PK11_SETATTRS(attrs,CKA_SUBPRIME,pubKey->u.dsa.params.subPrime.data,				pubKey->u.dsa.params.subPrime.len); attrs++;	    PK11_SETATTRS(attrs, CKA_BASE,  pubKey->u.dsa.params.base.data,					pubKey->u.dsa.params.base.len); attrs++;	    PK11_SETATTRS(attrs, CKA_VALUE,    pubKey->u.dsa.publicValue.data, 					pubKey->u.dsa.publicValue.len); attrs++;	    break;	case fortezzaKey:	    keyType = CKK_DSA;	    PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++; 	    signedattr = attrs;	    PK11_SETATTRS(attrs, CKA_PRIME,pubKey->u.fortezza.params.prime.data,				pubKey->u.fortezza.params.prime.len); attrs++;	    PK11_SETATTRS(attrs,CKA_SUBPRIME,				pubKey->u.fortezza.params.subPrime.data,				pubKey->u.fortezza.params.subPrime.len);attrs++;	    PK11_SETATTRS(attrs, CKA_BASE,  pubKey->u.fortezza.params.base.data,				pubKey->u.fortezza.params.base.len); attrs++;	    PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.fortezza.DSSKey.data, 				pubKey->u.fortezza.DSSKey.len); attrs++;            break;        case dhKey:	    keyType = CKK_DH;	    PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++; 	    signedattr = attrs;	    PK11_SETATTRS(attrs, CKA_PRIME,    pubKey->u.dh.prime.data,				pubKey->u.dh.prime.len); attrs++;	    PK11_SETATTRS(attrs, CKA_BASE,  pubKey->u.dh.base.data,					pubKey->u.dh.base.len); attrs++;	    PK11_SETATTRS(attrs, CKA_VALUE,    pubKey->u.dh.publicValue.data, 					pubKey->u.dh.publicValue.len); attrs++;	    break;	/* what about fortezza??? */	default:	    PORT_SetError( SEC_ERROR_BAD_KEY );	    return CK_INVALID_KEY;	}	templateCount = attrs - theTemplate;	signedcount = attrs - signedattr;	PORT_Assert(templateCount <= (sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)));	for (attrs=signedattr; signedcount; attrs++, signedcount--) {		pk11_SignedToUnsigned(attrs);	}         rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,				 	templateCount, isToken, &objectID);	if ( rv != SECSuccess) {	    return CK_INVALID_KEY;	}    }    pubKey->pkcs11ID = objectID;    pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);    return objectID;}/* * return the slot associated with a symetric key */PK11SlotInfo *PK11_GetSlotFromKey(PK11SymKey *symKey){    return PK11_ReferenceSlot(symKey->slot);}PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,								void *wincx){    CK_ATTRIBUTE findTemp[4];    CK_ATTRIBUTE *attrs;    CK_BBOOL ckTrue = CK_TRUE;    CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;    int tsize = 0;    CK_OBJECT_HANDLE key_id;    attrs = findTemp;    PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;    PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;    if (keyID) {        PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); attrs++;    }    tsize = attrs - findTemp;    PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));    key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize);    if (key_id == CK_INVALID_KEY) {	return NULL;    }    return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id,		 				PR_FALSE, wincx);}void *PK11_GetWindow(PK11SymKey *key){   return key->cx;}    /* * extract a symetric key value. NOTE: if the key is sensitive, we will * not be able to do this operation. This function is used to move * keys from one token to another */SECStatusPK11_ExtractKeyValue(PK11SymKey *symKey){    if (symKey->data.data != NULL) return SECSuccess;    if (symKey->slot == NULL) {	PORT_SetError( SEC_ERROR_INVALID_KEY );	return SECFailure;    }    return PK11_ReadAttribute(symKey->slot,symKey->objectID,CKA_VALUE,NULL,				&symKey->data);}SECItem *PK11_GetKeyData(PK11SymKey *symKey){    return &symKey->data;}/* * take an attribute and copy it into a secitem, converting unsigned to signed. */static CK_RVpk11_Attr2SecItem(PRArenaPool *arena, CK_ATTRIBUTE *attr, SECItem *item) {    unsigned char *dataPtr;    item->len = attr->ulValueLen;    dataPtr = (unsigned char*) PORT_ArenaAlloc(arena, item->len+1);    if ( dataPtr == NULL) {	return CKR_HOST_MEMORY;    }     *dataPtr = 0;    item->data = dataPtr+1;    PORT_Memcpy(item->data,attr->pValue,item->len);    if (item->data[0] & 0x80) {	item->data = item->data-1;	item->len++;    }    return CKR_OK;}/* * extract a public key from a slot and id */SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id){    CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;    PRArenaPool *arena;    PRArenaPool *tmp_arena;    SECKEYPublicKey *pubKey;    int templateCount = 0;    CK_KEY_TYPE pk11KeyType;    CK_RV crv;    CK_ATTRIBUTE template[8];    CK_ATTRIBUTE *attrs= template;    CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value;    /* if we didn't know the key type, get it */    if (keyType== nullKey) {        pk11KeyType = PK11_ReadULongAttribute(slot,id,CKA_KEY_TYPE);	if (pk11KeyType ==  CK_UNAVAILABLE_INFORMATION) {	    return NULL;	}	switch (pk11KeyType) {	case CKK_RSA:	    keyType = rsaKey;	    break;	case CKK_DSA:	    keyType = dsaKey;	    break;	case CKK_DH:	    keyType = dhKey;	    break;	default:	    PORT_SetError( SEC_ERROR_BAD_KEY );	    return NULL;	}    }    /* now we need to create space for the public key */    arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) return NULL;    tmp_arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);    if (tmp_arena == NULL) {	PORT_FreeArena (arena, PR_FALSE);	return NULL;    }    pubKey = (SECKEYPublicKey *) 			PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));    if (pubKey == NULL) {	PORT_FreeArena (arena, PR_FALSE);	PORT_FreeArena (tmp_arena, PR_FALSE);	return NULL;    }    pubKey->arena = arena;    pubKey->keyType = keyType;    pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);    pubKey->pkcs11ID = id;    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, 						sizeof(keyClass)); attrs++;    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &pk11KeyType, 						sizeof(pk11KeyType) ); attrs++;    switch (pubKey->keyType) {    case rsaKey:	modulus = attrs;	PK11_SETATTRS(attrs, CKA_MODULUS, NULL, 0); attrs++; 	exponent = attrs;	PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, NULL, 0); attrs++; 	templateCount = attrs - template;	PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));	crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);	if (crv != CKR_OK) break;	if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_RSA)) {	    crv = CKR_OBJECT_HANDLE_INVALID;	    break;	} 	crv = pk11_Attr2SecItem(arena,modulus,&pubKey->u.rsa.modulus);	if (crv != CKR_OK) break;	crv = pk11_Attr2SecItem(arena,exponent,&pubKey->u.rsa.publicExponent);	if (crv != CKR_OK) break;	break;    case dsaKey:	prime = attrs;	PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++; 	subprime = attrs;	PK11_SETATTRS(attrs, CKA_SUBPRIME, NULL, 0); attrs++; 	base = attrs;	PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++; 	value = attrs;	PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++; 	templateCount = attrs - template;	PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));	crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);	if (crv != CKR_OK) break;	if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) {	    crv = CKR_OBJECT_HANDLE_INVALID;	    break;	} 	crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dsa.params.prime);	if (crv != CKR_OK) break;	crv = pk11_Attr2SecItem(arena,subprime,&pubKey->u.dsa.params.subPrime);	if (crv != CKR_OK) break;	crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dsa.params.base);	if (crv != CKR_OK) break;	crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dsa.publicValue);	if (crv != CKR_OK) break;	break;    case dhKey:	prime = attrs;	PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++; 	base = attrs;	PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++; 	value =attrs;	PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++; 	templateCount = attrs - template;	PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));	crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);	if (crv != CKR_OK) break;	if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) {	    crv = CKR_OBJECT_HANDLE_INVALID;	    break;	} 	crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dh.prime);	if (crv != CKR_OK) break;	crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dh.base);	if (crv != CKR_OK) break;	crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue);	if (crv != CKR_OK) break;	break;    case fortezzaKey:    case nullKey:    default:	crv = CKR_OBJECT_HANDLE_INVALID;	break;    }    PORT_FreeArena(tmp_arena,PR_FALSE);    if (crv != CKR_OK) {	PORT_FreeArena(arena,PR_FALSE);	PK11_FreeSlot(slot);	PORT_SetError( PK11_MapError(crv) );	return NULL;    }    return pubKey;}/* * Build a Private Key structure from raw PKCS #11 information. */SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType, 			PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx){    PRArenaPool *arena;    SECKEYPrivateKey *privKey;    /* don't know? look it up */    if (keyType == nullKey) {	CK_KEY_TYPE pk11Type = CKK_RSA;	pk11Type = PK11_ReadULongAttribute(slot,privID,CKA_KEY_TYPE);	isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN);	switch (pk11Type) {	case CKK_RSA: keyType = rsaKey; break;	case CKK_DSA: keyType = dsaKey; break;	case CKK_DH: keyType = dhKey; break;	case CKK_KEA: keyType = fortezzaKey; break;	default:		break;	}    }    /* now we need to create space for the private key */    arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) return NULL;    privKey = (SECKEYPrivateKey *) 			PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));    if (privKey == NULL) {	PORT_FreeArena(arena, PR_FALSE);	return NULL;    }    privKey->arena = arena;    privKey->keyType = keyType;    privKey->pkcs11Slot = PK11_ReferenceSlot(slot);    privKey->pkcs11ID = privID;    privKey->pkcs11IsTemp = isTemp;    privKey->wincx = wincx;    return privKey;}/* return the keylength if possible.  '0' if not */unsigned intPK11_GetKeyLength(PK11SymKey *key){   if (key->size != 0) return key->size ;   if (key->data.data == NULL) {	PK11_ExtractKeyValue(key);   }   /* key is probably secret. Look up it's type and length */   /*  this is new PKCS #11 version 2.0 functionality. */   if (key->size == 0) {	CK_ULONG keyLength;	keyLength = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_VALUE_LEN);	/* doesn't have a length field, check the known PKCS #11 key types,	 * which don't have this field */	if (keyLength == CK_UNAVAILABLE_INFORMATION) {	    CK_KEY_TYPE keyType;	    keyType = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_KEY_TYPE);	    switch (keyType) {	    case CKK_DES: key->size = 8; break;	    case CKK_DES2: key->size = 16; break;	    case CKK_DES3: key->size = 24; break;	    case CKK_SKIPJACK: key->size = 10; break;	    case CKK_BATON: key->size = 20; break;	    case CKK_JUNIPER: key->size = 20; break;	    case CKK_GENERIC_SECRET:		if (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN)  {		    key->size=48;		}		break;	    default: break;	    }	} else {	    key->size = (unsigned int)keyLength;	}    }	   return key->size;}/* return the strength of a key. This is different from length in that * 1) it returns the size in bits, and 2) it returns only the secret portions * of the key minus any checksums or parity. */unsigned intPK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid) {     int size=0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?