]> git.saurik.com Git - apple/security.git/blob - libsecurity_smime/lib/cmsdigdata.c
Security-59306.61.1.tar.gz
[apple/security.git] / libsecurity_smime / lib / cmsdigdata.c
1 /*
2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
6 *
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
11 *
12 * The Original Code is the Netscape security libraries.
13 *
14 * The Initial Developer of the Original Code is Netscape
15 * Communications Corporation. Portions created by Netscape are
16 * Copyright (C) 1994-2000 Netscape Communications Corporation. All
17 * Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the
22 * terms of the GNU General Public License Version 2 or later (the
23 * "GPL"), in which case the provisions of the GPL are applicable
24 * instead of those above. If you wish to allow use of your
25 * version of this file only under the terms of the GPL and not to
26 * allow others to use your version of this file under the MPL,
27 * indicate your decision by deleting the provisions above and
28 * replace them with the notice and other provisions required by
29 * the GPL. If you do not delete the provisions above, a recipient
30 * may use your version of this file under either the MPL or the
31 * GPL.
32 */
33
34 /*
35 * CMS digestedData methods.
36 */
37
38 #include <Security/SecCmsDigestedData.h>
39
40 #include <Security/SecCmsContentInfo.h>
41 #include <Security/SecCmsDigestContext.h>
42
43 #include "cmslocal.h"
44
45 #include "SecAsn1Item.h"
46 #include "secoid.h"
47
48 #include <security_asn1/secasn1.h>
49 #include <security_asn1/secerr.h>
50 #include <security_asn1/secport.h>
51
52 /*
53 * SecCmsDigestedDataCreate - create a digestedData object (presumably for encoding)
54 *
55 * version will be set by SecCmsDigestedDataEncodeBeforeStart
56 * digestAlg is passed as parameter
57 * contentInfo must be filled by the user
58 * digest will be calculated while encoding
59 */
60 SecCmsDigestedDataRef
61 SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg)
62 {
63 void *mark;
64 SecCmsDigestedDataRef digd;
65 PLArenaPool *poolp;
66
67 poolp = cmsg->poolp;
68
69 mark = PORT_ArenaMark(poolp);
70
71 digd = (SecCmsDigestedDataRef)PORT_ArenaZAlloc(poolp, sizeof(SecCmsDigestedData));
72 if (digd == NULL)
73 goto loser;
74
75 digd->contentInfo.cmsg = cmsg;
76
77 if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess)
78 goto loser;
79
80 PORT_ArenaUnmark(poolp, mark);
81 return digd;
82
83 loser:
84 PORT_ArenaRelease(poolp, mark);
85 return NULL;
86 }
87
88 /*
89 * SecCmsDigestedDataDestroy - destroy a digestedData object
90 */
91 void
92 SecCmsDigestedDataDestroy(SecCmsDigestedDataRef digd)
93 {
94 if (digd == NULL) {
95 return;
96 }
97 /* everything's in a pool, so don't worry about the storage */
98 SecCmsContentInfoDestroy(&(digd->contentInfo));
99 return;
100 }
101
102 /*
103 * SecCmsDigestedDataGetContentInfo - return pointer to digestedData object's contentInfo
104 */
105 SecCmsContentInfoRef
106 SecCmsDigestedDataGetContentInfo(SecCmsDigestedDataRef digd)
107 {
108 return &(digd->contentInfo);
109 }
110
111 /*
112 * SecCmsDigestedDataEncodeBeforeStart - do all the necessary things to a DigestedData
113 * before encoding begins.
114 *
115 * In particular:
116 * - set the right version number. The contentInfo's content type must be set up already.
117 */
118 OSStatus
119 SecCmsDigestedDataEncodeBeforeStart(SecCmsDigestedDataRef digd)
120 {
121 unsigned long version;
122 SecAsn1Item * dummy;
123
124 version = SEC_CMS_DIGESTED_DATA_VERSION_DATA;
125 if (SecCmsContentInfoGetContentTypeTag(&(digd->contentInfo)) != SEC_OID_PKCS7_DATA)
126 version = SEC_CMS_DIGESTED_DATA_VERSION_ENCAP;
127
128 dummy = SEC_ASN1EncodeInteger(digd->contentInfo.cmsg->poolp, &(digd->version), version);
129 return (dummy == NULL) ? SECFailure : SECSuccess;
130 }
131
132 /*
133 * SecCmsDigestedDataEncodeBeforeData - do all the necessary things to a DigestedData
134 * before the encapsulated data is passed through the encoder.
135 *
136 * In detail:
137 * - set up the digests if necessary
138 */
139 OSStatus
140 SecCmsDigestedDataEncodeBeforeData(SecCmsDigestedDataRef digd)
141 {
142 /* set up the digests */
143 if (digd->digestAlg.algorithm.Length != 0 && digd->digest.Length == 0) {
144 /* if digest is already there, do nothing */
145 digd->contentInfo.digcx = SecCmsDigestContextStartSingle(&(digd->digestAlg));
146 if (digd->contentInfo.digcx == NULL)
147 return SECFailure;
148 }
149 return SECSuccess;
150 }
151
152 /*
153 * SecCmsDigestedDataEncodeAfterData - do all the necessary things to a DigestedData
154 * after all the encapsulated data was passed through the encoder.
155 *
156 * In detail:
157 * - finish the digests
158 */
159 OSStatus
160 SecCmsDigestedDataEncodeAfterData(SecCmsDigestedDataRef digd)
161 {
162 OSStatus rv = SECSuccess;
163 /* did we have digest calculation going on? */
164 if (digd->contentInfo.digcx) {
165 SecAsn1Item data;
166 rv = SecCmsDigestContextFinishSingle(digd->contentInfo.digcx, &data);
167 if (rv == SECSuccess)
168 rv = SECITEM_CopyItem(digd->contentInfo.cmsg->poolp, &(digd->digest), &data);
169 if (rv == SECSuccess)
170 SecCmsDigestContextDestroy(digd->contentInfo.digcx);
171 digd->contentInfo.digcx = NULL;
172 }
173
174 return rv;
175 }
176
177 /*
178 * SecCmsDigestedDataDecodeBeforeData - do all the necessary things to a DigestedData
179 * before the encapsulated data is passed through the encoder.
180 *
181 * In detail:
182 * - set up the digests if necessary
183 */
184 OSStatus
185 SecCmsDigestedDataDecodeBeforeData(SecCmsDigestedDataRef digd)
186 {
187 /* is there a digest algorithm yet? */
188 if (digd->digestAlg.algorithm.Length == 0)
189 return SECFailure;
190
191 digd->contentInfo.digcx = SecCmsDigestContextStartSingle(&(digd->digestAlg));
192 if (digd->contentInfo.digcx == NULL)
193 return SECFailure;
194
195 return SECSuccess;
196 }
197
198 /*
199 * SecCmsDigestedDataDecodeAfterData - do all the necessary things to a DigestedData
200 * after all the encapsulated data was passed through the encoder.
201 *
202 * In detail:
203 * - finish the digests
204 */
205 OSStatus
206 SecCmsDigestedDataDecodeAfterData(SecCmsDigestedDataRef digd)
207 {
208 OSStatus rv = SECSuccess;
209 /* did we have digest calculation going on? */
210 if (digd->contentInfo.digcx) {
211 SecAsn1Item data;
212 rv = SecCmsDigestContextFinishSingle(digd->contentInfo.digcx, &data);
213 if (rv == SECSuccess)
214 rv = SECITEM_CopyItem(digd->contentInfo.cmsg->poolp, &(digd->digest), &data);
215 if (rv == SECSuccess)
216 SecCmsDigestContextDestroy(digd->contentInfo.digcx);
217 digd->contentInfo.digcx = NULL;
218 }
219
220 return rv;
221 }
222
223 /*
224 * SecCmsDigestedDataDecodeAfterEnd - finalize a digestedData.
225 *
226 * In detail:
227 * - check the digests for equality
228 */
229 OSStatus
230 SecCmsDigestedDataDecodeAfterEnd(SecCmsDigestedDataRef digd)
231 {
232 if (!digd) {
233 return SECFailure;
234 }
235 /* did we have digest calculation going on? */
236 if (digd->cdigest.Length != 0) {
237 /* XXX comparision btw digest & cdigest */
238 /* XXX set status */
239 /* TODO!!!! */
240 }
241
242 return SECSuccess;
243 }