Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 }