]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/p12Parse/pkcs12Utils.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / p12Parse / pkcs12Utils.cpp
1 /*
2 * Copyright (c) 2003,2005 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please
7 * obtain a copy of the License at http://www.apple.com/publicsource and
8 * read it before using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
12 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
13 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
15 * Please see the License for the specific language governing rights and
16 * limitations under the License.
17 */
18
19 /*
20 * pkcs12Utils.cpp - standalone copies of utility functions from libsecurity_pkcs12
21 */
22
23 #include "pkcs12Utils.h"
24 #include <string.h>
25 #include <Security/oidsalg.h>
26 #include <security_asn1/nssUtils.h>
27
28 /* CSSM_DATA --> uint32. Returns true if OK. */
29 bool p12DataToInt(
30 const CSSM_DATA &cdata,
31 uint32 &u)
32 {
33 if((cdata.Length == 0) || (cdata.Data == NULL)) {
34 /* default/not present */
35 u = 0;
36 return true;
37 }
38 uint32 len = cdata.Length;
39 if(len > sizeof(uint32)) {
40 return false;
41 }
42
43 uint32 rtn = 0;
44 uint8 *cp = cdata.Data;
45 for(uint32 i=0; i<len; i++) {
46 rtn = (rtn << 8) | *cp++;
47 }
48 u = rtn;
49 return true;
50 }
51
52 /*
53 * OIDS for P12 and PKCS5 v1.5 (PBES1) encrypt and decrypt map to the following
54 * attributes.
55 */
56 typedef struct {
57 const CSSM_OID *oid;
58 CSSM_ALGORITHMS keyAlg; // e.g., CSSM_ALGID_DES
59 CSSM_ALGORITHMS encrAlg; // e.g., CSSM_ALGID_3DES_3KEY_EDE
60 CSSM_ALGORITHMS pbeHashAlg; // SHA1 or MD5
61 uint32 keySizeInBits;
62 uint32 blockSizeInBytes; // for IV, optional
63 CSSM_PADDING padding; // CSSM_PADDING_PKCS7, etc.
64 CSSM_ENCRYPT_MODE mode; // CSSM_ALGMODE_CBCPadIV8, etc.
65 PKCS_Which pkcs; // PW_PKCS12 (for this module) or PW_PKCS5_v1_5
66 } PKCSOidInfo;
67
68 static const PKCSOidInfo pkcsOidInfos[] = {
69 /* PKCS12 first, the ones this module uses */
70 {
71 &CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4,
72 CSSM_ALGID_RC4,
73 CSSM_ALGID_RC4,
74 CSSM_ALGID_SHA1,
75 128,
76 0, // RC4 is a stream cipher
77 CSSM_PADDING_NONE,
78 CSSM_ALGMODE_NONE,
79 PW_PKCS12
80 },
81 {
82 &CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4,
83 CSSM_ALGID_RC4,
84 CSSM_ALGID_RC4,
85 CSSM_ALGID_SHA1,
86 40,
87 0, // RC4 is a stream cipher
88 CSSM_PADDING_NONE,
89 CSSM_ALGMODE_NONE,
90 PW_PKCS12
91 },
92 {
93 &CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC,
94 CSSM_ALGID_3DES_3KEY,
95 CSSM_ALGID_3DES_3KEY_EDE,
96 CSSM_ALGID_SHA1,
97 64 * 3,
98 8,
99 CSSM_PADDING_PKCS7,
100 CSSM_ALGMODE_CBCPadIV8,
101 PW_PKCS12
102 },
103 {
104 &CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC,
105 CSSM_ALGID_3DES_2KEY,
106 CSSM_ALGID_3DES_2KEY_EDE,
107 CSSM_ALGID_SHA1,
108 64 * 2,
109 8,
110 CSSM_PADDING_PKCS7,
111 CSSM_ALGMODE_CBCPadIV8,
112 PW_PKCS12
113 },
114 {
115 &CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC,
116 CSSM_ALGID_RC2,
117 CSSM_ALGID_RC2,
118 CSSM_ALGID_SHA1,
119 128,
120 8,
121 CSSM_PADDING_PKCS7,
122 CSSM_ALGMODE_CBCPadIV8,
123 PW_PKCS12
124 },
125 {
126 &CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC,
127 CSSM_ALGID_RC2,
128 CSSM_ALGID_RC2,
129 CSSM_ALGID_SHA1,
130 40,
131 8,
132 CSSM_PADDING_PKCS7,
133 CSSM_ALGMODE_CBCPadIV8,
134 PW_PKCS12
135 },
136
137 /* PKCS5 v1.5, used for SecImportExport module */
138 {
139 &CSSMOID_PKCS5_pbeWithMD2AndDES,
140 CSSM_ALGID_DES,
141 CSSM_ALGID_DES,
142 CSSM_ALGID_MD2,
143 64,
144 8,
145 CSSM_PADDING_PKCS7,
146 CSSM_ALGMODE_CBCPadIV8,
147 PW_PKCS5_v1_5
148 },
149 {
150 &CSSMOID_PKCS5_pbeWithMD2AndRC2,
151 CSSM_ALGID_RC2,
152 CSSM_ALGID_RC2,
153 CSSM_ALGID_MD2,
154 64,
155 8,
156 CSSM_PADDING_PKCS7,
157 CSSM_ALGMODE_CBCPadIV8,
158 PW_PKCS5_v1_5
159 },
160 {
161 &CSSMOID_PKCS5_pbeWithMD5AndDES,
162 CSSM_ALGID_DES,
163 CSSM_ALGID_DES,
164 CSSM_ALGID_MD5,
165 64,
166 8,
167 CSSM_PADDING_PKCS7,
168 CSSM_ALGMODE_CBCPadIV8,
169 PW_PKCS5_v1_5
170 },
171 {
172 &CSSMOID_PKCS5_pbeWithMD5AndRC2,
173 CSSM_ALGID_RC2,
174 CSSM_ALGID_RC2,
175 CSSM_ALGID_MD5,
176 64,
177 8,
178 CSSM_PADDING_PKCS7,
179 CSSM_ALGMODE_CBCPadIV8,
180 PW_PKCS5_v1_5
181 },
182 {
183 &CSSMOID_PKCS5_pbeWithSHA1AndDES,
184 CSSM_ALGID_DES,
185 CSSM_ALGID_DES,
186 CSSM_ALGID_SHA1,
187 64,
188 8,
189 CSSM_PADDING_PKCS7,
190 CSSM_ALGMODE_CBCPadIV8,
191 PW_PKCS5_v1_5
192 },
193 {
194 &CSSMOID_PKCS5_pbeWithSHA1AndRC2,
195 CSSM_ALGID_RC2,
196 CSSM_ALGID_RC2,
197 CSSM_ALGID_SHA1,
198 64,
199 8,
200 CSSM_PADDING_PKCS7,
201 CSSM_ALGMODE_CBCPadIV8,
202 PW_PKCS5_v1_5
203 },
204
205 /* finally one for PKCS5 v2.0, which has its own means of
206 * cooking up all the parameters */
207 {
208 &CSSMOID_PKCS5_PBES2,
209 CSSM_ALGID_NONE,
210 CSSM_ALGID_NONE,
211 CSSM_ALGID_NONE,
212 0, 0, 0, 0,
213 PW_PKCS5_v2
214 }
215 };
216
217 #define NUM_PKCS_OID_INFOS (sizeof(pkcsOidInfos) / sizeof(pkcsOidInfos[1]))
218
219 /* map an OID to the components */
220 /* returns false if OID not found */
221
222 /*
223 * NOTE: as of March 8 2004 this is also used by the SecImportExport
224 * module...not just PKCS12!
225 */
226 bool pkcsOidToParams(
227 const CSSM_OID *oid,
228 CSSM_ALGORITHMS &keyAlg, // e.g., CSSM_ALGID_DES
229 CSSM_ALGORITHMS &encrAlg, // e.g., CSSM_ALGID_3DES_3KEY_EDE
230 CSSM_ALGORITHMS &pbeHashAlg, // SHA1 or MD5
231 uint32 &keySizeInBits,
232 uint32 &blockSizeInBytes, // for IV, optional
233 CSSM_PADDING &padding, // CSSM_PADDING_PKCS7, etc.
234 CSSM_ENCRYPT_MODE &mode, // CSSM_ALGMODE_CBCPadIV8, etc.
235 PKCS_Which &pkcs) // PW_PKCS5_v1_5 or PW_PKCS12
236 {
237 const PKCSOidInfo *info = pkcsOidInfos;
238 pkcs = PW_None;
239
240 for(unsigned dex=0; dex<NUM_PKCS_OID_INFOS; dex++) {
241 if(nssCompareCssmData(oid, info->oid)) {
242 keyAlg = info->keyAlg;
243 encrAlg = info->encrAlg;
244 pbeHashAlg = info->pbeHashAlg;
245 keySizeInBits = info->keySizeInBits;
246 blockSizeInBytes = info->blockSizeInBytes;
247 padding = info->padding;
248 mode = info->mode;
249 pkcs = info->pkcs;
250 return true;
251 }
252 info++;
253 }
254 return false;
255 }
256
257 /*
258 * Enum to string mappper.
259 * Maybe DEBUG only.
260 */
261 /*
262 * Each type of attribute has a name/value pair in a table of these:
263 */
264 typedef struct {
265 unsigned value;
266 const char *name;
267 } p12NameValuePair;
268
269 /* declare one entry in a table of p12NameValuePair */
270 #define NVP(attr) {attr, #attr}
271
272 /* the NULL entry which terminates all p12NameValuePair tables */
273 #define NVP_END {0, NULL}
274
275 static const p12NameValuePair p7CITypeNames[] =
276 {
277 NVP(CT_None),
278 NVP(CT_Data),
279 NVP(CT_SignedData),
280 NVP(CT_EnvData),
281 NVP(CT_SignedEnvData),
282 NVP(CT_DigestData),
283 NVP(CT_EncryptedData),
284 NVP_END
285 };
286
287 static const p12NameValuePair p12BagTypeNames[] =
288 {
289 NVP(BT_None),
290 NVP(BT_KeyBag),
291 NVP(BT_ShroudedKeyBag),
292 NVP(BT_CertBag),
293 NVP(BT_CrlBag),
294 NVP(BT_SecretBag),
295 NVP(BT_SafeContentsBag),
296 NVP_END
297 };
298
299 static const char *typeToStr(
300 unsigned type,
301 const p12NameValuePair *table)
302 {
303 while(table->name) {
304 if(table->value == type) {
305 return table->name;
306 }
307 table++;
308 }
309 return "Unknown";
310 }
311
312 const char *p12BagTypeStr(
313 NSS_P12_SB_Type type)
314 {
315 return typeToStr(type, p12BagTypeNames);
316 }
317
318 const char *p7ContentInfoTypeStr(
319 NSS_P7_CI_Type type)
320 {
321 return typeToStr(type, p7CITypeNames);
322 }