/src/nss/lib/smime/cmsdigdata.c
Line | Count | Source |
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 | |
|
31 | 0 | poolp = cmsg->poolp; |
32 | |
|
33 | 0 | mark = PORT_ArenaMark(poolp); |
34 | |
|
35 | 0 | digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData)); |
36 | 0 | if (digd == NULL) |
37 | 0 | goto loser; |
38 | | |
39 | 0 | digd->cmsg = cmsg; |
40 | |
|
41 | 0 | if (SECOID_CopyAlgorithmID(poolp, &(digd->digestAlg), digestalg) != SECSuccess) |
42 | 0 | goto loser; |
43 | | |
44 | 0 | PORT_ArenaUnmark(poolp, mark); |
45 | 0 | return digd; |
46 | | |
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 | 1.30k | { |
58 | | /* everything's in a pool, so don't worry about the storage */ |
59 | 1.30k | if (digd != NULL) { |
60 | 1.29k | NSS_CMSContentInfo_Destroy(&(digd->contentInfo)); |
61 | 1.29k | } |
62 | 1.30k | return; |
63 | 1.30k | } |
64 | | |
65 | | /* |
66 | | * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo |
67 | | */ |
68 | | NSSCMSContentInfo * |
69 | | NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd) |
70 | 0 | { |
71 | 0 | return &(digd->contentInfo); |
72 | 0 | } |
73 | | |
74 | | /* |
75 | | * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData |
76 | | * before encoding begins. |
77 | | * |
78 | | * In particular: |
79 | | * - set the right version number. The contentInfo's content type must be set up already. |
80 | | */ |
81 | | SECStatus |
82 | | NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd) |
83 | 0 | { |
84 | 0 | unsigned long version; |
85 | 0 | SECItem *dummy; |
86 | |
|
87 | 0 | version = NSS_CMS_DIGESTED_DATA_VERSION_DATA; |
88 | 0 | if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag( |
89 | 0 | &(digd->contentInfo)))) |
90 | 0 | version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP; |
91 | |
|
92 | 0 | dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version); |
93 | 0 | return (dummy == NULL) ? SECFailure : SECSuccess; |
94 | 0 | } |
95 | | |
96 | | /* |
97 | | * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData |
98 | | * before the encapsulated data is passed through the encoder. |
99 | | * |
100 | | * In detail: |
101 | | * - set up the digests if necessary |
102 | | */ |
103 | | SECStatus |
104 | | NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd) |
105 | 0 | { |
106 | 0 | SECStatus rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo); |
107 | 0 | if (rv != SECSuccess) { |
108 | 0 | return SECFailure; |
109 | 0 | } |
110 | | |
111 | | /* set up the digests */ |
112 | 0 | if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) { |
113 | | /* if digest is already there, do nothing */ |
114 | 0 | digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); |
115 | 0 | if (digd->contentInfo.privateInfo->digcx == NULL) |
116 | 0 | return SECFailure; |
117 | 0 | } |
118 | 0 | return SECSuccess; |
119 | 0 | } |
120 | | |
121 | | /* |
122 | | * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData |
123 | | * after all the encapsulated data was passed through the encoder. |
124 | | * |
125 | | * In detail: |
126 | | * - finish the digests |
127 | | */ |
128 | | SECStatus |
129 | | NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd) |
130 | 0 | { |
131 | 0 | SECStatus rv = SECSuccess; |
132 | | /* did we have digest calculation going on? */ |
133 | 0 | if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) { |
134 | 0 | rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx, |
135 | 0 | digd->cmsg->poolp, |
136 | 0 | &(digd->digest)); |
137 | | /* error has been set by NSS_CMSDigestContext_FinishSingle */ |
138 | 0 | digd->contentInfo.privateInfo->digcx = NULL; |
139 | 0 | } |
140 | |
|
141 | 0 | return rv; |
142 | 0 | } |
143 | | |
144 | | /* |
145 | | * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData |
146 | | * before the encapsulated data is passed through the encoder. |
147 | | * |
148 | | * In detail: |
149 | | * - set up the digests if necessary |
150 | | */ |
151 | | SECStatus |
152 | | NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd) |
153 | 1.23k | { |
154 | 1.23k | SECStatus rv; |
155 | | |
156 | | /* is there a digest algorithm yet? */ |
157 | 1.23k | if (digd->digestAlg.algorithm.len == 0) |
158 | 0 | return SECFailure; |
159 | | |
160 | 1.23k | rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo); |
161 | 1.23k | if (rv != SECSuccess) { |
162 | 0 | return SECFailure; |
163 | 0 | } |
164 | | |
165 | 1.23k | digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); |
166 | 1.23k | if (digd->contentInfo.privateInfo->digcx == NULL) |
167 | 1 | return SECFailure; |
168 | | |
169 | 1.23k | return SECSuccess; |
170 | 1.23k | } |
171 | | |
172 | | /* |
173 | | * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData |
174 | | * after all the encapsulated data was passed through the encoder. |
175 | | * |
176 | | * In detail: |
177 | | * - finish the digests |
178 | | */ |
179 | | SECStatus |
180 | | NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd) |
181 | 186 | { |
182 | 186 | SECStatus rv = SECSuccess; |
183 | | /* did we have digest calculation going on? */ |
184 | 186 | if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) { |
185 | 185 | rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx, |
186 | 185 | digd->cmsg->poolp, |
187 | 185 | &(digd->cdigest)); |
188 | | /* error has been set by NSS_CMSDigestContext_FinishSingle */ |
189 | 185 | digd->contentInfo.privateInfo->digcx = NULL; |
190 | 185 | } |
191 | | |
192 | 186 | return rv; |
193 | 186 | } |
194 | | |
195 | | /* |
196 | | * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData. |
197 | | * |
198 | | * In detail: |
199 | | * - check the digests for equality |
200 | | */ |
201 | | SECStatus |
202 | | NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd) |
203 | 169 | { |
204 | | /* did we have digest calculation going on? */ |
205 | 169 | if (digd->cdigest.len != 0) { |
206 | | /* XXX comparision btw digest & cdigest */ |
207 | | /* XXX set status */ |
208 | | /* TODO!!!! */ |
209 | 136 | } |
210 | | |
211 | 169 | return SECSuccess; |
212 | 169 | } |