pkcs11.c

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

C
1,963
字号
    SEC_TraversePermCerts(CERT_GetDefaultCertDB(),				       find_cert_by_pub_key, (void *)&cbarg);    if (cbarg.cert != NULL) {	CERTCertificate *cert = NULL;	/* can anyone tell me why this is call is necessary? rjr */	cert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),							&cbarg.cert->derCert);	/* does the certificate in the database have a 	 * nickname?  if not, it probably was inserted 	 * through SMIME and a nickname needs to be 	 * set.	 */	if (cert && !cert->nickname) {	    crv=pk11_Attribute2SecItem(NULL,&nickName,privKeyObject,CKA_LABEL);	    if (crv != CKR_OK) {		goto loser;	    }	    rv = CERT_AddPermNickname(cert, (char *)nickName.data);	    SECITEM_ZfreeItem(&nickName, PR_FALSE);	    if (rv != SECSuccess) {		goto loser;	    }	}	/* associate the certificate with the key */	pk11_importCertificate(privKeyObject->slot, cert, pubKey->data, 				pubKey->len, PR_FALSE);    }    return SECSuccess;loser:    if (cert) CERT_DestroyCertificate(cert);    if (cbarg.cert) CERT_DestroyCertificate(cbarg.cert);    return SECFailure;}static SECKEYLowPrivateKey * pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key);/* * check the consistancy and initialize a Private Key Object  */static CK_RVpk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type){    CK_BBOOL cktrue = CK_TRUE;    CK_BBOOL encrypt = CK_TRUE;    CK_BBOOL recover = CK_TRUE;    CK_BBOOL wrap = CK_TRUE;    CK_BBOOL ckfalse = CK_FALSE;    SECItem mod;    CK_RV crv;    switch (key_type) {    case CKK_RSA:	if ( !pk11_hasAttribute(object, CKA_MODULUS)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_PRIVATE_EXPONENT)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_PRIME_1)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_PRIME_2)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_EXPONENT_1)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_EXPONENT_2)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_COEFFICIENT)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	/* make sure Netscape DB attribute is set correctly */	crv = pk11_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);	if (crv != CKR_OK) return crv;	crv = pk11_forceAttribute(object, CKA_NETSCAPE_DB, 						pk11_item_expand(&mod));	if (mod.data) PORT_Free(mod.data);	if (crv != CKR_OK) return crv;		break;    case CKK_DSA:	if ( !pk11_hasAttribute(object, CKA_PRIME)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_SUBPRIME)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_BASE)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_VALUE)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	if ( !pk11_hasAttribute(object, CKA_NETSCAPE_DB)) {	    return CKR_TEMPLATE_INCOMPLETE;	}	encrypt = CK_FALSE;	recover = CK_FALSE;	wrap = CK_FALSE;	break;    case CKK_DH:    default:	return CKR_ATTRIBUTE_VALUE_INVALID;    }    crv = pk11_defaultAttribute(object,CKA_SUBJECT,NULL,0);    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_SENSITIVE,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_SIGN_RECOVER,&recover,							     sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_UNWRAP,&wrap,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     /* the next two bits get modified only in the key gen and token cases */    crv = pk11_forceAttribute(object,CKA_ALWAYS_SENSITIVE,						&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_forceAttribute(object,CKA_NEVER_EXTRACTABLE,						&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     if (pk11_isTrue(object,CKA_TOKEN)) {	SECKEYLowPrivateKey *privKey;	char *label;	SECStatus rv = SECSuccess;	SECItem pubKey;	privKey=pk11_mkPrivKey(object,key_type);	if (privKey == NULL) return CKR_HOST_MEMORY;	label = object->label = pk11_getString(object,CKA_LABEL);	crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);	if (crv == CKR_OK) {	    rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),			privKey, &pubKey, label,			(SECKEYGetPasswordKey) pk11_givePass, object->slot);	    /* check for the existance of an existing certificate and activate	     * it if necessary */	    if (rv == SECSuccess) {	        reload_existing_certificate(object,&pubKey);	    }	    if (pubKey.data) PORT_Free(pubKey.data);	} else {	    rv = SECFailure;	}	SECKEY_LowDestroyPrivateKey(privKey);	if (rv != SECSuccess) return CKR_DEVICE_ERROR;	object->inDB = PR_TRUE;        object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);    } else {	object->objectInfo = pk11_mkPrivKey(object,key_type);	if (object->objectInfo == NULL) return CKR_HOST_MEMORY;	object->infoFree = (PK11Free) SECKEY_LowDestroyPrivateKey;    }    /* now NULL out the sensitive attributes */    if (pk11_isTrue(object,CKA_SENSITIVE)) {	pk11_nullAttribute(object,CKA_PRIVATE_EXPONENT);	pk11_nullAttribute(object,CKA_PRIME_1);	pk11_nullAttribute(object,CKA_PRIME_2);	pk11_nullAttribute(object,CKA_EXPONENT_1);	pk11_nullAttribute(object,CKA_EXPONENT_2);	pk11_nullAttribute(object,CKA_COEFFICIENT);    }    return CKR_OK;}/* forward delcare the DES formating function for handleSecretKey */void pk11_FormatDESKey(unsigned char *key, int length);static SECKEYLowPrivateKey *pk11_mkSecretKeyRep(PK11Object *object);/* Validate secret key data, and set defaults */static CK_RVvalidateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS){    CK_RV crv;    CK_BBOOL cktrue = CK_TRUE;    CK_BBOOL ckfalse = CK_FALSE;    PK11Attribute *attribute = NULL;    crv = pk11_defaultAttribute(object,CKA_SENSITIVE,				isFIPS?&cktrue:&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_EXTRACTABLE,						&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_DECRYPT,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_SIGN,&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_VERIFY,&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_WRAP,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_UNWRAP,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     if ( !pk11_hasAttribute(object, CKA_VALUE)) {	return CKR_TEMPLATE_INCOMPLETE;    }    /* the next two bits get modified only in the key gen and token cases */    crv = pk11_forceAttribute(object,CKA_ALWAYS_SENSITIVE,						&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_forceAttribute(object,CKA_NEVER_EXTRACTABLE,						&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     /* some types of keys have a value length */    crv = CKR_OK;    switch (key_type) {    /* force CKA_VALUE_LEN to be set */    case CKK_GENERIC_SECRET:    case CKK_RC2:    case CKK_RC4:#if NSS_SOFTOKEN_DOES_RC5    case CKK_RC5:#endif    case CKK_CAST:    case CKK_CAST3:    case CKK_CAST5:	attribute = pk11_FindAttribute(object,CKA_VALUE);	/* shouldn't happen */	if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;	crv = pk11_forceAttribute(object, CKA_VALUE_LEN, 			&attribute->attrib.ulValueLen, sizeof(CK_ULONG));	pk11_FreeAttribute(attribute);	break;    /* force the value to have the correct parity */    case CKK_DES:    case CKK_DES2:    case CKK_DES3:    case CKK_CDMF:	attribute = pk11_FindAttribute(object,CKA_VALUE);	/* shouldn't happen */	if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;	pk11_FormatDESKey((unsigned char*)attribute->attrib.pValue,						 attribute->attrib.ulValueLen);	pk11_FreeAttribute(attribute);	break;    default:	break;    }    return crv;}/* * check the consistancy and initialize a Secret Key Object  */static CK_RVpk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,								PRBool isFIPS){    CK_RV crv;    CK_BBOOL cktrue = CK_TRUE;    CK_BBOOL ckfalse = CK_FALSE;    PK11Attribute *attribute = NULL;    SECKEYLowPrivateKey *privKey = NULL;    SECItem pubKey;    pubKey.data = 0;    /* First validate and set defaults */    crv = validateSecretKey(object, key_type, isFIPS);    if (crv != CKR_OK) goto loser;    /* If the object is a TOKEN object, store in the database */    if (pk11_isTrue(object,CKA_TOKEN)) {	char *label;	SECStatus rv = SECSuccess;	privKey=pk11_mkSecretKeyRep(object);	if (privKey == NULL) return CKR_HOST_MEMORY;	label = object->label = pk11_getString(object,CKA_LABEL);	crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_ID);  /* Should this be ID? */	if (crv != CKR_OK) goto loser;	rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),			privKey, &pubKey, label,			(SECKEYGetPasswordKey) pk11_givePass, object->slot);	object->inDB = PR_TRUE;        object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);    }loser:    if (privKey) SECKEY_LowDestroyPrivateKey(privKey);    if (pubKey.data) PORT_Free(pubKey.data);    return crv;}/* * check the consistancy and initialize a Key Object  */static CK_RVpk11_handleKeyObject(PK11Session *session, PK11Object *object){    PK11Attribute *attribute;    CK_KEY_TYPE key_type;    CK_BBOOL cktrue = CK_TRUE;    CK_BBOOL ckfalse = CK_FALSE;    CK_RV crv;    /* verify the required fields */    if ( !pk11_hasAttribute(object,CKA_KEY_TYPE) ) {	return CKR_TEMPLATE_INCOMPLETE;    }    /* now verify the common fields */    crv = pk11_defaultAttribute(object,CKA_ID,NULL,0);    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_START_DATE,NULL,0);    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_END_DATE,NULL,0);    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     /* get the key type */    attribute = pk11_FindAttribute(object,CKA_KEY_TYPE);    key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;    pk11_FreeAttribute(attribute);    switch (object->objclass) {    case CKO_PUBLIC_KEY:	return pk11_handlePublicKeyObject(object,key_type);    case CKO_PRIVATE_KEY:	return pk11_handlePrivateKeyObject(object,key_type);    case CKO_SECRET_KEY:	/* make sure the required fields exist */	return pk11_handleSecretKeyObject(object,key_type,			     (PRBool)(session->slot->slotID == FIPS_SLOT_ID));    default:	break;    }    return CKR_ATTRIBUTE_VALUE_INVALID;}/*  * Handle Object does all the object consistancy checks, automatic attribute * generation, attribute defaulting, etc. If handleObject succeeds, the object * will be assigned an object handle, and the object pointer will be adopted * by the session. (that is don't free object). */CK_RVpk11_handleObject(PK11Object *object, PK11Session *session){    PK11Slot *slot = session->slot;    CK_BBOOL ckfalse = CK_FALSE;    CK_BBOOL cktrue = CK_TRUE;    PK11Attribute *attribute;    CK_RV crv;    /* make sure all the base object types are defined. If not set the     * defaults */    crv = pk11_defaultAttribute(object,CKA_TOKEN,&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK) return crv;    crv = pk11_defaultAttribute(object,CKA_PRIVATE,&ckfalse,sizeof(CK_BBOOL));    if (crv != CKR_OK) return crv;    crv = pk11_defaultAttribute(object,CKA_LABEL,NULL,0);    if (crv != CKR_OK) return crv;    crv = pk11_defaultAttribute(object,CKA_MODIFIABLE,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK) return crv;    /* don't create a private object if we aren't logged in */    if ((!slot->isLoggedIn) && (slot->needLogin) &&				(pk11_isTrue(object,CKA_PRIVATE))) {	return CKR_USER_NOT_LOGGED_IN;    }    if (((session->info.flags & CKF_RW_SESSION) == 0) &&

⌨️ 快捷键说明

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