pkcs11.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,963 行 · 第 1/5 页
C
1,963 行
} /* Now Set up the parameters to generate the key (based on mechanism) */ if (lowPriv == NULL) { keyType = pubKey->keyType; } else { keyType = lowPriv->keyType; } switch (keyType) { case rsaKey: /* format the keys */ key_type = CKK_RSA; verify = CK_TRUE; recover = CK_TRUE; encrypt = CK_TRUE; derive = CK_FALSE; /* now fill in the RSA dependent parameters in the public key */ if (lowPriv) { crv = pk11_AddAttributeType(publicKey,CKA_MODULUS, pk11_item_expand(&lowPriv->u.rsa.modulus)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT, pk11_item_expand(&lowPriv->u.rsa.publicExponent)); if (crv != CKR_OK) break; } else { crv = pk11_AddAttributeType(publicKey,CKA_MODULUS, pk11_item_expand(&pubKey->u.rsa.modulus)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT, pk11_item_expand(&pubKey->u.rsa.publicExponent)); if (crv != CKR_OK) break; } break; case dsaKey: key_type = CKK_DSA; verify = CK_TRUE; recover = CK_FALSE; encrypt = CK_FALSE; derive = CK_FALSE; if (lowPriv) { crv = pk11_AddAttributeType(publicKey,CKA_PRIME, pk11_item_expand(&lowPriv->u.dsa.params.prime)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME, pk11_item_expand(&lowPriv->u.dsa.params.subPrime)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_BASE, pk11_item_expand(&lowPriv->u.dsa.params.base)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_VALUE, pk11_item_expand(&lowPriv->u.dsa.publicValue)); if (crv != CKR_OK) break; } else { crv = pk11_AddAttributeType(publicKey,CKA_PRIME, pk11_item_expand(&pubKey->u.dsa.params.prime)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME, pk11_item_expand(&pubKey->u.dsa.params.subPrime)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_BASE, pk11_item_expand(&pubKey->u.dsa.params.base)); if (crv != CKR_OK) break; crv = pk11_AddAttributeType(publicKey,CKA_VALUE, pk11_item_expand(&pubKey->u.dsa.publicValue)); if (crv != CKR_OK) break; } break; case dhKey: key_type = CKK_DH; verify = CK_FALSE; encrypt = CK_FALSE; recover = CK_FALSE; derive = CK_TRUE; crv = CKR_MECHANISM_INVALID; break; default: crv = CKR_MECHANISM_INVALID; } if (pubKey) { SECKEY_DestroyPublicKey(pubKey); pubKey = NULL; } if (crv != CKR_OK) { goto failed; } if (pk11_AddAttributeType(publicKey,CKA_VERIFY, &verify, sizeof(CK_BBOOL)) != CKR_OK) { goto failed; } if (pk11_AddAttributeType(publicKey,CKA_VERIFY_RECOVER, &recover, sizeof(CK_BBOOL)) != CKR_OK) { goto failed; } if (pk11_AddAttributeType(publicKey,CKA_ENCRYPT, &encrypt, sizeof(CK_BBOOL)) != CKR_OK) { goto failed; } if (pk11_AddAttributeType(publicKey,CKA_WRAP, &encrypt, sizeof(CK_BBOOL)) != CKR_OK) { goto failed; } if (pk11_AddAttributeType(publicKey,CKA_DERIVE, &derive, sizeof(CK_BBOOL)) != CKR_OK) { goto failed; } if (pk11_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type, sizeof(CK_KEY_TYPE)) != CKR_OK) { goto failed; } PK11_USE_THREADS(PR_Lock(slot->objectLock);) publicKey->handle = slot->tokenIDCount++; publicKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB); PK11_USE_THREADS(PR_Unlock(slot->objectLock);) publicKey->objclass = pubClass; publicKey->slot = slot; publicKey->inDB = PR_FALSE; /* not really in the Database */ return publicKey;failed: if (pubKey) SECKEY_DestroyPublicKey(pubKey); if (publicKey) pk11_FreeObject(publicKey); return NULL;}/* * Question.. Why doesn't import Cert call pk11_handleObject, or * pk11 handleCertObject? Answer: because they will try to write * this cert back out to the Database, even though it is already in * the database. */static PK11Object *pk11_importCertificate(PK11Slot *slot, CERTCertificate *cert, unsigned char *data, unsigned int size, PRBool needObject){ PK11Object *certObject = NULL; CK_BBOOL cktrue = CK_TRUE; CK_BBOOL ckfalse = CK_FALSE; CK_CERTIFICATE_TYPE certType = CKC_X_509; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; unsigned char cka_id[SHA1_LENGTH]; CK_ATTRIBUTE theTemplate; PK11ObjectListElement *objectList = NULL; CK_RV crv; /* * first make sure that no object for this cert already exists. */ theTemplate.type = CKA_VALUE; theTemplate.pValue = cert->derCert.data; theTemplate.ulValueLen = cert->derCert.len; crv = pk11_searchObjectList(&objectList,slot->tokObjects, slot->objectLock, &theTemplate, 1, slot->isLoggedIn); if ((crv == CKR_OK) && (objectList != NULL)) { if (needObject) { pk11_ReferenceObject(objectList->object); certObject = objectList->object; } pk11_FreeObjectList(objectList); return certObject; } /* * now lets create an object to hang the attributes off of */ certObject = pk11_NewObject(slot); /* fill in the handle later */ if (certObject == NULL) { return NULL; } /* First set the CKA_ID */ if (data == NULL) { SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(cert); SECItem *pubItem; if (pubKey == NULL) { pk11_FreeObject(certObject); return NULL; } /* pk11_GetPubItem returns data associated with the public key. * one only needs to free the public key. This comment is here * because this sematic would be non-obvious otherwise. */ pubItem =pk11_GetPubItem(pubKey); if (pubItem == NULL) { SECKEY_DestroyPublicKey(pubKey); pk11_FreeObject(certObject); return NULL; } SHA1_HashBuf(cka_id, (unsigned char *)pubItem->data, (uint32)pubItem->len); SECKEY_DestroyPublicKey(pubKey); } else { SHA1_HashBuf(cka_id, (unsigned char *)data, (uint32)size); } if (pk11_AddAttributeType(certObject, CKA_ID, cka_id, sizeof(cka_id))) { pk11_FreeObject(certObject); return NULL; } /* initalize the certificate attributes */ if (pk11_AddAttributeType(certObject, CKA_CLASS, &certClass, sizeof(CK_OBJECT_CLASS)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse, sizeof(CK_BBOOL)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_LABEL, cert->nickname, PORT_Strlen(cert->nickname)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_MODIFIABLE, &cktrue, sizeof(CK_BBOOL)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType, sizeof(CK_CERTIFICATE_TYPE))!=CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_VALUE, pk11_item_expand(&cert->derCert)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_ISSUER, pk11_item_expand(&cert->derIssuer)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_SUBJECT, pk11_item_expand(&cert->derSubject)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } if (pk11_AddAttributeType(certObject, CKA_SERIAL_NUMBER, pk11_item_expand(&cert->serialNumber)) != CKR_OK) { pk11_FreeObject(certObject); return NULL; } certObject->objectInfo = CERT_DupCertificate(cert); certObject->infoFree = (PK11Free) CERT_DestroyCertificate; /* now just verify the required date fields */ PK11_USE_THREADS(PR_Lock(slot->objectLock);) certObject->handle = slot->tokenIDCount++; certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT); PK11_USE_THREADS(PR_Unlock(slot->objectLock);) certObject->objclass = certClass; certObject->slot = slot; certObject->inDB = PR_TRUE; pk11_AddSlotObject(slot, certObject); if (needObject) { pk11_ReferenceObject(certObject); } else { certObject = NULL; } return certObject;}/* * ******************** Public Key Utilities *************************** *//* Generate a low public key structure from an object */SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type){ SECKEYLowPublicKey *pubKey; PLArenaPool *arena; CK_RV crv; if (object->objclass != CKO_PUBLIC_KEY) { return NULL; } /* If we already have a key, use it */ if (object->objectInfo) { return (SECKEYLowPublicKey *)object->objectInfo; } /* allocate the structure */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) return NULL; pubKey = (SECKEYLowPublicKey *) PORT_ArenaAlloc(arena,sizeof(SECKEYLowPublicKey)); if (pubKey == NULL) { PORT_FreeArena(arena,PR_FALSE); return NULL; } /* fill in the structure */ pubKey->arena = arena; switch (key_type) { case CKK_RSA: pubKey->keyType = rsaKey; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.modulus, object,CKA_MODULUS); if (crv != CKR_OK) break; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.publicExponent, object,CKA_PUBLIC_EXPONENT); break; case CKK_DSA: pubKey->keyType = dsaKey; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.prime, object,CKA_PRIME); if (crv != CKR_OK) break; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.subPrime, object,CKA_SUBPRIME); if (crv != CKR_OK) break; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.base, object,CKA_BASE); if (crv != CKR_OK) break; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.publicValue, object,CKA_VALUE); break; case CKK_DH: default: crv = CKR_KEY_TYPE_INCONSISTENT; break; } if (crv != CKR_OK) { PORT_FreeArena(arena,PR_FALSE); return NULL; } object->objectInfo = pubKey; object->infoFree = (PK11Free) SECKEY_LowDestroyPublicKey; return pubKey;}/* make a private key from a verified object */static SECKEYLowPrivateKey *pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type){ SECKEYLowPrivateKey *privKey; PLArenaPool *arena; CK_RV crv = CKR_OK; SECStatus rv; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) return NULL; privKey = (SECKEYLowPrivateKey *) PORT_ArenaAlloc(arena,sizeof(SECKEYLowPrivateKey)); if (privKey == NULL) { PORT_FreeArena(arena,PR_FALSE); return NULL; } /* in future this would be a switch on key_type */ privKey->arena = arena; switch (key_type) { case CKK_RSA: privKey->keyType = rsaKey; crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.modulus, object,CKA_MODULUS); if (crv != CKR_OK) break; crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.publicExponent,object, CKA_PUBLIC_EXPONENT); if (crv != CKR_OK) break; crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.privateExponent,object, CKA_PRIVATE_EXPONENT); if (crv != CKR_OK) break; crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.prime1,object, CKA_PRIME_1); if (crv != CKR_OK) break; crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.prime2,object, CKA_PRIME_2); if (crv != CKR_OK) break; crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.exponent1, object, CKA_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?