/* Returns NULL if "encoding" cannot be decoded. */ NSS_IMPLEMENT nssDecodedCert * nssDecodedPKIXCertificate_Create ( NSSArena *arenaOpt, NSSDER *encoding ) { nssDecodedCert *rvDC = NULL; CERTCertificate *cert; SECItem secDER; SECITEM_FROM_NSSITEM(&secDER, encoding); cert = CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL); if (cert) { rvDC = nss_ZNEW(arenaOpt, nssDecodedCert); if (rvDC) { rvDC->type = NSSCertificateType_PKIX; rvDC->data = (void *)cert; rvDC->getIdentifier = nss3certificate_getIdentifier; rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier; rvDC->matchIdentifier = nss3certificate_matchIdentifier; rvDC->isValidIssuer = nss3certificate_isValidIssuer; rvDC->getUsage = nss3certificate_getUsage; rvDC->isValidAtTime = nss3certificate_isValidAtTime; rvDC->isNewerThan = nss3certificate_isNewerThan; rvDC->matchUsage = nss3certificate_matchUsage; rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage; rvDC->getEmailAddress = nss3certificate_getEmailAddress; rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber; } else { CERT_DestroyCertificate(cert); } } return rvDC; }
/* 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; }
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; }
SECStatus certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr, SECItem *emailProfile, SECItem *profileTime) { PRTime oldtime; PRTime newtime; SECStatus rv = SECFailure; PRBool saveit; SECItem oldprof, oldproftime; SECItem *oldProfile = NULL; SECItem *oldProfileTime = NULL; PK11SlotInfo *slot = NULL; NSSCertificate *c; NSSCryptoContext *cc; nssSMIMEProfile *stanProfile = NULL; PRBool freeOldProfile = PR_FALSE; c = STAN_GetNSSCertificate(cert); if (!c) return SECFailure; cc = c->object.cryptoContext; if (cc != NULL) { stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); if (stanProfile) { PORT_Assert(stanProfile->profileData); SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData); oldProfile = &oldprof; SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime); oldProfileTime = &oldproftime; } } else { oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr, &cert->derSubject, &oldProfileTime); freeOldProfile = PR_TRUE; } saveit = PR_FALSE; /* both profileTime and emailProfile have to exist or not exist */ if (emailProfile == NULL) { profileTime = NULL; } else if (profileTime == NULL) { emailProfile = NULL; } if (oldProfileTime == NULL) { saveit = PR_TRUE; } else { /* there was already a profile for this email addr */ if (profileTime) { /* we have an old and new profile - save whichever is more recent*/ if (oldProfileTime->len == 0) { /* always replace if old entry doesn't have a time */ oldtime = LL_MININT; } else { rv = DER_UTCTimeToTime(&oldtime, oldProfileTime); if (rv != SECSuccess) { goto loser; } } rv = DER_UTCTimeToTime(&newtime, profileTime); if (rv != SECSuccess) { goto loser; } if (LL_CMP(newtime, >, oldtime)) { /* this is a newer profile, save it and cert */ saveit = PR_TRUE; } } else { saveit = PR_TRUE; } }