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