security/nss/lib/smime/cmsreclist.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * CMS recipient list functions
     7  */
     9 #include "cmslocal.h"
    11 #include "cert.h"
    12 #include "key.h"
    13 #include "secasn1.h"
    14 #include "secitem.h"
    15 #include "secoid.h"
    16 #include "pk11func.h"
    17 #include "prtime.h"
    18 #include "secerr.h"
    20 static int
    21 nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipient **recipient_list)
    22 {
    23     int count = 0;
    24     int rlindex = 0;
    25     int i, j;
    26     NSSCMSRecipient *rle;
    27     NSSCMSRecipientInfo *ri;
    28     NSSCMSRecipientEncryptedKey *rek;
    30     for (i = 0; recipientinfos[i] != NULL; i++) {
    31 	ri = recipientinfos[i];
    32 	switch (ri->recipientInfoType) {
    33 	case NSSCMSRecipientInfoID_KeyTrans:
    34 	    if (recipient_list) {
    35 		NSSCMSRecipientIdentifier *recipId =
    36 		   &ri->ri.keyTransRecipientInfo.recipientIdentifier;
    38 		if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
    39                     recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
    40 		    PORT_SetError(SEC_ERROR_INVALID_ARGS);
    41 		    return -1;
    42 		}                
    43 		/* alloc one & fill it out */
    44 		rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
    45 		if (!rle)
    46 		    return -1;
    48 		rle->riIndex = i;
    49 		rle->subIndex = -1;
    50 		switch (recipId->identifierType) {
    51 		case NSSCMSRecipientID_IssuerSN:
    52 		    rle->kind = RLIssuerSN;
    53 		    rle->id.issuerAndSN = recipId->id.issuerAndSN;
    54 		    break;
    55 		case NSSCMSRecipientID_SubjectKeyID:
    56 		    rle->kind = RLSubjKeyID;
    57 		    rle->id.subjectKeyID = recipId->id.subjectKeyID;
    58 		    break;
    59 		default: /* we never get here because of identifierType check
    60                             we done before. Leaving it to kill compiler warning */
    61 		    break;
    62 		}
    63 		recipient_list[rlindex++] = rle;
    64 	    } else {
    65 		count++;
    66 	    }
    67 	    break;
    68 	case NSSCMSRecipientInfoID_KeyAgree:
    69 	    if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
    70 		break;
    71 	    for (j=0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
    72 		if (recipient_list) {
    73 		    rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
    74 		    /* alloc one & fill it out */
    75 		    rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
    76 		    if (!rle)
    77 			return -1;
    79 		    rle->riIndex = i;
    80 		    rle->subIndex = j;
    81 		    switch (rek->recipientIdentifier.identifierType) {
    82 		    case NSSCMSKeyAgreeRecipientID_IssuerSN:
    83 			rle->kind = RLIssuerSN;
    84 			rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
    85 			break;
    86 		    case NSSCMSKeyAgreeRecipientID_RKeyID:
    87 			rle->kind = RLSubjKeyID;
    88 			rle->id.subjectKeyID = rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier;
    89 			break;
    90 		    }
    91 		    recipient_list[rlindex++] = rle;
    92 		} else {
    93 		    count++;
    94 		}
    95 	    }
    96 	    break;
    97 	case NSSCMSRecipientInfoID_KEK:
    98 	    /* KEK is not implemented */
    99 	    break;
   100 	}
   101     }
   102     /* if we have a recipient list, we return on success (-1, above, on failure) */
   103     /* otherwise, we return the count. */
   104     if (recipient_list) {
   105 	recipient_list[rlindex] = NULL;
   106 	return 0;
   107     } else {
   108 	return count;
   109     }
   110 }
   112 NSSCMSRecipient **
   113 nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos)
   114 {
   115     int count, rv;
   116     NSSCMSRecipient **recipient_list;
   118     /* count the number of recipient identifiers */
   119     count = nss_cms_recipients_traverse(recipientinfos, NULL);
   120     if (count <= 0) {
   121 	/* no recipients? */
   122 	PORT_SetError(SEC_ERROR_BAD_DATA);
   123 #if 0
   124 	PORT_SetErrorString("Cannot find recipient data in envelope.");
   125 #endif
   126 	return NULL;
   127     }
   129     /* allocate an array of pointers */
   130     recipient_list = (NSSCMSRecipient **)
   131 		    PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
   132     if (recipient_list == NULL)
   133 	return NULL;
   135     /* now fill in the recipient_list */
   136     rv = nss_cms_recipients_traverse(recipientinfos, recipient_list);
   137     if (rv < 0) {
   138 	nss_cms_recipient_list_destroy(recipient_list);
   139 	return NULL;
   140     }
   141     return recipient_list;
   142 }
   144 void
   145 nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list)
   146 {
   147     int i;
   148     NSSCMSRecipient *recipient;
   150     for (i=0; recipient_list[i] != NULL; i++) {
   151 	recipient = recipient_list[i];
   152 	if (recipient->cert)
   153 	    CERT_DestroyCertificate(recipient->cert);
   154 	if (recipient->privkey)
   155 	    SECKEY_DestroyPrivateKey(recipient->privkey);
   156 	if (recipient->slot)
   157 	    PK11_FreeSlot(recipient->slot);
   158 	PORT_Free(recipient);
   159     }
   160     PORT_Free(recipient_list);
   161 }
   163 NSSCMSRecipientEncryptedKey *
   164 NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp)
   165 {
   166     return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientEncryptedKey));
   167 }

mercurial