|
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 * |
|
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 |
|
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 * |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 } |