]> git.saurik.com Git - apple/security.git/blob - libsecurity_smime/lib/cmsdigdata.c
Security-57031.30.12.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 /* everything's in a pool, so don't worry about the storage */
95 SecCmsContentInfoDestroy(&(digd->contentInfo));
96 return;
97 }
98
99 /*
100 * SecCmsDigestedDataGetContentInfo - return pointer to digestedData object's contentInfo
101 */
102 SecCmsContentInfoRef
103 SecCmsDigestedDataGetContentInfo(SecCmsDigestedDataRef digd)
104 {
105 return &(digd->contentInfo);
106 }
107
108 /*
109 * SecCmsDigestedDataEncodeBeforeStart - do all the necessary things to a DigestedData
110 * before encoding begins.
111 *
112 * In particular:
113 * - set the right version number. The contentInfo's content type must be set up already.
114 */
115 OSStatus
116 SecCmsDigestedDataEncodeBeforeStart(SecCmsDigestedDataRef digd)
117 {
118 unsigned long version;
119 SecAsn1Item * dummy;
120
121 version = SEC_CMS_DIGESTED_DATA_VERSION_DATA;
122 if (SecCmsContentInfoGetContentTypeTag(&(digd->contentInfo)) != SEC_OID_PKCS7_DATA)
123 version = SEC_CMS_DIGESTED_DATA_VERSION_ENCAP;
124
125 dummy = SEC_ASN1EncodeInteger(digd->contentInfo.cmsg->poolp, &(digd->version), version);
126 return (dummy == NULL) ? SECFailure : SECSuccess;
127 }
128
129 /*
130 * SecCmsDigestedDataEncodeBeforeData - do all the necessary things to a DigestedData
131 * before the encapsulated data is passed through the encoder.
132 *
133 * In detail:
134 * - set up the digests if necessary
135 */
136 OSStatus
137 SecCmsDigestedDataEncodeBeforeData(SecCmsDigestedDataRef digd)
138 {
139 /* set up the digests */
140 if (digd->digestAlg.algorithm.Length != 0 && digd->digest.Length == 0) {
141 /* if digest is already there, do nothing */
142 digd->contentInfo.digcx = SecCmsDigestContextStartSingle(&(digd->digestAlg));
143 if (digd->contentInfo.digcx == NULL)
144 return SECFailure;
145 }
146 return SECSuccess;
147 }
148
149 /*
150 * SecCmsDigestedDataEncodeAfterData - do all the necessary things to a DigestedData
151 * after all the encapsulated data was passed through the encoder.
152 *
153 * In detail:
154 * - finish the digests
155 */
156 OSStatus
157 SecCmsDigestedDataEncodeAfterData(SecCmsDigestedDataRef digd)
158 {
159 OSStatus rv = SECSuccess;
160 /* did we have digest calculation going on? */
161 if (digd->contentInfo.digcx) {
162 SecAsn1Item data;
163 rv = SecCmsDigestContextFinishSingle(digd->contentInfo.digcx, &data);
164 if (rv == SECSuccess)
165 rv = SECITEM_CopyItem(digd->contentInfo.cmsg->poolp, &(digd->digest), &data);
166 if (rv == SECSuccess)
167 SecCmsDigestContextDestroy(digd->contentInfo.digcx);
168 digd->contentInfo.digcx = NULL;
169 }
170
171 return rv;
172 }
173
174 /*
175 * SecCmsDigestedDataDecodeBeforeData - do all the necessary things to a DigestedData
176 * before the encapsulated data is passed through the encoder.
177 *
178 * In detail:
179 * - set up the digests if necessary
180 */
181 OSStatus
182 SecCmsDigestedDataDecodeBeforeData(SecCmsDigestedDataRef digd)
183 {
184 /* is there a digest algorithm yet? */
185 if (digd->digestAlg.algorithm.Length == 0)
186 return SECFailure;
187
188 digd->contentInfo.digcx = SecCmsDigestContextStartSingle(&(digd->digestAlg));
189 if (digd->contentInfo.digcx == NULL)
190 return SECFailure;
191
192 return SECSuccess;
193 }
194
195 /*
196 * SecCmsDigestedDataDecodeAfterData - do all the necessary things to a DigestedData
197 * after all the encapsulated data was passed through the encoder.
198 *
199 * In detail:
200 * - finish the digests
201 */
202 OSStatus
203 SecCmsDigestedDataDecodeAfterData(SecCmsDigestedDataRef digd)
204 {
205 OSStatus rv = SECSuccess;
206 /* did we have digest calculation going on? */
207 if (digd->contentInfo.digcx) {
208 SecAsn1Item data;
209 rv = SecCmsDigestContextFinishSingle(digd->contentInfo.digcx, &data);
210 if (rv == SECSuccess)
211 rv = SECITEM_CopyItem(digd->contentInfo.cmsg->poolp, &(digd->digest), &data);
212 if (rv == SECSuccess)
213 SecCmsDigestContextDestroy(digd->contentInfo.digcx);
214 digd->contentInfo.digcx = NULL;
215 }
216
217 return rv;
218 }
219
220 /*
221 * SecCmsDigestedDataDecodeAfterEnd - finalize a digestedData.
222 *
223 * In detail:
224 * - check the digests for equality
225 */
226 OSStatus
227 SecCmsDigestedDataDecodeAfterEnd(SecCmsDigestedDataRef digd)
228 {
229 /* did we have digest calculation going on? */
230 if (digd->cdigest.Length != 0) {
231 /* XXX comparision btw digest & cdigest */
232 /* XXX set status */
233 /* TODO!!!! */
234 }
235
236 return SECSuccess;
237 }