NSSCMSRecipientInfo * NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg, CERTCertificate *cert) { SECKEYPublicKey *pubKey = NULL; SECItem subjKeyID = {siBuffer, NULL, 0}; NSSCMSRecipientInfo *retVal = NULL; if (!cmsg || !cert) { return NULL; } pubKey = CERT_ExtractPublicKey(cert); if (!pubKey) { goto done; } if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess || subjKeyID.data == NULL) { goto done; } retVal = NSS_CMSRecipientInfo_CreateWithSubjKeyID(cmsg, &subjKeyID, pubKey); done: if (pubKey) SECKEY_DestroyPublicKey(pubKey); if (subjKeyID.data) SECITEM_FreeItem(&subjKeyID, PR_FALSE); return retVal; }
SecCmsRecipientInfoRef SecCmsRecipientInfoCreateWithSubjKeyIDFromCert(SecCmsEnvelopedDataRef envd, SecCertificateRef cert) { SecPublicKeyRef pubKey = NULL; SecAsn1Item subjKeyID = {0, NULL}; SecCmsRecipientInfoRef retVal = NULL; if (!envd || !cert) { return NULL; } pubKey = CERT_ExtractPublicKey(cert); if (!pubKey) { goto done; } if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess || subjKeyID.Data == NULL) { goto done; } retVal = SecCmsRecipientInfoCreateWithSubjKeyID(envd, &subjKeyID, pubKey); done: if (pubKey) SECKEY_DestroyPublicKey(pubKey); if (subjKeyID.Data) SECITEM_FreeItem(&subjKeyID, PR_FALSE); return retVal; }
SecCertificateRef CERT_FindCertBySubjectKeyID (CFTypeRef keychainOrArray, CSSM_DATA_PTR *rawCerts, const SECItem *subjKeyID) { SecCertificateRef certificate; int numRawCerts = SecCmsArrayCount((void **)rawCerts); int dex; OSStatus ortn; SECItem skid; /* * First search the rawCerts array. */ for(dex=0; dex<numRawCerts; dex++) { int match; ortn = SecCertificateCreateFromData(rawCerts[dex], CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certificate); if(ortn) { continue; } if(CERT_FindSubjectKeyIDExtension(certificate, &skid)) { CFRelease(certificate); /* not present */ continue; } match = compareCssmData(subjKeyID, &skid); SECITEM_FreeItem(&skid, PR_FALSE); if(match) { /* got it */ return certificate; } CFRelease(certificate); } /* now search keychain(s) */ OSStatus status = SecCertificateFindBySubjectKeyID(keychainOrArray,subjKeyID,&certificate); if (status) { PORT_SetError(SEC_ERROR_NO_EMAIL_CERT); certificate = NULL; } return certificate; }
static nssCertIDMatch nss3certificate_matchIdentifier(nssDecodedCert *dc, void *id) { CERTCertificate *c = (CERTCertificate *)dc->data; CERTAuthKeyID *authKeyID = (CERTAuthKeyID *)id; SECItem skid; nssCertIDMatch match = nssCertIDMatch_Unknown; /* keyIdentifier */ if (authKeyID->keyID.len > 0 && CERT_FindSubjectKeyIDExtension(c, &skid) == SECSuccess) { PRBool skiEqual; skiEqual = SECITEM_ItemsAreEqual(&authKeyID->keyID, &skid); PORT_Free(skid.data); if (skiEqual) { /* change the state to positive match, but keep going */ match = nssCertIDMatch_Yes; } else { /* exit immediately on failure */ return nssCertIDMatch_No; } } /* issuer/serial (treated as pair) */ if (authKeyID->authCertIssuer) { SECItem *caName = NULL; SECItem *caSN = &authKeyID->authCertSerialNumber; caName = (SECItem *)CERT_GetGeneralNameByType( authKeyID->authCertIssuer, certDirectoryName, PR_TRUE); if (caName != NULL && SECITEM_ItemsAreEqual(&c->derIssuer, caName) && SECITEM_ItemsAreEqual(&c->serialNumber, caSN)) { match = nssCertIDMatch_Yes; } else { match = nssCertIDMatch_Unknown; } } return match; }