123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /*
- * CMS recipient list functions
- */
- #include "cmslocal.h"
- #include "cert.h"
- #include "keyhi.h"
- #include "secasn1.h"
- #include "secitem.h"
- #include "secoid.h"
- #include "pk11func.h"
- #include "prtime.h"
- #include "secerr.h"
- static int
- nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos,
- NSSCMSRecipient **recipient_list)
- {
- int count = 0;
- int rlindex = 0;
- int i, j;
- NSSCMSRecipient *rle;
- NSSCMSRecipientInfo *ri;
- NSSCMSRecipientEncryptedKey *rek;
- for (i = 0; recipientinfos[i] != NULL; i++) {
- ri = recipientinfos[i];
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- if (recipient_list) {
- NSSCMSRecipientIdentifier *recipId =
- &ri->ri.keyTransRecipientInfo.recipientIdentifier;
- if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
- recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return -1;
- }
- /* alloc one & fill it out */
- rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
- if (!rle)
- return -1;
- rle->riIndex = i;
- rle->subIndex = -1;
- switch (recipId->identifierType) {
- case NSSCMSRecipientID_IssuerSN:
- rle->kind = RLIssuerSN;
- rle->id.issuerAndSN = recipId->id.issuerAndSN;
- break;
- case NSSCMSRecipientID_SubjectKeyID:
- rle->kind = RLSubjKeyID;
- rle->id.subjectKeyID = recipId->id.subjectKeyID;
- break;
- default: /* we never get here because of identifierType check
- we done before. Leaving it to kill compiler warning */
- break;
- }
- recipient_list[rlindex++] = rle;
- } else {
- count++;
- }
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
- break;
- for (j = 0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
- if (recipient_list) {
- rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
- /* alloc one & fill it out */
- rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
- if (!rle)
- return -1;
- rle->riIndex = i;
- rle->subIndex = j;
- switch (rek->recipientIdentifier.identifierType) {
- case NSSCMSKeyAgreeRecipientID_IssuerSN:
- rle->kind = RLIssuerSN;
- rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
- break;
- case NSSCMSKeyAgreeRecipientID_RKeyID:
- rle->kind = RLSubjKeyID;
- rle->id.subjectKeyID =
- rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier;
- break;
- }
- recipient_list[rlindex++] = rle;
- } else {
- count++;
- }
- }
- break;
- case NSSCMSRecipientInfoID_KEK:
- /* KEK is not implemented */
- break;
- }
- }
- /* if we have a recipient list, we return on success (-1, above, on failure) */
- /* otherwise, we return the count. */
- if (recipient_list) {
- recipient_list[rlindex] = NULL;
- return 0;
- } else {
- return count;
- }
- }
- NSSCMSRecipient **
- nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos)
- {
- int count, rv;
- NSSCMSRecipient **recipient_list;
- /* count the number of recipient identifiers */
- count = nss_cms_recipients_traverse(recipientinfos, NULL);
- if (count <= 0) {
- /* no recipients? */
- PORT_SetError(SEC_ERROR_BAD_DATA);
- #if 0
- PORT_SetErrorString("Cannot find recipient data in envelope.");
- #endif
- return NULL;
- }
- /* allocate an array of pointers */
- recipient_list = (NSSCMSRecipient **)
- PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
- if (recipient_list == NULL)
- return NULL;
- /* now fill in the recipient_list */
- rv = nss_cms_recipients_traverse(recipientinfos, recipient_list);
- if (rv < 0) {
- nss_cms_recipient_list_destroy(recipient_list);
- return NULL;
- }
- return recipient_list;
- }
- void
- nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list)
- {
- int i;
- NSSCMSRecipient *recipient;
- for (i = 0; recipient_list[i] != NULL; i++) {
- recipient = recipient_list[i];
- if (recipient->cert)
- CERT_DestroyCertificate(recipient->cert);
- if (recipient->privkey)
- SECKEY_DestroyPrivateKey(recipient->privkey);
- if (recipient->slot)
- PK11_FreeSlot(recipient->slot);
- PORT_Free(recipient);
- }
- PORT_Free(recipient_list);
- }
- NSSCMSRecipientEncryptedKey *
- NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp)
- {
- return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp,
- sizeof(NSSCMSRecipientEncryptedKey));
- }
|