NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportCRL ( NSSToken *token, nssSession *sessionOpt, NSSDER *subject, NSSDER *encoding, PRBool isKRL, NSSUTF8 *url, PRBool asTokenObject ) { nssCryptokiObject *object; CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE crl_tmpl[6]; CK_ULONG crlsize; NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize); if (asTokenObject) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url); if (isKRL) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false); } NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize); /* import the crl object onto the token */ object = import_object(token, sessionOpt, crl_tmpl, crlsize); if (object && token->cache) { nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, crl_tmpl, crlsize); } return object; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_FindTrustForCertificate ( NSSToken *token, nssSession *sessionOpt, NSSDER *certEncoding, NSSDER *certIssuer, NSSDER *certSerial, nssTokenSearchType searchType ) { CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE tobj_template[5]; CK_ULONG tobj_size; nssSession *session = sessionOpt ? sessionOpt : token->defaultSession; nssCryptokiObject *object = NULL, **objects; /* Don't ask the module to use an invalid session handle. */ if (!session || session->handle == CK_INVALID_SESSION) { PORT_SetError(SEC_ERROR_NO_TOKEN); return object; } NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); if (searchType == nssTokenSearchType_TokenOnly) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial); NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); objects = find_objects_by_template(token, session, tobj_template, tobj_size, 1, NULL); if (objects) { object = objects[0]; nss_ZFreeIf(objects); } return object; }
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; }
NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportTrust ( NSSToken *tok, nssSession *sessionOpt, NSSDER *certEncoding, NSSDER *certIssuer, NSSDER *certSerial, nssTrustLevel serverAuth, nssTrustLevel clientAuth, nssTrustLevel codeSigning, nssTrustLevel emailProtection, PRBool stepUpApproved, PRBool asTokenObject ) { nssCryptokiObject *object; CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST; CK_TRUST ckSA, ckCA, ckCS, ckEP; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE trust_tmpl[11]; CK_ULONG tsize; PRUint8 sha1[20]; /* this is cheating... */ PRUint8 md5[16]; NSSItem sha1_result, md5_result; sha1_result.data = sha1; sha1_result.size = sizeof sha1; md5_result.data = md5; md5_result.size = sizeof md5; sha1_hash(certEncoding, &sha1_result); md5_hash(certEncoding, &md5_result); ckSA = get_ck_trust(serverAuth); ckCA = get_ck_trust(clientAuth); ckCS = get_ck_trust(codeSigning); ckEP = get_ck_trust(emailProtection); NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); if (asTokenObject) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); /* now set the trust values */ NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP); if (stepUpApproved) { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, &g_ck_true); } else { NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED, &g_ck_false); } NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); /* import the trust object onto the token */ object = import_object(tok, sessionOpt, trust_tmpl, tsize); if (object && tok->cache) { nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, trust_tmpl, tsize); } return object; }
NSS_IMPLEMENT PRStatus nssCryptokiTrust_GetAttributes( nssCryptokiObject *trustObject, nssSession *sessionOpt, NSSItem *sha1_hash, nssTrustLevel *serverAuth, nssTrustLevel *clientAuth, nssTrustLevel *codeSigning, nssTrustLevel *emailProtection, PRBool *stepUpApproved) { PRStatus status; NSSSlot *slot; nssSession *session; CK_BBOOL isToken = PR_FALSE; CK_BBOOL stepUp = PR_FALSE; CK_TRUST saTrust = CKT_NSS_TRUST_UNKNOWN; CK_TRUST caTrust = CKT_NSS_TRUST_UNKNOWN; CK_TRUST epTrust = CKT_NSS_TRUST_UNKNOWN; CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE trust_template[7]; CK_ATTRIBUTE_PTR sha1_hash_attr; CK_ULONG trust_size; /* Use the trust object to find the trust settings */ NSS_CK_TEMPLATE_START(trust_template, attr, trust_size); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp); sha1_hash_attr = attr; NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, sha1_hash); NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL, trustObject, CKO_NSS_TRUST, trust_template, trust_size); if (status != PR_SUCCESS) { session = sessionOpt ? sessionOpt : nssToken_GetDefaultSession(trustObject->token); if (!session) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FAILURE; } slot = nssToken_GetSlot(trustObject->token); status = nssCKObject_GetAttributes(trustObject->handle, trust_template, trust_size, NULL, session, slot); nssSlot_Destroy(slot); if (status != PR_SUCCESS) { return status; } } if (sha1_hash_attr->ulValueLen == -1) { /* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */ sha1_hash_attr->ulValueLen = 0; } sha1_hash->size = sha1_hash_attr->ulValueLen; *serverAuth = get_nss_trust(saTrust); *clientAuth = get_nss_trust(caTrust); *emailProtection = get_nss_trust(epTrust); *codeSigning = get_nss_trust(csTrust); *stepUpApproved = stepUp; return PR_SUCCESS; }