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