/* appends a shrouded key to a key bag. this is used for exporting * to store externally wrapped keys. it is used when importing to convert * old items to new */ SECStatus sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag, SEC_PKCS12ESPVKItem *espvk) { int size; void *mark = NULL, *dummy = NULL; if((bag == NULL) || (espvk == NULL)) return SECFailure; mark = PORT_ArenaMark(bag->poolp); /* grow the list */ size = (bag->nEspvks + 1) * sizeof(SEC_PKCS12ESPVKItem *); dummy = (SEC_PKCS12ESPVKItem **)PORT_ArenaGrow(bag->poolp, bag->espvks, size, size + sizeof(SEC_PKCS12ESPVKItem *)); bag->espvks = (SEC_PKCS12ESPVKItem**)dummy; if(dummy == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } bag->espvks[bag->nEspvks] = espvk; bag->nEspvks++; bag->espvks[bag->nEspvks] = NULL; PORT_ArenaUnmark(bag->poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(bag->poolp, mark); return SECFailure; }
SECStatus CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent, CERTCertList *inCAPubs) { PLArenaPool *poolp; void *mark; SECStatus rv; PORT_Assert(inCertRepContent != NULL && inCAPubs != NULL && inCertRepContent->caPubs == NULL); if (inCertRepContent == NULL || inCAPubs == NULL || inCertRepContent == NULL) { return SECFailure; } poolp = inCertRepContent->poolp; mark = PORT_ArenaMark(poolp); rv = cmmf_ExtractCertsFromList(inCAPubs, poolp, &inCertRepContent->caPubs); if (rv != SECSuccess) { PORT_ArenaRelease(poolp, mark); } else { PORT_ArenaUnmark(poolp, mark); } return rv; }
/* * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding) * * version will be set by NSS_CMSDigestedData_Encode_BeforeStart * digestAlg is passed as parameter * contentInfo must be filled by the user * digest will be calculated while encoding */ NSSCMSDigestedData * NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg) { void *mark; NSSCMSDigestedData *digd; PLArenaPool *poolp; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData)); if (digd == NULL) goto loser; digd->cmsg = cmsg; if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return digd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
/* * SecCmsDigestedDataCreate - create a digestedData object (presumably for encoding) * * version will be set by SecCmsDigestedDataEncodeBeforeStart * digestAlg is passed as parameter * contentInfo must be filled by the user * digest will be calculated while encoding */ SecCmsDigestedDataRef SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg) { void *mark; SecCmsDigestedDataRef digd; PLArenaPool *poolp; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); digd = (SecCmsDigestedDataRef)PORT_ArenaZAlloc(poolp, sizeof(SecCmsDigestedData)); if (digd == NULL) goto loser; digd->contentInfo.cmsg = cmsg; if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return digd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
SECStatus CERT_FindCRLNumberExten (PRArenaPool *arena, CERTCrl *crl, SECItem *value) { SECItem encodedExtenValue; SECItem *tmpItem = NULL; SECStatus rv; void *mark = NULL; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER, &encodedExtenValue); if ( rv != SECSuccess ) return (rv); mark = PORT_ArenaMark(arena); tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue); if (tmpItem) { rv = SEC_QuickDERDecodeItem (arena, value, SEC_ASN1_GET(SEC_IntegerTemplate), tmpItem); } else { rv = SECFailure; } PORT_Free (encodedExtenValue.data); if (rv == SECFailure) { PORT_ArenaRelease(arena, mark); } else { PORT_ArenaUnmark(arena, mark); } return (rv); }
/* * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the * authenticated (i.e. signed) attributes of "signerinfo". * * This is expected to be included in outgoing signed * messages for email (S/MIME). */ SECStatus NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo) { NSSCMSAttribute *attr; SECItem *smimecaps = NULL; void *mark; PLArenaPool *poolp; poolp = signerinfo->cmsg->poolp; mark = PORT_ArenaMark(poolp); smimecaps = SECITEM_AllocItem(poolp, NULL, 0); if (smimecaps == NULL) goto loser; /* create new signing time attribute */ if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess) goto loser; if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL) goto loser; if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
NSSCMSSignedData * NSS_CMSSignedData_Create(NSSCMSMessage *cmsg) { void *mark; NSSCMSSignedData *sigd; PLArenaPool *poolp; if (!cmsg) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignedData)); if (sigd == NULL) goto loser; sigd->cmsg = cmsg; /* signerInfos, certs, certlists, crls are all empty */ /* version is set in NSS_CMSSignedData_Finalize() */ PORT_ArenaUnmark(poolp, mark); return sigd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
/* * SecCmsAttributeArrayAddAttr - add an attribute to an * array of attributes. */ OSStatus SecCmsAttributeArrayAddAttr(PLArenaPool *poolp, SecCmsAttribute ***attrs, SecCmsAttribute *attr) { SecCmsAttribute *oattr; void *mark; SECOidTag type; mark = PORT_ArenaMark(poolp); /* find oidtag of attr */ type = SecCmsAttributeGetType(attr); /* see if we have one already */ oattr = SecCmsAttributeArrayFindAttrByOidTag(*attrs, type, PR_FALSE); PORT_Assert (oattr == NULL); if (oattr != NULL) goto loser; /* XXX or would it be better to replace it? */ /* no, shove it in */ if (SecCmsArrayAdd(poolp, (void ***)attrs, (void *)attr) != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return SECFailure; }
SECStatus crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest, CERTName *src) { CERTName *newName; SECStatus rv; void *mark; mark = PORT_ArenaMark(poolp); *dest = newName = PORT_ArenaZNew(poolp, CERTName); if (newName == NULL) { goto loser; } rv = CERT_CopyName(poolp, newName, src); if (rv != SECSuccess) { goto loser; } PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); *dest = NULL; return SECFailure; }
/* * NSS_CMSAttribute_AddValue - add another value to an attribute */ SECStatus NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *value) { SECItem *copiedvalue; void *mark; PORT_Assert (poolp != NULL); mark = PORT_ArenaMark(poolp); if (value == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto loser; } if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL) goto loser; if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_Assert (mark != NULL); PORT_ArenaRelease (poolp, mark); return SECFailure; }
/* * NSS_CMSEnvelopedData_Create - create an enveloped data message */ NSSCMSEnvelopedData * NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize) { void *mark; NSSCMSEnvelopedData *envd; PLArenaPool *poolp; SECStatus rv; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); envd = (NSSCMSEnvelopedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEnvelopedData)); if (envd == NULL) goto loser; envd->cmsg = cmsg; /* version is set in NSS_CMSEnvelopedData_Encode_BeforeStart() */ rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo), algorithm, NULL, keysize); if (rv != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return envd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
SecCmsSignedDataRef SecCmsSignedDataCreate(SecCmsMessageRef cmsg) { void *mark; SecCmsSignedDataRef sigd; PLArenaPool *poolp; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); sigd = (SecCmsSignedDataRef)PORT_ArenaZAlloc (poolp, sizeof(SecCmsSignedData)); if (sigd == NULL) goto loser; sigd->cmsg = cmsg; /* signerInfos, certs, certlists, crls are all empty */ /* version is set in SecCmsSignedDataFinalize() */ PORT_ArenaUnmark(poolp, mark); return sigd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
/* * SecCmsSignerInfoAddSigningTime - add the signing time to the * authenticated (i.e. signed) attributes of "signerinfo". * * This is expected to be included in outgoing signed * messages for email (S/MIME) but is likely useful in other situations. * * This should only be added once; a second call will do nothing. * * XXX This will probably just shove the current time into "signerinfo" * but it will not actually get signed until the entire item is * processed for encoding. Is this (expected to be small) delay okay? */ OSStatus SecCmsSignerInfoAddSigningTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t) { SecCmsAttribute *attr; CSSM_DATA stime; void *mark; PLArenaPool *poolp; poolp = signerinfo->cmsg->poolp; mark = PORT_ArenaMark(poolp); /* create new signing time attribute */ if (DER_CFDateToUTCTime(t, &stime) != SECSuccess) goto loser; if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) { SECITEM_FreeItem (&stime, PR_FALSE); goto loser; } SECITEM_FreeItem (&stime, PR_FALSE); if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
OSStatus SecCmsSignedDataAddDigest(SecArenaPoolRef pool, SecCmsSignedDataRef sigd, SECOidTag digestalgtag, CSSM_DATA_PTR digest) { PRArenaPool *poolp = (PRArenaPool *)pool; SECAlgorithmID *digestalg; void *mark; mark = PORT_ArenaMark(poolp); digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); if (digestalg == NULL) goto loser; if (SECOID_SetAlgorithmID (poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */ goto loser; if (SecCmsArrayAdd(poolp, (void ***)&(sigd->digestAlgorithms), (void *)digestalg) != SECSuccess || /* even if digest is NULL, add dummy to have same-size array */ SecCmsArrayAdd(poolp, (void ***)&(sigd->digests), (void *)digest) != SECSuccess) { goto loser; } PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return SECFailure; }
/* * SecCmsAttributeArraySetAttr - set an attribute's value in a set of attributes */ OSStatus SecCmsAttributeArraySetAttr(PLArenaPool *poolp, SecCmsAttribute ***attrs, SECOidTag type, CSSM_DATA_PTR value, Boolean encoded) { SecCmsAttribute *attr; void *mark; mark = PORT_ArenaMark(poolp); /* see if we have one already */ attr = SecCmsAttributeArrayFindAttrByOidTag(*attrs, type, PR_FALSE); if (attr == NULL) { /* not found? create one! */ attr = SecCmsAttributeCreate(poolp, type, value, encoded); if (attr == NULL) goto loser; /* and add it to the list */ if (SecCmsArrayAdd(poolp, (void ***)attrs, (void *)attr) != SECSuccess) goto loser; } else { /* found, shove it in */ /* XXX we need a decent memory model @#$#$!#!!! */ attr->values[0] = value; attr->encoded = encoded; } PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
/* * SecCmsAttributeAddValue - add another value to an attribute */ OSStatus SecCmsAttributeAddValue(PLArenaPool *poolp, SecCmsAttribute *attr, CSSM_DATA_PTR value) { CSSM_DATA copiedvalue; void *mark; PORT_Assert (poolp != NULL); mark = PORT_ArenaMark(poolp); /* XXX we need an object memory model #$%#$%! */ if (SECITEM_CopyItem(poolp, &copiedvalue, value) != SECSuccess) goto loser; if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)&copiedvalue) != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_Assert (mark != NULL); PORT_ArenaRelease (poolp, mark); return SECFailure; }
/* create a safe contents structure with a list of * length 0 with the first element being NULL */ SEC_PKCS12SafeContents * sec_pkcs12_create_safe_contents(PLArenaPool *poolp) { SEC_PKCS12SafeContents *safe; void *mark; if(poolp == NULL) return NULL; /* allocate structure */ mark = PORT_ArenaMark(poolp); safe = (SEC_PKCS12SafeContents *)PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS12SafeContents)); if(safe == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_ArenaRelease(poolp, mark); return NULL; } /* init list */ safe->contents = (SEC_PKCS12SafeBag**)PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS12SafeBag *)); if(safe->contents == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_ArenaRelease(poolp, mark); return NULL; } safe->contents[0] = NULL; safe->poolp = poolp; safe->safe_size = 0; PORT_ArenaUnmark(poolp, mark); return safe; }
/* * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the * authenticated (i.e. signed) attributes of "signerinfo". * * This is expected to be included in outgoing signed * messages for email (S/MIME) but is likely useful in other situations. * * This should only be added once; a second call will do nothing. * * XXX This will probably just shove the current time into "signerinfo" * but it will not actually get signed until the entire item is * processed for encoding. Is this (expected to be small) delay okay? */ SECStatus NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t) { NSSCMSAttribute *attr; SECItem stime; void *mark; PLArenaPool *poolp; poolp = signerinfo->cmsg->poolp; mark = PORT_ArenaMark(poolp); /* create new signing time attribute */ if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess) goto loser; if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) { SECITEM_FreeItem (&stime, PR_FALSE); goto loser; } SECITEM_FreeItem (&stime, PR_FALSE); if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess) goto loser; PORT_ArenaUnmark (poolp, mark); return SECSuccess; loser: PORT_ArenaRelease (poolp, mark); return SECFailure; }
SECStatus crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest, SECAlgorithmID* src) { SECStatus rv; void *mark = NULL; SECAlgorithmID *mySecAlg; if (!poolp) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } mark = PORT_ArenaMark(poolp); *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); if (mySecAlg == NULL) { goto loser; } rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src); if (rv != SECSuccess) { goto loser; } if (mark) { PORT_ArenaUnmark(poolp, mark); } return SECSuccess; loser: *dest = NULL; if (mark) { PORT_ArenaRelease(poolp, mark); } return SECFailure; }
SECStatus NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag, SECItem *digestdata) { SECItem *digest = NULL; PLArenaPool *poolp; void *mark; int n, cnt; if (!sigd) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } poolp = sigd->cmsg->poolp; mark = PORT_ArenaMark(poolp); if (digestdata) { digest = (SECItem *) PORT_ArenaZAlloc(poolp,sizeof(SECItem)); /* copy digestdata item to arena (in case we have it and are not only making room) */ if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess) goto loser; } /* now allocate one (same size as digestAlgorithms) */ if (sigd->digests == NULL) { cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms); sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *)); if (sigd->digests == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } } n = -1; if (sigd->digestAlgorithms != NULL) n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); /* if not found, add a digest */ if (n < 0) { if (NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, digest) != SECSuccess) goto loser; } else { /* replace NULL pointer with digest item (and leak previous value) */ sigd->digests[n] = digest; } PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return SECFailure; }
/* * SecCmsEncryptedDataCreate - create an empty encryptedData object. * * "algorithm" specifies the bulk encryption algorithm to use. * "keysize" is the key size. * * An error results in a return value of NULL and an error set. * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ SecCmsEncryptedDataRef SecCmsEncryptedDataCreate(SecCmsMessageRef cmsg, SECOidTag algorithm, int keysize) { void *mark; SecCmsEncryptedDataRef encd; PLArenaPool *poolp; #if 0 SECAlgorithmID *pbe_algid; #endif OSStatus rv; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); encd = (SecCmsEncryptedDataRef)PORT_ArenaZAlloc(poolp, sizeof(SecCmsEncryptedData)); if (encd == NULL) goto loser; encd->cmsg = cmsg; /* version is set in SecCmsEncryptedDataEncodeBeforeStart() */ switch (algorithm) { /* XXX hmmm... hardcoded algorithms? */ case SEC_OID_RC2_CBC: case SEC_OID_DES_EDE3_CBC: case SEC_OID_DES_CBC: rv = SecCmsContentInfoSetContentEncAlg((SecArenaPoolRef)poolp, &(encd->contentInfo), algorithm, NULL, keysize); break; default: /* Assume password-based-encryption. At least, try that. */ #if 1 // @@@ Fix me rv = SECFailure; break; #else pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL); if (pbe_algid == NULL) { rv = SECFailure; break; } rv = SecCmsContentInfoSetContentEncAlgID((SecArenaPoolRef)poolp, &(encd->contentInfo), pbe_algid, keysize); SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); break; #endif } if (rv != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return encd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
SecAsn1Item * SECITEM_AllocItem(PRArenaPool *arena, SecAsn1Item *item, size_t len) { SecAsn1Item *result = NULL; void *mark = NULL; if (arena != NULL) { mark = PORT_ArenaMark(arena); } if (item == NULL) { if (arena != NULL) { result = PORT_ArenaZAlloc(arena, sizeof(SecAsn1Item)); } else { result = PORT_ZAlloc(sizeof(SecAsn1Item)); } if (result == NULL) { goto loser; } } else { PORT_Assert(item->Data == NULL); result = item; } result->Length = len; if (len) { if (arena != NULL) { result->Data = PORT_ArenaAlloc(arena, len); } else { result->Data = PORT_Alloc(len); } } if (mark) { PORT_ArenaUnmark(arena, mark); } return(result); loser: if ( arena != NULL ) { if (mark) { PORT_ArenaRelease(arena, mark); } if (item != NULL) { item->Data = NULL; item->Length = 0; } } else { if (result != NULL) { SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE); } } return(NULL); }
OSStatus SecCmsSignedDataSetDigestValue(SecCmsSignedDataRef sigd, SECOidTag digestalgtag, CSSM_DATA_PTR digestdata) { CSSM_DATA_PTR digest = NULL; PLArenaPool *poolp; void *mark; int n, cnt; poolp = sigd->cmsg->poolp; mark = PORT_ArenaMark(poolp); if (digestdata) { digest = (CSSM_DATA_PTR) PORT_ArenaZAlloc(poolp,sizeof(CSSM_DATA)); /* copy digestdata item to arena (in case we have it and are not only making room) */ if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess) goto loser; } /* now allocate one (same size as digestAlgorithms) */ if (sigd->digests == NULL) { cnt = SecCmsArrayCount((void **)sigd->digestAlgorithms); sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(CSSM_DATA_PTR)); if (sigd->digests == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } } n = -1; if (sigd->digestAlgorithms != NULL) n = SecCmsAlgArrayGetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); /* if not found, add a digest */ if (n < 0) { if (SecCmsSignedDataAddDigest((SecArenaPoolRef)poolp, sigd, digestalgtag, digest) != SECSuccess) goto loser; } else { /* replace NULL pointer with digest item (and leak previous value) */ sigd->digests[n] = digest; } PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return SECFailure; }
/* * NSS_CMSEncryptedData_Create - create an empty encryptedData object. * * "algorithm" specifies the bulk encryption algorithm to use. * "keysize" is the key size. * * An error results in a return value of NULL and an error set. * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ NSSCMSEncryptedData * NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize) { void *mark; NSSCMSEncryptedData *encd; PLArenaPool *poolp; SECAlgorithmID *pbe_algid; SECStatus rv; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); encd = PORT_ArenaZNew(poolp, NSSCMSEncryptedData); if (encd == NULL) goto loser; encd->cmsg = cmsg; /* version is set in NSS_CMSEncryptedData_Encode_BeforeStart() */ if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) { rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(encd->contentInfo), algorithm, NULL, keysize); } else { /* Assume password-based-encryption. * Note: we can't generate pkcs5v2 from this interface. * PK11_CreateBPEAlgorithmID generates pkcs5v2 by accepting * non-PBE oids and assuming that they are pkcs5v2 oids, but * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular * CMS encrypted data, so we can't tell NSS_CMS_EncryptedData_Create * to create pkcs5v2 PBEs */ pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL); if (pbe_algid == NULL) { rv = SECFailure; } else { rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, &(encd->contentInfo), pbe_algid, keysize); SECOID_DestroyAlgorithmID(pbe_algid, PR_TRUE); } } if (rv != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return encd; loser: PORT_ArenaRelease(poolp, mark); return NULL; }
OSStatus SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, SecPublicKeyRef publickey, SecSymmetricKeyRef bulkkey, SecAsn1Item * encKey) { OSStatus rv; size_t data_len; //KeyType keyType; void *mark = NULL; mark = PORT_ArenaMark(poolp); if (!mark) goto loser; #if 0 /* sanity check */ keyType = SECKEY_GetPublicKeyType(publickey); PORT_Assert(keyType == rsaKey); if (keyType != rsaKey) { goto loser; } #endif /* allocate memory for the encrypted key */ #if USE_CDSA_CRYPTO rv = SecKeyGetStrengthInBits(publickey, NULL, &data_len); if (rv) goto loser; // Convert length to bytes; data_len >>= 2; #else data_len = SecKeyGetSize(publickey, kSecKeyEncryptedDataSize); #endif encKey->Data = (unsigned char*)PORT_ArenaAlloc(poolp, data_len); encKey->Length = data_len; if (encKey->Data == NULL) goto loser; /* encrypt the key now */ rv = WRAP_PubWrapSymKey(publickey, bulkkey, encKey); if (rv != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: if (mark) { PORT_ArenaRelease(poolp, mark); } return SECFailure; }
/* * NSS_CMSSignedData_CreateCertsOnly - create a certs-only SignedData. * * cert - base certificates that will be included * include_chain - if true, include the complete cert chain for cert * * More certs and chains can be added via AddCertificate and AddCertChain. * * An error results in a return value of NULL and an error set. * * XXXX CRLs */ NSSCMSSignedData * NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain) { NSSCMSSignedData *sigd; void *mark; PLArenaPool *poolp; SECStatus rv; if (!cmsg || !cert) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); sigd = NSS_CMSSignedData_Create(cmsg); if (sigd == NULL) goto loser; /* no signerinfos, thus no digestAlgorithms */ /* but certs */ if (include_chain) { rv = NSS_CMSSignedData_AddCertChain(sigd, cert); } else { rv = NSS_CMSSignedData_AddCertificate(sigd, cert); } if (rv != SECSuccess) goto loser; /* RFC2630 5.2 sez: * In the degenerate case where there are no signers, the * EncapsulatedContentInfo value being "signed" is irrelevant. In this * case, the content type within the EncapsulatedContentInfo value being * "signed" should be id-data (as defined in section 4), and the content * field of the EncapsulatedContentInfo value should be omitted. */ rv = NSS_CMSContentInfo_SetContent_Data(cmsg, &(sigd->contentInfo), NULL, PR_TRUE); if (rv != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return sigd; loser: if (sigd) NSS_CMSSignedData_Destroy(sigd); PORT_ArenaRelease(poolp, mark); return NULL; }
CERTAuthKeyID * CERT_DecodeAuthKeyID (PLArenaPool *arena, const SECItem *encodedValue) { CERTAuthKeyID * value = NULL; SECStatus rv = SECFailure; void * mark; SECItem newEncodedValue; PORT_Assert (arena); do { mark = PORT_ArenaMark (arena); value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); if (value == NULL) break; value->DERAuthCertIssuer = NULL; /* copy the DER into the arena, since Quick DER returns data that points into the DER input, which may get freed by the caller */ rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); if ( rv != SECSuccess ) { break; } rv = SEC_QuickDERDecodeItem (arena, value, CERTAuthKeyIDTemplate, &newEncodedValue); if (rv != SECSuccess) break; value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer); if (value->authCertIssuer == NULL) break; /* what if the general name contains other format but not URI ? hl */ if ((value->authCertSerialNumber.data && !value->authCertIssuer) || (!value->authCertSerialNumber.data && value->authCertIssuer)){ PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); break; } } while (0); if (rv != SECSuccess) { PORT_ArenaRelease (arena, mark); return ((CERTAuthKeyID *)NULL); } PORT_ArenaUnmark(arena, mark); return (value); }
/* * The strategy for adding templates will differ from all the other * attributes in the template. First, we want to allow the client * of this API to set extensions more than just once. So we will * need the ability grow the array of extensions. Since arenas don't * give us the realloc function, we'll use the generic PORT_* functions * to allocate the array of pointers *ONLY*. Then we will allocate each * individual extension from the arena that comes along with the certReq * structure that owns this template. */ static SECStatus crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate, CRMFCertExtCreationInfo *extensions) { void *mark; int newSize, oldSize, i; SECStatus rv; CRMFCertExtension **extArray; CRMFCertExtension *newExt, *currExt; mark = PORT_ArenaMark(poolp); if (inTemplate->extensions == NULL) { newSize = extensions->numExtensions; extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1); } else {
static SECStatus crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag, CRMFControl **destControl) { SECOidData *oidData; SECStatus rv; PRArenaPool *poolp; int numControls = 0; CRMFControl *newControl; CRMFControl **controls; void *mark; poolp = inCertReq->poolp; if (poolp == NULL) { return SECFailure; } mark = PORT_ArenaMark(poolp); if (inCertReq->controls != NULL) { while (inCertReq->controls[numControls] != NULL) numControls++; } rv = crmf_modify_control_array(inCertReq, numControls); if (rv != SECSuccess) { goto loser; } controls = inCertReq->controls; oidData = SECOID_FindOIDByTag(inTag); newControl = *destControl = PORT_ArenaZNew(poolp,CRMFControl); if (newControl == NULL) { goto loser; } rv = SECITEM_CopyItem(poolp, &newControl->derTag, &oidData->oid); if (rv != SECSuccess) { goto loser; } newControl->tag = inTag; controls[numControls] = newControl; controls[numControls+1] = NULL; PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); *destControl = NULL; return SECFailure; }
/* * SecCmsSignedDataCreateCertsOnly - create a certs-only SignedData. * * cert - base certificates that will be included * include_chain - if true, include the complete cert chain for cert * * More certs and chains can be added via AddCertificate and AddCertChain. * * An error results in a return value of NULL and an error set. * * XXXX CRLs */ SecCmsSignedDataRef SecCmsSignedDataCreateCertsOnly(SecCmsMessageRef cmsg, SecCertificateRef cert, Boolean include_chain) { SecCmsSignedDataRef sigd; void *mark; PLArenaPool *poolp; OSStatus rv; poolp = cmsg->poolp; mark = PORT_ArenaMark(poolp); sigd = SecCmsSignedDataCreate(cmsg); if (sigd == NULL) goto loser; /* no signerinfos, thus no digestAlgorithms */ /* but certs */ if (include_chain) { rv = SecCmsSignedDataAddCertChain(sigd, cert); } else { rv = SecCmsSignedDataAddCertificate(sigd, cert); } if (rv != SECSuccess) goto loser; /* RFC2630 5.2 sez: * In the degenerate case where there are no signers, the * EncapsulatedContentInfo value being "signed" is irrelevant. In this * case, the content type within the EncapsulatedContentInfo value being * "signed" should be id-data (as defined in section 4), and the content * field of the EncapsulatedContentInfo value should be omitted. */ rv = SecCmsContentInfoSetContentData(cmsg, &(sigd->contentInfo), NULL, PR_TRUE); if (rv != SECSuccess) goto loser; PORT_ArenaUnmark(poolp, mark); return sigd; loser: if (sigd) SecCmsSignedDataDestroy(sigd); PORT_ArenaRelease(poolp, mark); return NULL; }