/* this function should not be a hack; it will be needed in 4.0 (rename) */ NSS_IMPLEMENT NSSItem * STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der) { NSSItem *rvKey; SECItem secDER; SECItem secKey = { 0 }; SECStatus secrv; PLArenaPool *arena; SECITEM_FROM_NSSITEM(&secDER, der); /* nss3 call uses nss3 arena's */ arena = PORT_NewArena(256); if (!arena) { return NULL; } secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey); if (secrv != SECSuccess) { PORT_FreeArena(arena, PR_FALSE); return NULL; } rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data); PORT_FreeArena(arena,PR_FALSE); return rvKey; }
static NSSItem * nss3certificate_getIdentifier(nssDecodedCert *dc) { NSSItem *rvID; CERTCertificate *c = (CERTCertificate *)dc->data; rvID = nssItem_Create(NULL, NULL, c->certKey.len, c->certKey.data); return rvID; }
NSS_IMPLEMENT NSSItem * nssToken_FinishDigest ( NSSToken *tok, nssSession *sessionOpt, NSSItem *rvOpt, NSSArena *arenaOpt ) { CK_RV ckrv; CK_ULONG digestLen; CK_BYTE_PTR digest; NSSItem *rvItem = NULL; void *epv = nssToken_GetCryptokiEPV(tok); nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; /* 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 NULL; } nssSession_EnterMonitor(session); ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen); if (ckrv != CKR_OK || digestLen == 0) { nssSession_ExitMonitor(session); return NULL; } digest = NULL; if (rvOpt) { if (rvOpt->size > 0 && rvOpt->size < digestLen) { nssSession_ExitMonitor(session); /* the error should be bad args */ return NULL; } if (rvOpt->data) { digest = rvOpt->data; } digestLen = rvOpt->size; } if (!digest) { digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); if (!digest) { nssSession_ExitMonitor(session); return NULL; } } ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen); nssSession_ExitMonitor(session); if (ckrv != CKR_OK) { nss_ZFreeIf(digest); return NULL; } if (!rvOpt) { rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); } return rvItem; }
static PRStatus nss3certificate_getDERSerialNumber(nssDecodedCert *dc, NSSDER *serial, NSSArena *arena) { CERTCertificate *cc = (CERTCertificate *)dc->data; SECItem derSerial = { 0 }; SECStatus secrv; secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); if (secrv == SECSuccess) { (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); return PR_SUCCESS; } return PR_FAILURE; }
NSS_IMPLEMENT PRStatus nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena, NSSDER *issuer, NSSDER *serial) { SECStatus secrv; SECItem derCert; SECItem derIssuer = { 0 }; SECItem derSerial = { 0 }; SECITEM_FROM_NSSITEM(&derCert, der); secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial); if (secrv != SECSuccess) { return PR_FAILURE; } (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data); secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer); if (secrv != SECSuccess) { PORT_Free(derSerial.data); return PR_FAILURE; } (void)nssItem_Create(arena, issuer, derIssuer.len, derIssuer.data); PORT_Free(derSerial.data); PORT_Free(derIssuer.data); return PR_SUCCESS; }
NSS_IMPLEMENT NSSItem * nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt) { #ifdef DEBUG if ((NSSArena *)NULL != arenaOpt) { if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) { return (NSSItem *)NULL; } } if ((NSSItem *)NULL == obj) { nss_SetError(NSS_ERROR_INVALID_ITEM); return (NSSItem *)NULL; } #endif /* DEBUG */ return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data); }
NSS_IMPLEMENT NSSItem * nssToken_Digest ( NSSToken *tok, nssSession *sessionOpt, NSSAlgorithmAndParameters *ap, NSSItem *data, NSSItem *rvOpt, NSSArena *arenaOpt ) { CK_RV ckrv; CK_ULONG digestLen; CK_BYTE_PTR digest; NSSItem *rvItem = NULL; void *epv = nssToken_GetCryptokiEPV(tok); nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession; /* 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 rvItem; } nssSession_EnterMonitor(session); ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); return NULL; } #if 0 /* XXX the standard says this should work, but it doesn't */ ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); return NULL; } #endif digestLen = 0; /* XXX for now */ digest = NULL; if (rvOpt) { if (rvOpt->size > 0 && rvOpt->size < digestLen) { nssSession_ExitMonitor(session); /* the error should be bad args */ return NULL; } if (rvOpt->data) { digest = rvOpt->data; } digestLen = rvOpt->size; } if (!digest) { digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen); if (!digest) { nssSession_ExitMonitor(session); return NULL; } } ckrv = CKAPI(epv)->C_Digest(session->handle, (CK_BYTE_PTR)data->data, (CK_ULONG)data->size, (CK_BYTE_PTR)digest, &digestLen); nssSession_ExitMonitor(session); if (ckrv != CKR_OK) { nss_ZFreeIf(digest); return NULL; } if (!rvOpt) { rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest); } return rvItem; }
NSS_EXTERN NSSCertificate * STAN_GetNSSCertificate(CERTCertificate *cc) { NSSCertificate *c; nssCryptokiInstance *instance; nssPKIObject *pkiob; NSSArena *arena; c = cc->nssCertificate; if (c) { return c; } /* i don't think this should happen. but if it can, need to create * NSSCertificate from CERTCertificate values here. */ /* Yup, it can happen. */ arena = NSSArena_Create(); if (!arena) { return NULL; } c = nss_ZNEW(arena, NSSCertificate); if (!c) { nssArena_Destroy(arena); return NULL; } NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); c->type = NSSCertificateType_PKIX; pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor); if (!pkiob) { nssArena_Destroy(arena); return NULL; } c->object = *pkiob; nssItem_Create(arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); nssItem_Create(arena, &c->subject, cc->derSubject.len, cc->derSubject.data); if (PR_TRUE) { /* CERTCertificate stores serial numbers decoded. I need the DER * here. sigh. */ SECItem derSerial; SECStatus secrv; secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); if (secrv == SECFailure) { nssArena_Destroy(arena); return NULL; } nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); } if (cc->emailAddr && cc->emailAddr[0]) { c->email = nssUTF8_Create(arena, nssStringType_PrintableString, (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } if (cc->slot) { instance = nss_ZNEW(arena, nssCryptokiInstance); if (!instance) { nssArena_Destroy(arena); return NULL; } instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot)); instance->handle = cc->pkcs11ID; instance->isTokenObject = PR_TRUE; if (cc->nickname) { instance->label = nssUTF8_Create(arena, nssStringType_UTF8String, (NSSUTF8 *)cc->nickname, PORT_Strlen(cc->nickname)); } nssPKIObject_AddInstance(&c->object, instance); } c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc); cc->nssCertificate = c; return c; }
CERTCertificate * CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname, PRBool isperm, PRBool copyDER) { NSSCertificate *c; CERTCertificate *cc; NSSCertificate *tempCert = NULL; nssPKIObject *pkio; NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); if (!isperm) { NSSDER encoding; NSSITEM_FROM_SECITEM(&encoding, derCert); /* First, see if it is already a temp cert */ c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC, &encoding); if (!c) { /* Then, see if it is already a perm cert */ c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, &encoding); } if (c) { /* actually, that search ends up going by issuer/serial, * so it is still possible to return a cert with the same * issuer/serial but a different encoding, and we're * going to reject that */ if (!nssItem_Equal(&c->encoding, &encoding, NULL)) { nssCertificate_Destroy(c); PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); cc = NULL; } else { cc = STAN_GetCERTCertificateOrRelease(c); if (cc == NULL) { CERT_MapStanError(); } } return cc; } } pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor); if (!pkio) { CERT_MapStanError(); return NULL; } c = nss_ZNEW(pkio->arena, NSSCertificate); if (!c) { CERT_MapStanError(); nssPKIObject_Destroy(pkio); return NULL; } c->object = *pkio; if (copyDER) { nssItem_Create(c->object.arena, &c->encoding, derCert->len, derCert->data); } else { NSSITEM_FROM_SECITEM(&c->encoding, derCert); } /* Forces a decoding of the cert in order to obtain the parts used * below */ /* 'c' is not adopted here, if we fail loser frees what has been * allocated so far for 'c' */ cc = STAN_GetCERTCertificate(c); if (!cc) { CERT_MapStanError(); goto loser; } nssItem_Create(c->object.arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); nssItem_Create(c->object.arena, &c->subject, cc->derSubject.len, cc->derSubject.data); if (PR_TRUE) { /* CERTCertificate stores serial numbers decoded. I need the DER * here. sigh. */ SECItem derSerial = { 0 }; CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); if (!derSerial.data) goto loser; nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); } if (nickname) { c->object.tempName = nssUTF8_Create(c->object.arena, nssStringType_UTF8String, (NSSUTF8 *)nickname, PORT_Strlen(nickname)); } if (cc->emailAddr && cc->emailAddr[0]) { c->email = nssUTF8_Create( c->object.arena, nssStringType_PrintableString, (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c); if (!tempCert) { CERT_MapStanError(); goto loser; } /* destroy our copy */ NSSCertificate_Destroy(c); /* and use the stored entry */ c = tempCert; cc = STAN_GetCERTCertificateOrRelease(c); if (!cc) { /* STAN_GetCERTCertificateOrRelease destroys c on failure. */ CERT_MapStanError(); return NULL; } cc->istemp = PR_TRUE; cc->isperm = PR_FALSE; return cc; loser: /* Perhaps this should be nssCertificate_Destroy(c) */ nssPKIObject_Destroy(&c->object); return NULL; }