pkcs11.c

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

C
1,963
字号
	tokDescription = tokdes;    }    if (ptokdes && (PORT_Strlen(ptokdes) == 33)) {	privTokDescription = ptokdes;    }    if (slotdes && (PORT_Strlen(slotdes) == 65)) {	slotDescription = slotdes;    }    if (pslotdes && (PORT_Strlen(pslotdes) == 65)) {	privSlotDescription = pslotdes;    }    if (minimumPinLen <= PK11_MAX_PIN) {	minimumPinLen = minPwd;    }    if ((minimumPinLen == 0) && (pwRequired) && 		(minimumPinLen <= PK11_MAX_PIN)) {	minimumPinLen = 1;    }    PK11_ConfigureFIPS(fslotdes,fpslotdes);    return;}/* * ******************** Password Utilities ******************************* *//* Handle to give the password to the database. user arg should be a pointer * to the slot. */static SECItem *pk11_givePass(void *sp,SECKEYKeyDBHandle *handle){    PK11Slot *slot = (PK11Slot *)sp;    if (slot->password == NULL) return NULL;    return SECITEM_DupItem(slot->password);}/* * see if the key DB password is enabled */PRBoolpk11_hasNullPassword(SECItem **pwitem){    PRBool pwenabled;    SECKEYKeyDBHandle *keydb;        keydb = SECKEY_GetDefaultKeyDB();    pwenabled = PR_FALSE;    *pwitem = NULL;    if (SECKEY_HasKeyDBPassword (keydb) == SECSuccess) {	*pwitem = SECKEY_HashPassword("", keydb->global_salt);	if ( *pwitem ) {	    if (SECKEY_CheckKeyDBPassword (keydb, *pwitem) == SECSuccess) {		pwenabled = PR_TRUE;	    } else {	    	SECITEM_ZfreeItem(*pwitem, PR_TRUE);		*pwitem = NULL;	    }	}    }    return pwenabled;}/* * ******************** Object Creation Utilities *************************** *//* Make sure a given attribute exists. If it doesn't, initialize it to * value and len */CK_RVpk11_defaultAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value,							unsigned int len){    if ( !pk11_hasAttribute(object, type)) {	return pk11_AddAttributeType(object,type,value,len);    }    return CKR_OK;}/* * check the consistancy and initialize a Data Object  */static CK_RVpk11_handleDataObject(PK11Session *session,PK11Object *object){    CK_RV crv;    /* first reject private and token data objects */    if (pk11_isTrue(object,CKA_PRIVATE) || pk11_isTrue(object,CKA_TOKEN)) {	return CKR_ATTRIBUTE_VALUE_INVALID;    }    /* now just verify the required date fields */    crv = pk11_defaultAttribute(object,CKA_APPLICATION,NULL,0);    if (crv != CKR_OK) return crv;    crv = pk11_defaultAttribute(object,CKA_VALUE,NULL,0);    if (crv != CKR_OK) return crv;    return CKR_OK;}/* * check the consistancy and initialize a Certificate Object  */static CK_RVpk11_handleCertObject(PK11Session *session,PK11Object *object){    PK11Attribute *attribute;    CK_CERTIFICATE_TYPE type;    SECItem derCert;    char *label;    CERTCertDBHandle *handle;    CERTCertificate *cert;    CK_RV crv;    /* certificates must have a type */    if ( !pk11_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) {	return CKR_TEMPLATE_INCOMPLETE;    }    /* we can't store any certs private */    if (pk11_isTrue(object,CKA_PRIVATE)) {	return CKR_ATTRIBUTE_VALUE_INVALID;    }	    /* We only support X.509 Certs for now */    attribute = pk11_FindAttribute(object,CKA_CERTIFICATE_TYPE);    if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;    type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue;    pk11_FreeAttribute(attribute);    if (type != CKC_X_509) {	return CKR_ATTRIBUTE_VALUE_INVALID;    }    /* X.509 Certificate */    /* make sure we have a cert */    if ( !pk11_hasAttribute(object,CKA_VALUE) ) {	return CKR_TEMPLATE_INCOMPLETE;    }    /* in PKCS #11, Subject is a required field */    if ( !pk11_hasAttribute(object,CKA_SUBJECT) ) {	return CKR_TEMPLATE_INCOMPLETE;    }    /*     * now parse the certificate     */    handle = CERT_GetDefaultCertDB();    /* get the nickname */    label = pk11_getString(object,CKA_LABEL);    object->label = label;    if (label == NULL) {	return CKR_HOST_MEMORY;    }      /* get the der cert */     attribute = pk11_FindAttribute(object,CKA_VALUE);    derCert.data = (unsigned char *)attribute->attrib.pValue;    derCert.len = attribute->attrib.ulValueLen ;        cert = CERT_NewTempCertificate(handle, &derCert, label, PR_FALSE, PR_TRUE);    pk11_FreeAttribute(attribute);    if (cert == NULL) {	return CKR_ATTRIBUTE_VALUE_INVALID;    }    /* add it to the object */    object->objectInfo = cert;    object->infoFree = (PK11Free) CERT_DestroyCertificate;        /* now just verify the required date fields */    crv = pk11_defaultAttribute(object, CKA_ID, NULL, 0);    if (crv != CKR_OK) { return crv; }    crv = pk11_defaultAttribute(object,CKA_ISSUER,				pk11_item_expand(&cert->derIssuer));    if (crv != CKR_OK) { return crv; }    crv = pk11_defaultAttribute(object,CKA_SERIAL_NUMBER,				pk11_item_expand(&cert->serialNumber));    if (crv != CKR_OK) { return crv; }    if (pk11_isTrue(object,CKA_TOKEN)) {	SECCertUsage *certUsage = NULL;	CERTCertTrust trust = { CERTDB_USER, CERTDB_USER, CERTDB_USER };	attribute = pk11_FindAttribute(object,CKA_NETSCAPE_TRUST);	if(attribute) {	    certUsage = (SECCertUsage*)attribute->attrib.pValue;	    pk11_FreeAttribute(attribute);	}	/* Temporary for PKCS 12 */	if(cert->nickname == NULL) {	    /* use the arena so we at least don't leak memory  */	    cert->nickname = (char *)PORT_ArenaAlloc(cert->arena,							PORT_Strlen(label)+1);	    if(cert->nickname == NULL) {		return CKR_HOST_MEMORY;	    }	    PORT_Memcpy(cert->nickname, label, PORT_Strlen(label));	}	/* only add certs that have a private key */	if (SECKEY_KeyForCertExists(SECKEY_GetDefaultKeyDB(),cert) 							!= SECSuccess) {	    return CKR_ATTRIBUTE_VALUE_INVALID;	}	if (CERT_AddTempCertToPerm(cert, label, &trust) != SECSuccess) {	    return CKR_HOST_MEMORY;	}	if(certUsage) {	    if(CERT_ChangeCertTrustByUsage(CERT_GetDefaultCertDB(),				cert, *certUsage) != SECSuccess) {		return CKR_HOST_MEMORY;	    }	}	object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);	object->inDB = PR_TRUE;    }    /* label has been adopted by object->label */    /*PORT_Free(label); */    return CKR_OK;}SECKEYLowPublicKey * pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key);/* * check the consistancy and initialize a Public Key Object  */static CK_RVpk11_handlePublicKeyObject(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_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;	}	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;	}	encrypt = CK_FALSE;	recover = CK_FALSE;	wrap = CK_FALSE;	break;    case CKK_DH:    default:	return CKR_ATTRIBUTE_VALUE_INVALID;    }    /* make sure the required fields exist */    crv = pk11_defaultAttribute(object,CKA_SUBJECT,NULL,0);    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_VERIFY_RECOVER,						&recover,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     crv = pk11_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));    if (crv != CKR_OK)  return crv;     object->objectInfo = pk11_GetPubKey(object,key_type);    object->infoFree = (PK11Free) SECKEY_LowDestroyPublicKey;    if (pk11_isTrue(object,CKA_TOKEN)) {        object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);    }    return CKR_OK;}/* 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. All callers * should include this comment. */static SECItem *pk11_GetPubItem(SECKEYPublicKey *pubKey) {    SECItem *pubItem = NULL;    /* get value to compare from the cert's public key */    switch ( pubKey->keyType ) {    case rsaKey:	    pubItem = &pubKey->u.rsa.modulus;	    break;    case dsaKey:	    pubItem = &pubKey->u.dsa.publicValue;	    break;    default:	    break;    }    return pubItem;}typedef struct {    CERTCertificate *cert;    SECItem *pubKey;} find_cert_callback_arg;static SECStatusfind_cert_by_pub_key(CERTCertificate *cert, SECItem *k, void *arg){    find_cert_callback_arg *cbarg;    SECKEYPublicKey *pubKey = NULL;    SECItem *pubItem;    if((cert == NULL) || (arg == NULL)) {	return SECFailure;    }    /* if this cert doesn't look like a user cert, we aren't interested */    if (!((cert->isperm) && (cert->trust) &&     	  (( cert->trust->sslFlags & CERTDB_USER ) ||	   ( cert->trust->emailFlags & CERTDB_USER ) ||	   ( cert->trust->objectSigningFlags & CERTDB_USER )) &&					  ( cert->nickname != NULL ) ) ) {	goto done;    }    /* get cert's public key */    pubKey = CERT_ExtractPublicKey(cert);    if ( pubKey == NULL ) {	goto done;    }    /* 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. All callers     * should include this comment.     */    pubItem = pk11_GetPubItem(pubKey);    if (pubItem == NULL) goto done;        cbarg = (find_cert_callback_arg *)arg;    if(SECITEM_CompareItem(pubItem, cbarg->pubKey) == SECEqual) {	cbarg->cert = CERT_DupCertificate(cert);	return SECFailure;    }done:    if ( pubKey ) {	SECKEY_DestroyPublicKey(pubKey);    }    return (SECSuccess);}static PK11Object *pk11_importCertificate(PK11Slot *slot,CERTCertificate *cert,		 unsigned char *data, unsigned int size, PRBool needCert);/*  * find a cert associated with the key and load it. */static SECStatusreload_existing_certificate(PK11Object *privKeyObject,SECItem *pubKey){    find_cert_callback_arg cbarg;    SECItem nickName;    CERTCertificate *cert = NULL;    CK_RV crv;    SECStatus rv;		        cbarg.pubKey = pubKey;    cbarg.cert = NULL;

⌨️ 快捷键说明

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