SECOidData * NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo) { SECOidData *algdata; SECOidTag algtag; algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm)); if (algdata == NULL) { return algdata; } /* Windows may have given us a signer algorithm oid instead of a digest * algorithm oid. This call will map to a signer oid to a digest one, * otherwise it leaves the oid alone and let the chips fall as they may * if it's not a digest oid. */ algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset); if (algtag != algdata->offset) { /* if the tags don't match, then we must have received a signer * algorithID. Now we need to get the oid data for the digest * oid, which the rest of the code is expecting */ algdata = SECOID_FindOIDByTag(algtag); } return algdata; }
/* returns proper bag type template based upon object type tag */ const SEC_ASN1Template * sec_pkcs12_choose_bag_type_old(void *src_or_dest, PRBool encoding) { const SEC_ASN1Template *theTemplate; SEC_PKCS12SafeBag *safebag; SECOidData *oiddata; if (src_or_dest == NULL) { return NULL; } safebag = (SEC_PKCS12SafeBag*)src_or_dest; oiddata = safebag->safeBagTypeTag; if (oiddata == NULL) { oiddata = SECOID_FindOID(&safebag->safeBagType); safebag->safeBagTypeTag = oiddata; } switch (oiddata->offset) { default: theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); break; case SEC_OID_PKCS12_KEY_BAG_ID: theTemplate = SEC_PointerToPKCS12KeyBagTemplate; break; case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID: theTemplate = SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD; break; case SEC_OID_PKCS12_SECRET_BAG_ID: theTemplate = SEC_PointerToPKCS12SecretBagTemplate; break; } return theTemplate; }
static ECName params2ecName(SECKEYECParams * params) { SECItem oid = { siBuffer, NULL, 0}; SECOidData *oidData = NULL; PRUint32 policyFlags = 0; ECName i; /* * params->data needs to contain the ASN encoding of an object ID (OID) * representing a named curve. Here, we strip away everything * before the actual OID and use the OID to look up a named curve. */ if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName; oid.len = params->len - 2; oid.data = params->data + 2; if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName; for (i = ec_noName + 1; i < ec_pastLastName; i++) { if (ecName2OIDTag[i] == oidData->offset) { if (NSS_GetAlgorithmPolicy(oidData->offset, &policyFlags) == SECSuccess && (policyFlags & NSS_USE_ALG_IN_SSL_KX)) { return i; } } } return ec_noName; }
/* * SecCmsAlgArrayGetIndexByAlgTag - find a specific algorithm in an array of * algorithms. * * algorithmArray - array of algorithm IDs * algtag - algorithm tag of algorithm to pick * * Returns: * An integer containing the index of the algorithm in the array or -1 if * algorithm was not found. */ int SecCmsAlgArrayGetIndexByAlgTag(SECAlgorithmID **algorithmArray, SECOidTag algtag) { SECOidData *algid; int i = -1; if (algorithmArray == NULL || algorithmArray[0] == NULL) return i; #ifdef ORDER_N_SQUARED for (i = 0; algorithmArray[i] != NULL; i++) { algid = SECOID_FindOID(&(algorithmArray[i]->algorithm)); if (algid->offset == algtag) break; /* bingo */ } #else algid = SECOID_FindOIDByTag(algtag); if (!algid) return i; for (i = 0; algorithmArray[i] != NULL; i++) { if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid)) break; /* bingo */ } #endif if (algorithmArray[i] == NULL) return -1; /* not found */ return i; }
const SEC_ASN1Template * sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding) { const SEC_ASN1Template *theTemplate; SEC_PKCS12CertAndCRL *certbag; SECOidData *oiddata; if (src_or_dest == NULL) { return NULL; } certbag = (SEC_PKCS12CertAndCRL*)src_or_dest; oiddata = certbag->BagTypeTag; if (oiddata == NULL) { oiddata = SECOID_FindOID(&certbag->BagID); certbag->BagTypeTag = oiddata; } switch (oiddata->offset) { default: theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); break; case SEC_OID_PKCS12_X509_CERT_CRL_BAG: theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate; break; case SEC_OID_PKCS12_SDSI_CERT_BAG: theTemplate = SEC_PointerToPKCS12SDSICertTemplate; break; } return theTemplate; }
/* returns appropriate shroud template based on object type tag */ const SEC_ASN1Template * sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding) { const SEC_ASN1Template *theTemplate; SEC_PKCS12ESPVKItem *espvk; SECOidData *oiddata; if (src_or_dest == NULL) { return NULL; } espvk = (SEC_PKCS12ESPVKItem*)src_or_dest; oiddata = espvk->espvkTag; if (oiddata == NULL) { oiddata = SECOID_FindOID(&espvk->espvkOID); espvk->espvkTag = oiddata; } switch (oiddata->offset) { default: theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); break; case SEC_OID_PKCS12_PKCS8_KEY_SHROUDING: theTemplate = SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate); break; } return theTemplate; }
static const SEC_ASN1Template * sec_pkcs12_choose_cert_bag_type(void *src_or_dest, PRBool encoding) { const SEC_ASN1Template *theTemplate; sec_PKCS12CertBag *certbag; SECOidData *oiddata; if (src_or_dest == NULL) { return NULL; } certbag = (sec_PKCS12CertBag*)src_or_dest; oiddata = SECOID_FindOID(&certbag->bagID); if(oiddata == NULL) { return SEC_ASN1_GET(SEC_AnyTemplate); } switch (oiddata->offset) { default: theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); break; case SEC_OID_PKCS9_X509_CERT: theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate); break; case SEC_OID_PKCS9_SDSI_CERT: theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); break; } return theTemplate; }
/* This function does NOT expect a DER type and length. */ SECOidTag SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level) { SECOidData *oiddata; char *oidString = NULL; oiddata = SECOID_FindOID(oid); if (oiddata != NULL) { const char *name = oiddata->desc; SECU_Indent(out, level); if (m != NULL) fprintf(out, "%s: ", m); fprintf(out, "%s\n", name); return oiddata->offset; } oidString = CERT_GetOidString(oid); if (oidString) { SECU_Indent(out, level); if (m != NULL) fprintf(out, "%s: ", m); fprintf(out, "%s\n", oidString); PR_smprintf_free(oidString); return SEC_OID_UNKNOWN; } SECU_PrintAsHex(out, oid, m, level); return SEC_OID_UNKNOWN; }
static const SEC_ASN1Template * sec_pkcs12_choose_attr_type(void *src_or_dest, PRBool encoding) { const SEC_ASN1Template *theTemplate; sec_PKCS12Attribute *attr; SECOidData *oiddata; if (src_or_dest == NULL) { return NULL; } attr = (sec_PKCS12Attribute*)src_or_dest; oiddata = SECOID_FindOID(&attr->attrType); if(oiddata == NULL) { return SEC_ASN1_GET(SEC_AnyTemplate); } switch (oiddata->offset) { default: theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); break; case SEC_OID_PKCS9_FRIENDLY_NAME: theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate); break; case SEC_OID_PKCS9_LOCAL_KEY_ID: theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate); break; case SEC_OID_PKCS12_KEY_USAGE: theTemplate = SEC_ASN1_GET(SEC_BitStringTemplate); break; } return theTemplate; }
/* ** secu_PrintPKCS7ContentInfo ** Takes a SEC_PKCS7ContentInfo type and sends the contents to the ** appropriate function */ int sv_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src, char *m) { const char *desc; SECOidTag kind; int rv; if (src->contentTypeTag == NULL) src->contentTypeTag = SECOID_FindOID(&(src->contentType)); if (src->contentTypeTag == NULL) { desc = "Unknown"; kind = SEC_OID_PKCS7_DATA; } else { desc = src->contentTypeTag->desc; kind = src->contentTypeTag->offset; } fprintf(out, "%s%s\n", m, desc); if (src->content.data == NULL) { fprintf(out, "pkcs7.data=<no content>\n"); return 0; } rv = 0; switch (kind) { case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */ rv = sv_PrintPKCS7Signed(out, src->content.signedData); break; case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */ fprintf(out, "pkcs7EnvelopedData=<unsupported>\n"); /*sv_PrintPKCS7Enveloped(out, src->content.envelopedData);*/ break; case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */ fprintf(out, "pkcs7SignedEnvelopedData=<unsupported>\n"); /*rv = sv_PrintPKCS7SignedAndEnveloped(out, src->content.signedAndEnvelopedData);*/ break; case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */ fprintf(out, "pkcs7DigestedData=<unsupported>\n"); /*sv_PrintPKCS7Digested(out, src->content.digestedData);*/ break; case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */ fprintf(out, "pkcs7EncryptedData=<unsupported>\n"); /*sv_PrintPKCS7Encrypted(out, src->content.encryptedData);*/ break; default: fprintf(out, "pkcs7UnknownData=<unsupported>\n"); /*sv_PrintAsHex(out, src->content.data);*/ break; } return rv; }
/* * SecCmsContentInfoGetContentType{Tag,OID} - find out (saving pointer to lookup result * for future reference) and return the inner content type. */ SECOidTag SecCmsContentInfoGetContentTypeTag(SecCmsContentInfoRef cinfo) { if (cinfo->contentTypeTag == NULL) cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); if (cinfo->contentTypeTag == NULL) return SEC_OID_OTHER; // was...SEC_OID_UNKNOWN OK? return cinfo->contentTypeTag->offset; }
/* * Find out (saving pointer to lookup result for future reference) * and return the inner content type. */ SECOidTag SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo) { if (cinfo->contentTypeTag == NULL) cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); if (cinfo->contentTypeTag == NULL) return SEC_OID_UNKNOWN; return cinfo->contentTypeTag->offset; }
SECOidTag SecCmsSignerInfoGetDigestAlgTag(SecCmsSignerInfoRef signerinfo) { SECOidData *algdata; algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm)); if (algdata != NULL) return algdata->offset; else return SEC_OID_UNKNOWN; }
/* * NSS_CMSAttribute_GetType - return the OID tag */ SECOidTag NSS_CMSAttribute_GetType(NSSCMSAttribute *attr) { SECOidData *typetag; typetag = SECOID_FindOID(&(attr->type)); if (typetag == NULL) return SEC_OID_UNKNOWN; return typetag->offset; }
ECCurveName SECOID_FindOIDTag(const SECItem *oid) { SECOidData *oiddata; oiddata = SECOID_FindOID (oid); if (oiddata == NULL) return ECCurve_noName; return oiddata->offset; }
/* * SecCmsAttributeGetType - return the OID tag */ SECOidTag SecCmsAttributeGetType(SecCmsAttribute *attr) { SECOidData *typetag; typetag = SECOID_FindOID(&(attr->type)); if (typetag == NULL) return SEC_OID_UNKNOWN; return typetag->offset; }
SECOidTag CERT_GetAVATag(CERTAVA *ava) { SECOidData *oid; if (!ava->type.data) return (SECOidTag)-1; oid = SECOID_FindOID(&ava->type); if ( oid ) { return(oid->offset); } return (SECOidTag)-1; }
/* * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result * for future reference) and return the inner content type. */ SECOidTag NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo) { if (cinfo == NULL) { return SEC_OID_UNKNOWN; } if (cinfo->contentTypeTag == NULL) cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); if (cinfo->contentTypeTag == NULL) return SEC_OID_UNKNOWN; return cinfo->contentTypeTag->offset; }
static const SEC_ASN1Template * sec_pkcs12_choose_safe_bag_type(void *src_or_dest, PRBool encoding) { const SEC_ASN1Template *theTemplate; sec_PKCS12SafeBag *safeBag; SECOidData *oiddata; if (src_or_dest == NULL) { return NULL; } safeBag = (sec_PKCS12SafeBag*)src_or_dest; oiddata = SECOID_FindOID(&safeBag->safeBagType); if(oiddata == NULL) { return SEC_ASN1_GET(SEC_AnyTemplate); } switch (oiddata->offset) { default: theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); break; case SEC_OID_PKCS12_V1_KEY_BAG_ID: theTemplate = SEC_ASN1_GET(SECKEY_PointerToPrivateKeyInfoTemplate); break; case SEC_OID_PKCS12_V1_CERT_BAG_ID: theTemplate = sec_PKCS12PointerToCertBagTemplate; break; case SEC_OID_PKCS12_V1_CRL_BAG_ID: theTemplate = sec_PKCS12PointerToCRLBagTemplate; break; case SEC_OID_PKCS12_V1_SECRET_BAG_ID: theTemplate = sec_PKCS12PointerToSecretBagTemplate; break; case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID: theTemplate = SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate); break; case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID: if(encoding) { theTemplate = sec_PKCS12PointerToSafeContentsTemplate; } else { theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); } break; } return theTemplate; }
SECItem * NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo) { if (cinfo == NULL) { return NULL; } if (cinfo->contentTypeTag == NULL) { cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); } if (cinfo->contentTypeTag == NULL) { return NULL; } return &(cinfo->contentTypeTag->oid); }
CSSM_DATA_PTR SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo) { if (cinfo->contentTypeTag == NULL) cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); if (cinfo->contentTypeTag == NULL) { /* if we have an OID but we just don't recognize it, return that */ if(cinfo->contentType.Data != NULL) { return &cinfo->contentType; } else { return NULL; } } return &(cinfo->contentTypeTag->oid); }
void sv_PrintObjectID(FILE *out, SECItem *oid, char *m) { const char *name; SECOidData *oiddata; oiddata = SECOID_FindOID(oid); if (oiddata == NULL) { sv_PrintAsHex(out, oid, m); return; } name = oiddata->desc; if (m != NULL) fprintf(out, "%s", m); fprintf(out, "%s\n", name); }
/* ** secu_PrintPKCS7EncContent ** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it) */ void secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src, char *m, int level) { if (src->contentTypeTag == NULL) src->contentTypeTag = SECOID_FindOID(&(src->contentType)); secu_Indent(out, level); fprintf(out, "%s:\n", m); secu_Indent(out, level + 1); fprintf(out, "Content Type: %s\n", (src->contentTypeTag != NULL) ? src->contentTypeTag->desc : "Unknown"); sv_PrintAlgorithmID(out, &(src->contentEncAlg), "Content Encryption Algorithm"); sv_PrintAsHex(out, &(src->encContent), "Encrypted Content", level+1); }
static SECStatus OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, SECItem *sig, SECAlgorithmID *sigAlgorithm) { SECStatus rv; VFYContext *cx; SECOidData *sigAlgOid, *oiddata; SECOidTag sigAlgTag; SECOidTag hashAlgTag; int showDigestOid=0; cx = VFY_CreateContextWithAlgorithmID(key, sig, sigAlgorithm, &hashAlgTag, NULL); if (cx == NULL) return SECFailure; sigAlgOid = SECOID_FindOID(&sigAlgorithm->algorithm); if (sigAlgOid == 0) return SECFailure; sigAlgTag = sigAlgOid->offset; if (showDigestOid) { oiddata = SECOID_FindOIDByTag(hashAlgTag); if ( oiddata ) { printf("PROBLEM: (cont) Digest OID is %s\n", oiddata->desc); } else { SECU_PrintAsHex(stdout, &oiddata->oid, "PROBLEM: UNKNOWN OID", 0); } } rv = VFY_Begin(cx); if (rv == SECSuccess) { rv = VFY_Update(cx, buf, len); if (rv == SECSuccess) rv = VFY_End(cx); } VFY_DestroyContext(cx, PR_TRUE); return rv; }
void * SecCmsUtilGetHashObjByAlgID(SECAlgorithmID *algid) { SECOidData *oidData = SECOID_FindOID(&(algid->algorithm)); if (oidData) { void *digobj = NULL; switch (oidData->offset) { case SEC_OID_SHA1: digobj = calloc(1, sizeof(CC_SHA1_CTX)); CC_SHA1_Init(digobj); break; case SEC_OID_MD5: digobj = calloc(1, sizeof(CC_MD5_CTX)); CC_MD5_Init(digobj); break; case SEC_OID_SHA224: digobj = calloc(1, sizeof(CC_SHA256_CTX)); CC_SHA224_Init(digobj); break; case SEC_OID_SHA256: digobj = calloc(1, sizeof(CC_SHA256_CTX)); CC_SHA256_Init(digobj); break; case SEC_OID_SHA384: digobj = calloc(1, sizeof(CC_SHA512_CTX)); CC_SHA384_Init(digobj); break; case SEC_OID_SHA512: digobj = calloc(1, sizeof(CC_SHA512_CTX)); CC_SHA512_Init(digobj); break; default: break; } return digobj; } return 0; }
const namedGroupDef * ssl_ECPubKey2NamedGroup(const SECKEYPublicKey *pubKey) { SECItem oid = { siBuffer, NULL, 0 }; SECOidData *oidData = NULL; PRUint32 policyFlags = 0; unsigned int i; const SECKEYECParams *params; if (pubKey->keyType != ecKey) { PORT_Assert(0); return NULL; } params = &pubKey->u.ec.DEREncodedParams; /* * params->data needs to contain the ASN encoding of an object ID (OID) * representing a named curve. Here, we strip away everything * before the actual OID and use the OID to look up a named curve. */ if (params->data[0] != SEC_ASN1_OBJECT_ID) return NULL; oid.len = params->len - 2; oid.data = params->data + 2; if ((oidData = SECOID_FindOID(&oid)) == NULL) return NULL; if ((NSS_GetAlgorithmPolicy(oidData->offset, &policyFlags) == SECSuccess) && !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) { return NULL; } for (i = 0; i < ssl_named_group_count; ++i) { if (ssl_named_groups[i].oidTag == oidData->offset) { return &ssl_named_groups[i]; } } return NULL; }
static ECName params2ecName(SECKEYECParams * params) { SECItem oid = { siBuffer, NULL, 0}; SECOidData *oidData = NULL; ECName i; /* * params->data needs to contain the ASN encoding of an object ID (OID) * representing a named curve. Here, we strip away everything * before the actual OID and use the OID to look up a named curve. */ if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName; oid.len = params->len - 2; oid.data = params->data + 2; if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName; for (i = ec_noName + 1; i < ec_pastLastName; i++) { if (ecName2OIDTag[i] == oidData->offset) return i; } return ec_noName; }
/* * helper function for dynamic template determination of the attribute value */ static const SecAsn1Template * cms_attr_choose_attr_value_template(void *src_or_dest, Boolean encoding, const char *buf, void *dest) { const SecAsn1Template *theTemplate; SecCmsAttribute *attribute; SECOidData *oiddata; Boolean encoded; PORT_Assert (src_or_dest != NULL); if (src_or_dest == NULL) return NULL; attribute = (SecCmsAttribute *)src_or_dest; if (encoding && attribute->encoded) /* we're encoding, and the attribute value is already encoded. */ return SEC_ASN1_GET(kSecAsn1AnyTemplate); /* get attribute's typeTag */ oiddata = attribute->typeTag; if (oiddata == NULL) { oiddata = SECOID_FindOID(&attribute->type); attribute->typeTag = oiddata; } if (oiddata == NULL) { /* still no OID tag? OID is unknown then. en/decode value as ANY. */ encoded = PR_TRUE; theTemplate = SEC_ASN1_GET(kSecAsn1AnyTemplate); } else { switch (oiddata->offset) { case SEC_OID_PKCS9_SMIME_CAPABILITIES: case SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE: /* these guys need to stay DER-encoded */ default: /* same goes for OIDs that are not handled here */ encoded = PR_TRUE; theTemplate = SEC_ASN1_GET(kSecAsn1AnyTemplate); break; /* otherwise choose proper template */ case SEC_OID_PKCS9_EMAIL_ADDRESS: case SEC_OID_RFC1274_MAIL: case SEC_OID_PKCS9_UNSTRUCTURED_NAME: encoded = PR_FALSE; theTemplate = SEC_ASN1_GET(kSecAsn1IA5StringTemplate); break; case SEC_OID_PKCS9_CONTENT_TYPE: encoded = PR_FALSE; theTemplate = SEC_ASN1_GET(kSecAsn1ObjectIDTemplate); break; case SEC_OID_PKCS9_MESSAGE_DIGEST: encoded = PR_FALSE; theTemplate = SEC_ASN1_GET(kSecAsn1OctetStringTemplate); break; case SEC_OID_PKCS9_SIGNING_TIME: encoded = PR_FALSE; theTemplate = SEC_ASN1_GET(kSecAsn1UTCTimeTemplate); // @@@ This should be a choice between UTCTime and GeneralizedTime -- mb break; /* XXX Want other types here, too */ } } if (encoding) { /* * If we are encoding and we think we have an already-encoded value, * then the code which initialized this attribute should have set * the "encoded" property to true (and we would have returned early, * up above). No devastating error, but that code should be fixed. * (It could indicate that the resulting encoded bytes are wrong.) */ PORT_Assert (!encoded); } else { /* * We are decoding; record whether the resulting value is * still encoded or not. */ attribute->encoded = encoded; } return theTemplate; }
nsresult VerifyCMSDetachedSignatureIncludingCertificate( const SECItem& buffer, const SECItem& detachedDigest, nsresult (*verifyCertificate)(CERTCertificate* cert, void* context, void* pinArg), void *verifyCertificateContext, void* pinArg) { // XXX: missing pinArg is tolerated. if (NS_WARN_IF(!buffer.data && buffer.len > 0) || NS_WARN_IF(!detachedDigest.data && detachedDigest.len > 0) || (!verifyCertificate) || NS_WARN_IF(!verifyCertificateContext)) { return NS_ERROR_INVALID_ARG; } ScopedNSSCMSMessage cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast<SECItem*>(&buffer), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); if (!cmsMsg) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } if (!NSS_CMSMessage_IsSigned(cmsMsg.get())) { return NS_ERROR_CMS_VERIFY_NOT_SIGNED; } NSSCMSContentInfo* cinfo = NSS_CMSMessage_ContentLevel(cmsMsg.get(), 0); if (!cinfo) { return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO; } // signedData is non-owning NSSCMSSignedData* signedData = reinterpret_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(cinfo)); if (!signedData) { return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO; } // Set digest value. if (NSS_CMSSignedData_SetDigestValue(signedData, SEC_OID_SHA1, const_cast<SECItem*>(&detachedDigest))) { return NS_ERROR_CMS_VERIFY_BAD_DIGEST; } // Parse the certificates into CERTCertificate objects held in memory so // verifyCertificate will be able to find them during path building. ScopedCERTCertList certs(CERT_NewCertList()); if (!certs) { return NS_ERROR_OUT_OF_MEMORY; } if (signedData->rawCerts) { for (size_t i = 0; signedData->rawCerts[i]; ++i) { ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), signedData->rawCerts[i], nullptr, false, true)); // Skip certificates that fail to parse if (cert) { if (CERT_AddCertToListTail(certs.get(), cert.get()) == SECSuccess) { cert.forget(); // ownership transfered } else { return NS_ERROR_OUT_OF_MEMORY; } } } } // Get the end-entity certificate. int numSigners = NSS_CMSSignedData_SignerInfoCount(signedData); if (NS_WARN_IF(numSigners != 1)) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } // signer is non-owning. NSSCMSSignerInfo* signer = NSS_CMSSignedData_GetSignerInfo(signedData, 0); if (NS_WARN_IF(!signer)) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } CERTCertificate* signerCert = NSS_CMSSignerInfo_GetSigningCertificate(signer, CERT_GetDefaultCertDB()); if (!signerCert) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } nsresult rv = verifyCertificate(signerCert, verifyCertificateContext, pinArg); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } // See NSS_CMSContentInfo_GetContentTypeOID, which isn't exported from NSS. SECOidData* contentTypeOidData = SECOID_FindOID(&signedData->contentInfo.contentType); if (!contentTypeOidData) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } return MapSECStatus(NSS_CMSSignerInfo_Verify(signer, const_cast<SECItem*>(&detachedDigest), &contentTypeOidData->oid)); }
static SecCmsCipherContext * SecCmsCipherContextStart(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid, PRBool encrypt) { SecCmsCipherContext *cc; CSSM_CC_HANDLE ciphercc = 0; SECOidData *oidData; SECOidTag algtag; CSSM_ALGORITHMS algorithm; CSSM_PADDING padding = CSSM_PADDING_PKCS7; CSSM_ENCRYPT_MODE mode; CSSM_CSP_HANDLE cspHandle; const CSSM_KEY *cssmKey; OSStatus rv; uint8 ivbuf[8]; CSSM_DATA initVector = { sizeof(ivbuf), ivbuf }; //CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_ALG_PARAMS, sizeof(CSSM_DATA_PTR) }; rv = SecKeyGetCSPHandle(key, &cspHandle); if (rv) goto loser; rv = SecKeyGetCSSMKey(key, &cssmKey); if (rv) goto loser; // @@@ Add support for PBE based stuff oidData = SECOID_FindOID(&algid->algorithm); if (!oidData) goto loser; algtag = oidData->offset; algorithm = oidData->cssmAlgorithm; if (!algorithm) goto loser; switch (algtag) { case SEC_OID_RC2_CBC: case SEC_OID_RC4: case SEC_OID_DES_EDE3_CBC: case SEC_OID_DES_EDE: case SEC_OID_DES_CBC: case SEC_OID_RC5_CBC_PAD: case SEC_OID_AES_128_CBC: case SEC_OID_AES_192_CBC: case SEC_OID_AES_256_CBC: case SEC_OID_FORTEZZA_SKIPJACK: mode = CSSM_ALGMODE_CBCPadIV8; break; case SEC_OID_DES_ECB: case SEC_OID_AES_128_ECB: case SEC_OID_AES_192_ECB: case SEC_OID_AES_256_ECB: mode = CSSM_ALGMODE_ECBPad; break; case SEC_OID_DES_OFB: mode = CSSM_ALGMODE_OFBPadIV8; break; case SEC_OID_DES_CFB: mode = CSSM_ALGMODE_CFBPadIV8; break; default: goto loser; } if (encrypt) { CSSM_CC_HANDLE randomcc; //SECItem *parameters; // Generate random initVector if (CSSM_CSP_CreateRandomGenContext(cspHandle, CSSM_ALGID_APPLE_YARROW, NULL, /* seed*/ initVector.Length, &randomcc)) goto loser; if (CSSM_GenerateRandom(randomcc, &initVector)) goto loser; CSSM_DeleteContext(randomcc); // Put IV into algid.parameters switch (algtag) { case SEC_OID_RC4: case SEC_OID_DES_EDE3_CBC: case SEC_OID_DES_EDE: case SEC_OID_DES_CBC: case SEC_OID_AES_128_CBC: case SEC_OID_AES_192_CBC: case SEC_OID_AES_256_CBC: case SEC_OID_FORTEZZA_SKIPJACK: case SEC_OID_DES_ECB: case SEC_OID_AES_128_ECB: case SEC_OID_AES_192_ECB: case SEC_OID_AES_256_ECB: case SEC_OID_DES_OFB: case SEC_OID_DES_CFB: /* Just encode the initVector as an octet string. */ if (!SEC_ASN1EncodeItem(poolp, &algid->parameters, &initVector, SEC_OctetStringTemplate)) goto loser; break; case SEC_OID_RC2_CBC: { sec_rc2cbcParameter rc2 = {}; unsigned long rc2version; SECItem *newParams; rc2.iv = initVector; rc2version = rc2_unmap(cssmKey->KeyHeader.LogicalKeySizeInBits); if (!SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion), rc2version)) goto loser; newParams = SEC_ASN1EncodeItem (poolp, &algid->parameters, &rc2, sec_rc2cbc_parameter_template); PORT_Free(rc2.rc2ParameterVersion.Data); if (newParams == NULL) goto loser; break; } case SEC_OID_RC5_CBC_PAD: default: // @@@ Implement rc5 params stuff. goto loser; break; } } else { // Extract IV from algid.parameters // Put IV into algid.parameters switch (algtag) { case SEC_OID_RC4: case SEC_OID_DES_EDE3_CBC: case SEC_OID_DES_EDE: case SEC_OID_DES_CBC: case SEC_OID_AES_128_CBC: case SEC_OID_AES_192_CBC: case SEC_OID_AES_256_CBC: case SEC_OID_FORTEZZA_SKIPJACK: case SEC_OID_DES_ECB: case SEC_OID_AES_128_ECB: case SEC_OID_AES_192_ECB: case SEC_OID_AES_256_ECB: case SEC_OID_DES_OFB: case SEC_OID_DES_CFB: { CSSM_DATA iv = {}; /* Just decode the initVector from an octet string. */ rv = SEC_ASN1DecodeItem(NULL, &iv, SEC_OctetStringTemplate, &(algid->parameters)); if (rv) goto loser; if (initVector.Length != iv.Length) { PORT_Free(iv.Data); goto loser; } memcpy(initVector.Data, iv.Data, initVector.Length); PORT_Free(iv.Data); break; } case SEC_OID_RC2_CBC: { sec_rc2cbcParameter rc2 = {}; unsigned long ulEffectiveBits; rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2cbc_parameter_template, &(algid->parameters)); if (rv) goto loser; if (initVector.Length != rc2.iv.Length) { PORT_Free(rc2.iv.Data); PORT_Free(rc2.rc2ParameterVersion.Data); goto loser; } memcpy(initVector.Data, rc2.iv.Data, initVector.Length); PORT_Free(rc2.iv.Data); ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion); PORT_Free(rc2.rc2ParameterVersion.Data); if (ulEffectiveBits != cssmKey->KeyHeader.LogicalKeySizeInBits) goto loser; break; } case SEC_OID_RC5_CBC_PAD: default: // @@@ Implement rc5 params stuff. goto loser; break; } } if (CSSM_CSP_CreateSymmetricContext(cspHandle, algorithm, mode, NULL, /* accessCred */ cssmKey, &initVector, padding, NULL, /* reserved */ &ciphercc)) goto loser; if (encrypt) rv = CSSM_EncryptDataInit(ciphercc); else rv = CSSM_DecryptDataInit(ciphercc); if (rv) goto loser; cc = (SecCmsCipherContext *)PORT_ZAlloc(sizeof(SecCmsCipherContext)); if (cc == NULL) goto loser; cc->cc = ciphercc; cc->encrypt = encrypt; return cc; loser: if (ciphercc) CSSM_DeleteContext(ciphercc); return NULL; }