/src/mozilla-central/security/nss/lib/smime/cmsdigdata.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
27 | 0 | void *mark; |
28 | 0 | NSSCMSDigestedData *digd; |
29 | 0 | PLArenaPool *poolp; |
30 | 0 |
|
31 | 0 | poolp = cmsg->poolp; |
32 | 0 |
|
33 | 0 | mark = PORT_ArenaMark(poolp); |
34 | 0 |
|
35 | 0 | digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData)); |
36 | 0 | if (digd == NULL) |
37 | 0 | goto loser; |
38 | 0 | |
39 | 0 | digd->cmsg = cmsg; |
40 | 0 |
|
41 | 0 | if (SECOID_CopyAlgorithmID(poolp, &(digd->digestAlg), digestalg) != SECSuccess) |
42 | 0 | goto loser; |
43 | 0 | |
44 | 0 | PORT_ArenaUnmark(poolp, mark); |
45 | 0 | return digd; |
46 | 0 | |
47 | 0 | loser: |
48 | 0 | PORT_ArenaRelease(poolp, mark); |
49 | 0 | return NULL; |
50 | 0 | } |
51 | | |
52 | | /* |
53 | | * NSS_CMSDigestedData_Destroy - destroy a digestedData object |
54 | | */ |
55 | | void |
56 | | NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd) |
57 | 0 | { |
58 | 0 | /* everything's in a pool, so don't worry about the storage */ |
59 | 0 | NSS_CMSContentInfo_Destroy(&(digd->contentInfo)); |
60 | 0 | return; |
61 | 0 | } |
62 | | |
63 | | /* |
64 | | * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo |
65 | | */ |
66 | | NSSCMSContentInfo * |
67 | | NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd) |
68 | 0 | { |
69 | 0 | return &(digd->contentInfo); |
70 | 0 | } |
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 | 0 | { |
82 | 0 | unsigned long version; |
83 | 0 | SECItem *dummy; |
84 | 0 |
|
85 | 0 | version = NSS_CMS_DIGESTED_DATA_VERSION_DATA; |
86 | 0 | if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag( |
87 | 0 | &(digd->contentInfo)))) |
88 | 0 | version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP; |
89 | 0 |
|
90 | 0 | dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version); |
91 | 0 | return (dummy == NULL) ? SECFailure : SECSuccess; |
92 | 0 | } |
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 | 0 | { |
104 | 0 | SECStatus rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo); |
105 | 0 | if (rv != SECSuccess) { |
106 | 0 | return SECFailure; |
107 | 0 | } |
108 | 0 | |
109 | 0 | /* set up the digests */ |
110 | 0 | if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) { |
111 | 0 | /* if digest is already there, do nothing */ |
112 | 0 | digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); |
113 | 0 | if (digd->contentInfo.privateInfo->digcx == NULL) |
114 | 0 | return SECFailure; |
115 | 0 | } |
116 | 0 | return SECSuccess; |
117 | 0 | } |
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 | 0 | { |
129 | 0 | SECStatus rv = SECSuccess; |
130 | 0 | /* did we have digest calculation going on? */ |
131 | 0 | if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) { |
132 | 0 | rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx, |
133 | 0 | digd->cmsg->poolp, |
134 | 0 | &(digd->digest)); |
135 | 0 | /* error has been set by NSS_CMSDigestContext_FinishSingle */ |
136 | 0 | digd->contentInfo.privateInfo->digcx = NULL; |
137 | 0 | } |
138 | 0 |
|
139 | 0 | return rv; |
140 | 0 | } |
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 | 0 | { |
152 | 0 | SECStatus rv; |
153 | 0 |
|
154 | 0 | /* is there a digest algorithm yet? */ |
155 | 0 | if (digd->digestAlg.algorithm.len == 0) |
156 | 0 | return SECFailure; |
157 | 0 | |
158 | 0 | rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo); |
159 | 0 | if (rv != SECSuccess) { |
160 | 0 | return SECFailure; |
161 | 0 | } |
162 | 0 | |
163 | 0 | digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); |
164 | 0 | if (digd->contentInfo.privateInfo->digcx == NULL) |
165 | 0 | return SECFailure; |
166 | 0 | |
167 | 0 | return SECSuccess; |
168 | 0 | } |
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 | 0 | { |
180 | 0 | SECStatus rv = SECSuccess; |
181 | 0 | /* did we have digest calculation going on? */ |
182 | 0 | if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) { |
183 | 0 | rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx, |
184 | 0 | digd->cmsg->poolp, |
185 | 0 | &(digd->cdigest)); |
186 | 0 | /* error has been set by NSS_CMSDigestContext_FinishSingle */ |
187 | 0 | digd->contentInfo.privateInfo->digcx = NULL; |
188 | 0 | } |
189 | 0 |
|
190 | 0 | return rv; |
191 | 0 | } |
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 | 0 | { |
202 | 0 | /* did we have digest calculation going on? */ |
203 | 0 | if (digd->cdigest.len != 0) { |
204 | 0 | /* XXX comparision btw digest & cdigest */ |
205 | 0 | /* XXX set status */ |
206 | 0 | /* TODO!!!! */ |
207 | 0 | } |
208 | 0 |
|
209 | 0 | return SECSuccess; |
210 | 0 | } |