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 + -
显示快捷键?