pk11cert.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,345 行 · 第 1/5 页
C
2,345 行
CERTCertificate * cert; SECOidData *oid; SECStatus rv1 = SECSuccess; SECStatus rv2 = SECSuccess; if (slot->cert_array) { for (i=0; i < slot->cert_count; i++) { cert = slot->cert_array[i]; oid = SECOID_FindOID(&cert->subjectPublicKeyInfo.algorithm.algorithm); if (oid != NULL) { tag = oid->offset; /* Check if cert has a DSA or Fortezza public key */ if ( (tag == SEC_OID_MISSI_KEA_DSS_OLD) || (tag == SEC_OID_MISSI_DSS_OLD) || (tag == SEC_OID_MISSI_KEA_DSS) || (tag == SEC_OID_MISSI_DSS) || (tag == SEC_OID_ANSIX9_DSA_SIGNATURE) || (tag == SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) || (tag == SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) ) { /* update PQG parameters */ rv1 = SECKEY_UpdateCertPQG(cert); if (rv1 == SECFailure) { rv2 = rv1; } } } /* end of if oid != NULL */ } /* end of for loop */ } return rv2;}/* * Extract all the certs on a card from a slot. */static SECStatuspk11_ExtractCertsFromSlot(PK11SlotInfo *slot, void *arg){ pk11TraverseSlotCert *slotcb = (pk11TraverseSlotCert *) arg; int object_count; SECStatus rv; rv = SECSuccess; PK11_FreeSlotCerts(slot); object_count = PK11_NumberObjectsFor(slot,slotcb->findTemplate, slotcb->templateCount); /*Actually this isn't a failure... there just were no certs to be found*/ if (object_count == 0) { return SECSuccess; } slot->cert_array = (CERTCertificate **) PORT_Alloc(sizeof(CERTCertificate *)*object_count); if (slot->cert_array == NULL) { return SECFailure; } slot->cert_count = 0; slot->array_size = object_count; PK11_TraverseSlot(slot,arg); /* Update the PQG parameters for the extracted certs. */ rv = pk11_UpdateSlotPQG(slot); return rv;}/* * read all the certs from a slot */SECStatusPK11_ReadSlotCerts(PK11SlotInfo *slot){ /* build slot list */ pk11CertCallback caller; pk11DoCertCallback saver; pk11TraverseSlotCert creater; CK_ATTRIBUTE theTemplate; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass)); caller.callback = NULL; caller.callbackArg = NULL; saver.callback = pk11_SaveCert; saver.noslotcallback = NULL; saver.callbackArg = (void *) & caller; creater.callback = pk11_DoCerts; creater.callbackArg = (void *) & saver; creater.findTemplate = &theTemplate; creater.templateCount = 1; return pk11_ExtractCertsFromSlot(slot, &creater);}/* * Extract all the certs on a card from a slot. */static SECStatuspk11_TraverseAllSlots(PRBool loadCerts, SECStatus (*callback)(PK11SlotInfo *,void *),void *arg,void *wincx) { PK11SlotList *list; PK11SlotListElement *le; SECStatus rv; /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,loadCerts,wincx); if (list == NULL) return SECFailure; /* look at each slot and authenticate as necessary */ for (le = list->head ; le; le = le->next) { /* don't nab internal slots */ if ((!loadCerts) && le->slot->isInternal == PR_TRUE) { continue; } if (loadCerts || !PK11_IsFriendly(le->slot)) { rv = PK11_Authenticate(le->slot, loadCerts, wincx); if (rv != SECSuccess) continue; } (*callback)(le->slot,arg); } PK11_FreeSlotList(list); return SECSuccess;}/* * Extract all the certs on a card from a slot. */SECStatusPK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *), void *arg, void *wincx) { pk11CertCallback caller; pk11DoCertCallback saver; pk11TraverseSlotCert creater; CK_ATTRIBUTE theTemplate; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass)); caller.callback = callback; caller.callbackArg = arg; saver.callback = pk11_SaveCert; saver.noslotcallback = NULL; saver.callbackArg = (void *) & caller; creater.callback = pk11_DoCerts; creater.callbackArg = (void *) & saver; creater.findTemplate = &theTemplate; creater.templateCount = 1; return pk11_TraverseAllSlots(PR_FALSE, pk11_ExtractCertsFromSlot, &creater, wincx);}CK_OBJECT_HANDLE *PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr, CK_OBJECT_CLASS objclass, int *returnCount, void *wincx) { char *tokenName; char *delimit; PK11SlotInfo *slot; CK_OBJECT_HANDLE *objID; CK_ATTRIBUTE findTemplate[] = { { CKA_LABEL, NULL, 0}, { CKA_CLASS, NULL, 0}, }; int findCount = sizeof(findTemplate)/sizeof(findTemplate[0]); SECStatus rv; PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass)); *slotptr = slot = NULL; *returnCount = 0; /* first find the slot associated with this nickname */ if ((delimit = PORT_Strchr(nickname,':')) != NULL) { int len = delimit - nickname; tokenName = (char*)PORT_Alloc(len+1); PORT_Memcpy(tokenName,nickname,len); tokenName[len] = 0; slot = *slotptr = PK11_FindSlotByName(tokenName); PORT_Free(tokenName); /* if we couldn't find a slot, assume the nickname is an internal cert * with no proceding slot name */ if (slot == NULL) { slot = *slotptr = PK11_GetInternalKeySlot(); } else { nickname = delimit+1; } } else { *slotptr = slot = PK11_GetInternalKeySlot(); } if (slot == NULL) { return CK_INVALID_KEY; } if (!PK11_IsFriendly(slot)) { rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) { PK11_FreeSlot(slot); *slotptr = NULL; return CK_INVALID_KEY; } } findTemplate[0].pValue = nickname; findTemplate[0].ulValueLen = PORT_Strlen(nickname); objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount,returnCount); if (objID == NULL) { /* PKCS #11 isn't clear on whether or not the NULL is * stored in the template.... try the find again with the * full null terminated string. */ findTemplate[0].ulValueLen += 1; objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount, returnCount); if (objID == NULL) { /* Well that's the best we can do. It's just not here */ /* what about faked nicknames? */ PK11_FreeSlot(slot); *slotptr = NULL; *returnCount = 0; } } return objID;} CERTCertificate *PK11_FindCertFromNickname(char *nickname, void *wincx) { PK11SlotInfo *slot; int count=0; CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot, CKO_CERTIFICATE, &count, wincx); CERTCertificate *cert; if (certID == CK_INVALID_KEY) return NULL; cert = PK11_MakeCertFromHandle(slot,certID[0],NULL); PK11_FreeSlot(slot); PORT_Free(certID); return cert;}CERTCertList *PK11_FindCertsFromNickname(char *nickname, void *wincx) { PK11SlotInfo *slot; int i,count = 0; CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot, CKO_CERTIFICATE, &count, wincx); CERTCertList *certList = NULL; if (certID == NULL) return NULL; certList= CERT_NewCertList(); for (i=0; i < count; i++) { CERTCertificate *cert = PK11_MakeCertFromHandle(slot,certID[i],NULL); if (cert) CERT_AddCertToListTail(certList,cert); } if (CERT_LIST_HEAD(certList) == NULL) { CERT_DestroyCertList(certList); certList = NULL; } PK11_FreeSlot(slot); PORT_Free(certID); return certList;}/* * extract a key ID for a certificate... * NOTE: We call this function from PKCS11.c If we ever use * pkcs11 to extract the public key (we currently do not), this will break. */SECItem *PK11_GetPubIndexKeyID(CERTCertificate *cert) { SECKEYPublicKey *pubk; SECItem *newItem = NULL; pubk = CERT_ExtractPublicKey(cert); if (pubk == NULL) return NULL; switch (pubk->keyType) { case rsaKey: newItem = SECITEM_DupItem(&pubk->u.rsa.modulus); break; case dsaKey: newItem = SECITEM_DupItem(&pubk->u.dsa.publicValue); break; case dhKey: newItem = SECITEM_DupItem(&pubk->u.dh.publicValue); case fortezzaKey: default: newItem = NULL; /* Fortezza Fix later... */ } SECKEY_DestroyPublicKey(pubk); /* make hash of it */ return newItem;}/* * generate a CKA_ID from a certificate. */SECItem *pk11_mkcertKeyID(CERTCertificate *cert) { SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert) ; SECItem *certCKA_ID; if (pubKeyData == NULL) return NULL; certCKA_ID = PK11_MakeIDFromPubKey(pubKeyData); SECITEM_FreeItem(pubKeyData,PR_TRUE); return certCKA_ID;}/* * Generate a CKA_ID from the relevant public key data. The CKA_ID is generated * from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make * smart cards happy. */SECItem *PK11_MakeIDFromPubKey(SECItem *pubKeyData) { PK11Context *context; SECItem *certCKA_ID; SECStatus rv; context = PK11_CreateDigestContext(SEC_OID_SHA1); if (context == NULL) { return NULL; } rv = PK11_DigestBegin(context); if (rv == SECSuccess) { rv = PK11_DigestOp(context,pubKeyData->data,pubKeyData->len); } if (rv != SECSuccess) { PK11_DestroyContext(context,PR_TRUE); return NULL; } certCKA_ID = (SECItem *)PORT_Alloc(sizeof(SECItem)); if (certCKA_ID == NULL) { PK11_DestroyContext(context,PR_TRUE); return NULL; } certCKA_ID->len = SHA1_LENGTH; certCKA_ID->data = (unsigned char*)PORT_Alloc(certCKA_ID->len); if (certCKA_ID->data == NULL) { PORT_Free(certCKA_ID); PK11_DestroyContext(context,PR_TRUE); return NULL; } rv = PK11_DigestFinal(context,certCKA_ID->data,&certCKA_ID->len, SHA1_LENGTH); PK11_DestroyContext(context,PR_TRUE); if (rv != SECSuccess) { SECITEM_FreeItem(certCKA_ID,PR_TRUE); return NULL; } return certCKA_ID;}/* * Write the cert into the token. */SECStatusPK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust) { int len = 0; SECItem *keyID = pk11_mkcertKeyID(cert); CK_ATTRIBUTE keyAttrs[] = { { CKA_LABEL, NULL, 0}, { CKA_SUBJECT, NULL, 0}, }; CK_OBJECT_CLASS certc = CKO_CERTIFICATE; CK_CERTIFICATE_TYPE certType = CKC_X_509; CK_OBJECT_HANDLE certID; CK_SESSION_HANDLE rwsession; CK_BBOOL cktrue = CK_TRUE; SECStatus rv = SECFailure; CK_ATTRIBUTE certAttrs[] = { { CKA_ID, NULL, 0 }, { CKA_LABEL, NULL, 0}, { CKA_CLASS, NULL, 0}, { CKA_TOKEN, NULL, 0}, { CKA_CERTIFICATE_TYPE, NULL, 0}, { CKA_SUBJECT, NULL, 0}, { CKA_ISSUER, NULL, 0}, { CKA_SERIAL_NUMBER, NULL, 0}, { CKA_VALUE, NULL, 0}, { CKA_NETSCAPE_TRUST, NULL, 0}, }; int certCount = sizeof(certAttrs)/sizeof(certAttrs[0]), keyCount = 2; CK_ATTRIBUTE *attrs; CK_RV crv; SECCertUsage *certUsage = NULL; if (keyID == NULL) { PORT_SetError(SEC_ERROR_ADDING_CERT); return rv; } len = ((nickname) ? PORT_Strlen(nickname) : 0); attrs = certAttrs; PK11_SETATTRS(attrs,CKA_ID, keyID->data, keyID->len); attrs++; if(nickname) { PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++; } PK11_SETATTRS(attrs,CKA_CLASS, &certc, sizeof(certc) ); attrs++; PK11_SETATTRS(attrs,CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++; PK11_SETATTRS(attrs,CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)); attrs++; PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data, cert->derSubject.len ); attrs++; PK11_SETATTRS(attrs,CKA_ISSUER, cert->derIssuer.data, cert->derIssuer.len ); attrs++; PK11_SETATTRS(attrs,CKA_SERIAL_NUMBER, cert->serialNumber.data, cert->serialNumber.len); attrs++; PK11_SETATTRS(attrs,CKA_VALUE, cert->derCert.data, cert->derCert.len); if(includeTrust && PK11_IsInternal(slot)) { attrs++; certUsage = (SECCertUsage*)PORT_Alloc(sizeof(SECCertUsage)); if(!certUsage) { SECITEM_FreeItem(keyID,PR_TRUE); PORT_SetError(SEC_ERROR_NO_MEMORY); return rv; } *certUsage = certUsageUserCertImport; PK11_SETATTRS(attrs,CKA_NETSCAPE_TRUST, certUsage, sizeof(SECCertUsage)); } else { certCount--; } attrs = keyAttrs; if(nickname) { PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++; } PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data, cert->derSubject.len ); if(!nickname) { certCount--; keyCount--; } rwsession = PK11_GetRWSession(slot); crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession,key,keyAttrs, keyCount); if (crv != CKR_OK) { PORT_SetError( PK11_MapError(crv) ); goto done; } crv = PK11_GETTAB(slot)->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?