NSS_IMPLEMENT PRStatus nssCryptokiCRL_GetAttributes( nssCryptokiObject *crlObject, nssSession *sessionOpt, NSSArena *arenaOpt, NSSItem *encodingOpt, NSSItem *subjectOpt, CK_ULONG *crl_class, NSSUTF8 **urlOpt, PRBool *isKRLOpt) { PRStatus status; NSSSlot *slot; nssSession *session; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE crl_template[7]; CK_ULONG crl_size; PRUint32 i; NSS_CK_TEMPLATE_START(crl_template, attr, crl_size); if (crl_class) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS); } if (encodingOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); } if (urlOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_URL); } if (isKRLOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_KRL); } if (subjectOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT); } NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size); status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL, crlObject, CKO_NSS_CRL, crl_template, crl_size); if (status != PR_SUCCESS) { session = sessionOpt ? sessionOpt : nssToken_GetDefaultSession(crlObject->token); if (session == NULL) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FAILURE; } slot = nssToken_GetSlot(crlObject->token); status = nssCKObject_GetAttributes(crlObject->handle, crl_template, crl_size, arenaOpt, session, slot); nssSlot_Destroy(slot); if (status != PR_SUCCESS) { return status; } } i = 0; if (crl_class) { NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); i++; } if (encodingOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++; } if (urlOpt) { NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++; } if (isKRLOpt) { NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++; } if (subjectOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++; } return PR_SUCCESS; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportCertificate ( NSSToken *tok, nssSession *sessionOpt, NSSCertificateType certType, NSSItem *id, const NSSUTF8 *nickname, NSSDER *encoding, NSSDER *issuer, NSSDER *subject, NSSDER *serial, NSSASCII7 *email, PRBool asTokenObject ) { PRStatus status; CK_CERTIFICATE_TYPE cert_type; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_tmpl[10]; CK_ULONG ctsize; nssTokenSearchType searchType; nssCryptokiObject *rvObject = NULL; if (!tok) { PORT_SetError(SEC_ERROR_NO_TOKEN); return NULL; } if (certType == NSSCertificateType_PKIX) { cert_type = CKC_X_509; } else { return (nssCryptokiObject *)NULL; } NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); if (asTokenObject) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); searchType = nssTokenSearchType_TokenOnly; } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); searchType = nssTokenSearchType_SessionOnly; } NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); if (email) { NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email); } NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); /* see if the cert is already there */ rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok, sessionOpt, issuer, serial, searchType, NULL); if (rvObject) { NSSItem existingDER; NSSSlot *slot = nssToken_GetSlot(tok); nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE); if (!session) { nssCryptokiObject_Destroy(rvObject); nssSlot_Destroy(slot); return (nssCryptokiObject *)NULL; } /* Reject any attempt to import a new cert that has the same * issuer/serial as an existing cert, but does not have the * same encoding */ NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); status = nssCKObject_GetAttributes(rvObject->handle, cert_tmpl, ctsize, NULL, session, slot); NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); if (status == PR_SUCCESS) { if (!nssItem_Equal(encoding, &existingDER, NULL)) { nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); status = PR_FAILURE; } nss_ZFreeIf(existingDER.data); } if (status == PR_FAILURE) { nssCryptokiObject_Destroy(rvObject); nssSession_Destroy(session); nssSlot_Destroy(slot); return (nssCryptokiObject *)NULL; } /* according to PKCS#11, label, ID, issuer, and serial number * may change after the object has been created. For PKIX, the * last two attributes can't change, so for now we'll only worry * about the first two. */ NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); /* reset the mutable attributes on the token */ nssCKObject_SetAttributes(rvObject->handle, cert_tmpl, ctsize, session, slot); if (!rvObject->label && nickname) { rvObject->label = nssUTF8_Duplicate(nickname, NULL); } nssSession_Destroy(session); nssSlot_Destroy(slot); } else { /* Import the certificate onto the token */ rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); } if (rvObject && tok->cache) { /* The cache will overwrite the attributes if the object already * exists. */ nssTokenObjectCache_ImportObject(tok->cache, rvObject, CKO_CERTIFICATE, cert_tmpl, ctsize); } return rvObject; }
/* incoming pointers must be valid */ NSS_IMPLEMENT PRStatus nssCryptokiCertificate_GetAttributes( nssCryptokiObject *certObject, nssSession *sessionOpt, NSSArena *arenaOpt, NSSCertificateType *certTypeOpt, NSSItem *idOpt, NSSDER *encodingOpt, NSSDER *issuerOpt, NSSDER *serialOpt, NSSDER *subjectOpt) { PRStatus status; PRUint32 i; nssSession *session; NSSSlot *slot; CK_ULONG template_size; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_template[6]; /* Set up a template of all options chosen by caller */ NSS_CK_TEMPLATE_START(cert_template, attr, template_size); if (certTypeOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE); } if (idOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID); } if (encodingOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); } if (issuerOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER); } if (serialOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER); } if (subjectOpt) { NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT); } NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size); if (template_size == 0) { /* caller didn't want anything */ return PR_SUCCESS; } status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt, certObject, CKO_CERTIFICATE, cert_template, template_size); if (status != PR_SUCCESS) { session = sessionOpt ? sessionOpt : nssToken_GetDefaultSession(certObject->token); if (!session) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FAILURE; } slot = nssToken_GetSlot(certObject->token); status = nssCKObject_GetAttributes(certObject->handle, cert_template, template_size, arenaOpt, session, slot); nssSlot_Destroy(slot); if (status != PR_SUCCESS) { return status; } } i = 0; if (certTypeOpt) { *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++; } if (idOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++; } if (encodingOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++; } if (issuerOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++; } if (serialOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++; } if (subjectOpt) { NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++; } return PR_SUCCESS; }