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/
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.
12 * The Original Code is the Netscape security libraries.
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
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
35 * CMS digestedData methods.
38 #include <Security/SecCmsDigestedData.h>
40 #include <Security/SecCmsContentInfo.h>
41 #include <Security/SecCmsDigestContext.h>
45 #include "SecAsn1Item.h"
48 #include <security_asn1/secasn1.h>
49 #include <security_asn1/secerr.h>
50 #include <security_asn1/secport.h>
53 * SecCmsDigestedDataCreate - create a digestedData object (presumably for encoding)
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
61 SecCmsDigestedDataCreate(SecCmsMessageRef cmsg
, SECAlgorithmID
*digestalg
)
64 SecCmsDigestedDataRef digd
;
69 mark
= PORT_ArenaMark(poolp
);
71 digd
= (SecCmsDigestedDataRef
)PORT_ArenaZAlloc(poolp
, sizeof(SecCmsDigestedData
));
75 digd
->contentInfo
.cmsg
= cmsg
;
77 if (SECOID_CopyAlgorithmID (poolp
, &(digd
->digestAlg
), digestalg
) != SECSuccess
)
80 PORT_ArenaUnmark(poolp
, mark
);
84 PORT_ArenaRelease(poolp
, mark
);
89 * SecCmsDigestedDataDestroy - destroy a digestedData object
92 SecCmsDigestedDataDestroy(SecCmsDigestedDataRef digd
)
94 /* everything's in a pool, so don't worry about the storage */
95 SecCmsContentInfoDestroy(&(digd
->contentInfo
));
100 * SecCmsDigestedDataGetContentInfo - return pointer to digestedData object's contentInfo
103 SecCmsDigestedDataGetContentInfo(SecCmsDigestedDataRef digd
)
105 return &(digd
->contentInfo
);
109 * SecCmsDigestedDataEncodeBeforeStart - do all the necessary things to a DigestedData
110 * before encoding begins.
113 * - set the right version number. The contentInfo's content type must be set up already.
116 SecCmsDigestedDataEncodeBeforeStart(SecCmsDigestedDataRef digd
)
118 unsigned long version
;
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
;
125 dummy
= SEC_ASN1EncodeInteger(digd
->contentInfo
.cmsg
->poolp
, &(digd
->version
), version
);
126 return (dummy
== NULL
) ? SECFailure
: SECSuccess
;
130 * SecCmsDigestedDataEncodeBeforeData - do all the necessary things to a DigestedData
131 * before the encapsulated data is passed through the encoder.
134 * - set up the digests if necessary
137 SecCmsDigestedDataEncodeBeforeData(SecCmsDigestedDataRef digd
)
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
)
150 * SecCmsDigestedDataEncodeAfterData - do all the necessary things to a DigestedData
151 * after all the encapsulated data was passed through the encoder.
154 * - finish the digests
157 SecCmsDigestedDataEncodeAfterData(SecCmsDigestedDataRef digd
)
159 OSStatus rv
= SECSuccess
;
160 /* did we have digest calculation going on? */
161 if (digd
->contentInfo
.digcx
) {
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
;
175 * SecCmsDigestedDataDecodeBeforeData - do all the necessary things to a DigestedData
176 * before the encapsulated data is passed through the encoder.
179 * - set up the digests if necessary
182 SecCmsDigestedDataDecodeBeforeData(SecCmsDigestedDataRef digd
)
184 /* is there a digest algorithm yet? */
185 if (digd
->digestAlg
.algorithm
.Length
== 0)
188 digd
->contentInfo
.digcx
= SecCmsDigestContextStartSingle(&(digd
->digestAlg
));
189 if (digd
->contentInfo
.digcx
== NULL
)
196 * SecCmsDigestedDataDecodeAfterData - do all the necessary things to a DigestedData
197 * after all the encapsulated data was passed through the encoder.
200 * - finish the digests
203 SecCmsDigestedDataDecodeAfterData(SecCmsDigestedDataRef digd
)
205 OSStatus rv
= SECSuccess
;
206 /* did we have digest calculation going on? */
207 if (digd
->contentInfo
.digcx
) {
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
;
221 * SecCmsDigestedDataDecodeAfterEnd - finalize a digestedData.
224 * - check the digests for equality
227 SecCmsDigestedDataDecodeAfterEnd(SecCmsDigestedDataRef digd
)
229 /* did we have digest calculation going on? */
230 if (digd
->cdigest
.Length
!= 0) {
231 /* XXX comparision btw digest & cdigest */