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