pk11cert.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,345 行 · 第 1/5 页
C
2,345 行
C_CreateObject(rwsession,certAttrs,certCount,&certID); if (crv == CKR_OK) { rv = SECSuccess; } else { PORT_SetError( PK11_MapError(crv) ); }done: SECITEM_FreeItem(keyID,PR_TRUE); PK11_RestoreROSession(slot,rwsession); if(certUsage) { PORT_Free(certUsage); } return rv;}/* * get a certificate handle, look at the cached handle first.. */CK_OBJECT_HANDLEpk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert, CK_ATTRIBUTE *theTemplate,int tsize){ CK_OBJECT_HANDLE certh; if (cert->slot == slot) { certh = cert->pkcs11ID; if (certh == CK_INVALID_KEY) { certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize); cert->pkcs11ID = certh; } } else { certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize); } return certh;}/* * return the private key From a given Cert */SECKEYPrivateKey *PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx) { CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_ATTRIBUTE theTemplate[] = { { CKA_VALUE, NULL, 0 }, { CKA_CLASS, NULL, 0 } }; /* if you change the array, change the variable below as well */ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); CK_OBJECT_HANDLE certh; CK_OBJECT_HANDLE keyh; CK_ATTRIBUTE *attrs = theTemplate; SECStatus rv; PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, cert->derCert.len); attrs++; PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); /* * issue the find */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) { return NULL; } certh = pk11_getcerthandle(slot,cert,theTemplate,tsize); if (certh == CK_INVALID_KEY) { return NULL; } keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY); if (keyh == CK_INVALID_KEY) { return NULL; } return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);} /* * return the private key with the given ID */static CK_OBJECT_HANDLEpk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID) { CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY; CK_ATTRIBUTE theTemplate[] = { { CKA_ID, NULL, 0 }, { CKA_CLASS, NULL, 0 }, }; /* if you change the array, change the variable below as well */ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); CK_ATTRIBUTE *attrs = theTemplate; PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len ); attrs++; PK11_SETATTRS(attrs, CKA_CLASS, &privKey, sizeof(privKey)); return pk11_FindObjectByTemplate(slot,theTemplate,tsize);} /* * import a cert for a private key we have already generated. Set the label * on both to be the nickname. This is for the Key Gen, orphaned key case. */PK11SlotInfo *PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, void *wincx) { PK11SlotList *list; PK11SlotListElement *le; SECItem *keyID; CK_OBJECT_HANDLE key; PK11SlotInfo *slot = NULL; SECStatus rv; keyID = pk11_mkcertKeyID(cert); /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if ((keyID == NULL) || (list == NULL)) { if (keyID) SECITEM_FreeItem(keyID,PR_TRUE); if (list) PK11_FreeSlotList(list); return NULL; } /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; key = pk11_FindPrivateKeyFromCertID(le->slot,keyID); if (key != CK_INVALID_KEY) { slot = PK11_ReferenceSlot(le->slot); if (keyPtr) *keyPtr = key; break; } } SECITEM_FreeItem(keyID,PR_TRUE); PK11_FreeSlotList(list); return slot;}PK11SlotInfo *PK11_ImportCertForKey(CERTCertificate *cert, char *nickname,void *wincx) { PK11SlotInfo *slot = NULL; CK_OBJECT_HANDLE key; slot = PK11_KeyForCertExists(cert,&key,wincx); if (slot) { if (PK11_ImportCert(slot,cert,key,nickname,PR_FALSE) != SECSuccess) { PK11_FreeSlot(slot); slot = NULL; } } else { PORT_SetError(SEC_ERROR_ADDING_CERT); } return slot;}static CK_OBJECT_HANDLEpk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr, CK_ATTRIBUTE *searchTemplate, int count, void *wincx) { PK11SlotList *list; PK11SlotListElement *le; CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY; PK11SlotInfo *slot = NULL; SECStatus rv; *slotPtr = NULL; /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { if (list) PK11_FreeSlotList(list); return CK_INVALID_KEY; } /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { if (!PK11_IsFriendly(le->slot)) { rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; } certHandle = pk11_FindObjectByTemplate(le->slot,searchTemplate,count); if (certHandle != CK_INVALID_KEY) { slot = PK11_ReferenceSlot(le->slot); break; } } PK11_FreeSlotList(list); if (slot == NULL) { return CK_INVALID_KEY; } *slotPtr = slot; return certHandle;}/* * We're looking for a cert which we have the private key for that's on the * list of recipients. This searches one slot. * this is the new version for NSS SMIME code * this stuff should REALLY be in the SMIME code, but some things in here are not public * (they should be!) */static CK_OBJECT_HANDLEpk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist, int *rlIndex){ CK_OBJECT_HANDLE certHandle; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_OBJECT_CLASS peerClass ; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, NULL, 0 }, { CKA_ISSUER, NULL, 0 }, { CKA_SERIAL_NUMBER, NULL, 0} }; int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE); NSSCMSRecipient *ri = NULL; CK_ATTRIBUTE *attrs; int i; peerClass = CKO_PRIVATE_KEY; if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) { peerClass = CKO_PUBLIC_KEY; } for (i=0; (ri = recipientlist[i]) != NULL; i++) { /* XXXXX fixme - not yet implemented! */ if (ri->kind == RLSubjKeyID) continue; attrs = searchTemplate; PK11_SETATTRS(attrs, CKA_CLASS, &certClass,sizeof(certClass)); attrs++; PK11_SETATTRS(attrs, CKA_ISSUER, ri->id.issuerAndSN->derIssuer.data, ri->id.issuerAndSN->derIssuer.len); attrs++; PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER, ri->id.issuerAndSN->serialNumber.data,ri->id.issuerAndSN->serialNumber.len); certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count); if (certHandle != CK_INVALID_KEY) { CERTCertificate *cert = pk11_fastCert(slot,certHandle,NULL,NULL); if (PK11_IsUserCert(slot,cert,certHandle)) { /* we've found a cert handle, now let's see if there is a key * associated with it... */ ri->slot = PK11_ReferenceSlot(slot); *rlIndex = i; CERT_DestroyCertificate(cert); return certHandle; } CERT_DestroyCertificate(cert); } } *rlIndex = -1; return CK_INVALID_KEY;}/* * This function is the same as above, but it searches all the slots. * this is the new version for NSS SMIME code * this stuff should REALLY be in the SMIME code, but some things in here are not public * (they should be!) */static CK_OBJECT_HANDLEpk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *wincx, int *rlIndex){ PK11SlotList *list; PK11SlotListElement *le; CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY; PK11SlotInfo *slot = NULL; SECStatus rv; /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { if (list) PK11_FreeSlotList(list); return CK_INVALID_KEY; } /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { if ( !PK11_IsFriendly(le->slot)) { rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; } certHandle = pk11_FindCertObjectByRecipientNew(le->slot, recipientlist, rlIndex); if (certHandle != CK_INVALID_KEY) break; } PK11_FreeSlotList(list); return (le == NULL) ? CK_INVALID_KEY : certHandle;}/* * We're looking for a cert which we have the private key for that's on the * list of recipients. This searches one slot. */static CK_OBJECT_HANDLEpk11_FindCertObjectByRecipient(PK11SlotInfo *slot, SEC_PKCS7RecipientInfo **recipientArray,SEC_PKCS7RecipientInfo **rip){ CK_OBJECT_HANDLE certHandle; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_OBJECT_CLASS peerClass ; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, NULL, 0 }, { CKA_ISSUER, NULL, 0 }, { CKA_SERIAL_NUMBER, NULL, 0} }; int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE); SEC_PKCS7RecipientInfo *ri = NULL; CK_ATTRIBUTE *attrs; int i; peerClass = CKO_PRIVATE_KEY; if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) { peerClass = CKO_PUBLIC_KEY; } for (i=0; (ri = recipientArray[i]) != NULL; i++) { attrs = searchTemplate; PK11_SETATTRS(attrs, CKA_CLASS, &certClass,sizeof(certClass)); attrs++; PK11_SETATTRS(attrs, CKA_ISSUER, ri->issuerAndSN->derIssuer.data, ri->issuerAndSN->derIssuer.len); attrs++; PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER, ri->issuerAndSN->serialNumber.data,ri->issuerAndSN->serialNumber.len); certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count); if (certHandle != CK_INVALID_KEY) { CERTCertificate *cert = pk11_fastCert(slot,certHandle,NULL,NULL); if (PK11_IsUserCert(slot,cert,certHandle)) { /* we've found a cert handle, now let's see if there is a key * associated with it... */ *rip = ri; CERT_DestroyCertificate(cert); return certHandle; } CERT_DestroyCertificate(cert); } } *rip = NULL; return CK_INVALID_KEY;}/* * This function is the same as above, but it searches all the slots. */static CK_OBJECT_HANDLEpk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr, SEC_PKCS7RecipientInfo **recipientArray,SEC_PKCS7RecipientInfo **rip, void *wincx) { PK11SlotList *list; PK11SlotListElement *le; CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY; PK11SlotInfo *slot = NULL; SECStatus rv; *slotPtr = NULL; /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { if (list) PK11_FreeSlotList(list); return CK_INVALID_KEY; } *rip = NULL; /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { if ( !PK11_IsFriendly(le->slot)) { rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; } certHandle = pk11_FindCertObjectByRecipient(le->slot, recipientArray,rip); if (certHandle != CK_INVALID_KEY) { slot = PK11_ReferenceSlot(le->slot); break; } } PK11_FreeSlotList(list); if (slot == NULL) { return CK_INVALID_KEY; } *slotPtr = slot; return certHandle;}/* * We need to invert the search logic for PKCS 7 because if we search for * each cert on the list over all the slots, we wind up with lots of spurious * password prompts. This way we get only one password prompt per slot, at * the max, and most of the time we can find the cert, and only prompt for * the key... */CERTCertificate *PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr, SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip, SECKEYPrivateKey**privKey, void *wincx){ CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY; CK_OBJECT_HANDLE keyHandle = CK_INVALID_KEY; PK11SlotInfo *slot = NULL; CERTCertificate *cert = NULL; SECStatus rv; *privKey = NULL; certHandle = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx); if (certHandle == CK_INVALID_KEY) { return NULL; } rv = PK11_Authenticate(*slotPtr,PR_TRUE,wincx); if (rv != SECSuccess) { PK11_FreeSlot(*slotPtr); *slotPtr = NULL; return NULL; } keyHandle = PK11_MatchItem(*slotPtr,certHandle,CKO_PRIVATE_KEY); if (keyHandle == CK_INVALID_KEY) { PK11_FreeSlot(*slotPtr); *slotPtr = NULL; return NULL; } *privKey = PK11_MakePrivKey(*slotPtr, nullKey, PR_TRUE, keyHandle, wincx); if (*privKey == NULL) { PK11_FreeSlot(*slotPtr); *slotPtr = NULL; return NULL; } cert = PK11_MakeCertFromHandle(*slotPtr,certHandle,NULL); if (cert == NULL) { PK11_FreeSlot(*slotPtr); SECKEY_DestroyPrivateKey(*privKey); *slotPtr = NULL; *privKey = NULL; return NULL; } return cert;}/* * This is the new version of the above function for NSS SMIME code * this stuff should REALLY be in the SMIME code, but some things in here are not public * (they should be!) */intPK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx){ CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY; CK_OBJECT_HANDLE keyHandle = CK_INVALID_KEY; SECStatus rv;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?