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/. */
4
5 /*
6 * CMS digestedData methods.
7 */
8
9 #include "cmslocal.h"
10
11 #include "secitem.h"
12 #include "secasn1.h"
13 #include "secoid.h"
14 #include "secerr.h"
15
16 /*
17 * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding)
18 *
19 * version will be set by NSS_CMSDigestedData_Encode_BeforeStart
20 * digestAlg is passed as parameter
21 * contentInfo must be filled by the user
22 * digest will be calculated while encoding
23 */
24 NSSCMSDigestedData *
NSS_CMSDigestedData_Create(NSSCMSMessage * cmsg,SECAlgorithmID * digestalg)25 NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg)
26 {
27 void *mark;
28 NSSCMSDigestedData *digd;
29 PLArenaPool *poolp;
30
31 poolp = cmsg->poolp;
32
33 mark = PORT_ArenaMark(poolp);
34
35 digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData));
36 if (digd == NULL)
37 goto loser;
38
39 digd->cmsg = cmsg;
40
41 if (SECOID_CopyAlgorithmID(poolp, &(digd->digestAlg), digestalg) != SECSuccess)
42 goto loser;
43
44 PORT_ArenaUnmark(poolp, mark);
45 return digd;
46
47 loser:
48 PORT_ArenaRelease(poolp, mark);
49 return NULL;
50 }
51
52 /*
53 * NSS_CMSDigestedData_Destroy - destroy a digestedData object
54 */
55 void
NSS_CMSDigestedData_Destroy(NSSCMSDigestedData * digd)56 NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd)
57 {
58 /* everything's in a pool, so don't worry about the storage */
59 NSS_CMSContentInfo_Destroy(&(digd->contentInfo));
60 return;
61 }
62
63 /*
64 * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo
65 */
66 NSSCMSContentInfo *
NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData * digd)67 NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd)
68 {
69 return &(digd->contentInfo);
70 }
71
72 /*
73 * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData
74 * before encoding begins.
75 *
76 * In particular:
77 * - set the right version number. The contentInfo's content type must be set up already.
78 */
79 SECStatus
NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData * digd)80 NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd)
81 {
82 unsigned long version;
83 SECItem *dummy;
84
85 version = NSS_CMS_DIGESTED_DATA_VERSION_DATA;
86 if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag(
87 &(digd->contentInfo))))
88 version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP;
89
90 dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version);
91 return (dummy == NULL) ? SECFailure : SECSuccess;
92 }
93
94 /*
95 * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData
96 * before the encapsulated data is passed through the encoder.
97 *
98 * In detail:
99 * - set up the digests if necessary
100 */
101 SECStatus
NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData * digd)102 NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd)
103 {
104 SECStatus rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
105 if (rv != SECSuccess) {
106 return SECFailure;
107 }
108
109 /* set up the digests */
110 if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) {
111 /* if digest is already there, do nothing */
112 digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
113 if (digd->contentInfo.privateInfo->digcx == NULL)
114 return SECFailure;
115 }
116 return SECSuccess;
117 }
118
119 /*
120 * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData
121 * after all the encapsulated data was passed through the encoder.
122 *
123 * In detail:
124 * - finish the digests
125 */
126 SECStatus
NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData * digd)127 NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd)
128 {
129 SECStatus rv = SECSuccess;
130 /* did we have digest calculation going on? */
131 if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) {
132 rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx,
133 digd->cmsg->poolp,
134 &(digd->digest));
135 /* error has been set by NSS_CMSDigestContext_FinishSingle */
136 digd->contentInfo.privateInfo->digcx = NULL;
137 }
138
139 return rv;
140 }
141
142 /*
143 * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData
144 * before the encapsulated data is passed through the encoder.
145 *
146 * In detail:
147 * - set up the digests if necessary
148 */
149 SECStatus
NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData * digd)150 NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd)
151 {
152 SECStatus rv;
153
154 /* is there a digest algorithm yet? */
155 if (digd->digestAlg.algorithm.len == 0)
156 return SECFailure;
157
158 rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
159 if (rv != SECSuccess) {
160 return SECFailure;
161 }
162
163 digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
164 if (digd->contentInfo.privateInfo->digcx == NULL)
165 return SECFailure;
166
167 return SECSuccess;
168 }
169
170 /*
171 * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData
172 * after all the encapsulated data was passed through the encoder.
173 *
174 * In detail:
175 * - finish the digests
176 */
177 SECStatus
NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData * digd)178 NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd)
179 {
180 SECStatus rv = SECSuccess;
181 /* did we have digest calculation going on? */
182 if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) {
183 rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx,
184 digd->cmsg->poolp,
185 &(digd->cdigest));
186 /* error has been set by NSS_CMSDigestContext_FinishSingle */
187 digd->contentInfo.privateInfo->digcx = NULL;
188 }
189
190 return rv;
191 }
192
193 /*
194 * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData.
195 *
196 * In detail:
197 * - check the digests for equality
198 */
199 SECStatus
NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData * digd)200 NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd)
201 {
202 /* did we have digest calculation going on? */
203 if (digd->cdigest.len != 0) {
204 /* XXX comparision btw digest & cdigest */
205 /* XXX set status */
206 /* TODO!!!! */
207 }
208
209 return SECSuccess;
210 }
211