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