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