Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2012 Milan Jurik. All rights reserved.
25 + * Copyright (c) 2018, Joyent. Inc.
25 26 */
26 27
27 28 #include <stdlib.h>
28 29 #include <string.h>
29 30 #include <strings.h>
30 31 #include <lber.h>
31 32 #include <security/cryptoki.h>
32 33 #include "softDSA.h"
33 34 #include "softDH.h"
34 35 #include "softRSA.h"
35 36 #include "softObject.h"
36 37 #include "softASN1.h"
37 38
38 39 #define OID_TAG 0x06
39 40
40 41 #define MAX_DH_KEY MAX_DH_KEYLENGTH_IN_BYTES /* bytes in DH key */
41 42 static uchar_t DH_OID[] = {
42 43 /* DH key agreement OID: 1 . 2 . 840 . 113549 . 1 . 3 . 1 */
43 44 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01
44 45 };
45 46
46 47 #define MAX_DH942_KEY MAX_DH_KEYLENGTH_IN_BYTES /* bytes in DH X9.42 key */
47 48 static uchar_t DH942_OID[] = {
48 49 /* DH X9.42 OID: 1 . 2 . 840 . 10046 . 1 */
49 50 0x2A, 0x86, 0x48, 0xCE, 0x3E, 0x01
50 51 };
51 52
52 53 #define MAX_DSA_KEY MAX_DSA_KEY_LEN /* bytes in DSA key */
53 54 static uchar_t DSA_OID[] = {
54 55 /* DSA algorithm OID: 1 . 2 . 840 . 10040 . 4 . 1 */
55 56 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01
56 57 };
57 58
58 59 #define MAX_RSA_KEY MAX_RSA_KEYLENGTH_IN_BYTES /* bytes in RSA key */
59 60 static uchar_t RSA_OID[] = {
60 61 /* RSA algorithm OID: 1 . 2 . 840 . 113549 . 1 . 1 . 1 */
61 62 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
62 63 };
63 64
64 65
65 66 /*
66 67 * If the first bit of big integer is non-zero (i.e, first byte is
67 68 * 0x80 or greater), it may be interpreted as an ASN.1 negative number.
68 69 * Add one leading byte of zero-padding only in these cases to ensure
69 70 * it is treated as an unsigned integer.
70 71 */
71 72 static CK_RV
72 73 pad_bigint_attr(biginteger_t *src, biginteger_t *dst)
73 74 {
74 75 int padding;
75 76
76 77 /* Src and dst must already by previously allocated. */
77 78 if (src == NULL || dst == NULL)
78 79 return (CKR_HOST_MEMORY);
79 80
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
80 81 if (src->big_value_len == 0) {
81 82 dst->big_value = NULL;
82 83 dst->big_value_len = 0;
83 84 return (CKR_OK);
84 85 }
85 86 /*
86 87 * Realloc() may free() or shrink previous memory location, so
87 88 * clear out potentially sensitive data before that happens.
88 89 */
89 90 if (dst->big_value != NULL)
90 - (void) memset(dst->big_value, 0x0, dst->big_value_len);
91 + explicit_bzero(dst->big_value, dst->big_value_len);
91 92
92 93 padding = (src->big_value[0] < 0x80) ? 0 : 1;
93 94 dst->big_value_len = src->big_value_len + padding;
94 95
95 96 dst->big_value = realloc(dst->big_value, dst->big_value_len);
96 97 if (dst->big_value == NULL)
97 98 return (CKR_HOST_MEMORY);
98 99
99 100 /* Set zero-pad at first byte, then append actual big_value. */
100 101 dst->big_value[0] = 0x0;
101 102 (void) memcpy(&(dst->big_value[padding]), src->big_value,
102 103 src->big_value_len);
103 104 return (CKR_OK);
104 105 }
105 106
106 107 /*
107 108 * Sometimes there is one bytes of zero-padding, if a big integer may
108 109 * be interpreted as an ASN.1 negative number (i.e, the first bit is
109 110 * non-zero, the first byte is 0x80 or greater). Remove first byte
110 111 * of zero-padding in those cases from the decoded octet strings.
111 112 */
112 113 static CK_RV
113 114 unpad_bigint_attr(biginteger_t src, biginteger_t *dst)
114 115 {
115 116 int offset;
116 117
117 118 if (dst == NULL)
118 119 return (CKR_HOST_MEMORY);
119 120
120 121 if (src.big_value_len == 0) {
121 122 dst->big_value = NULL;
122 123 dst->big_value_len = 0;
123 124 return (CKR_OK);
124 125 }
125 126
126 127 offset = (src.big_value[0] == 0x00) ? 1 : 0;
127 128 dst->big_value_len = src.big_value_len - offset;
128 129
129 130 /*
130 131 * Must allocate memory here because subsequent calls to
131 132 * copy_bigint_attr() just redirect pointer; it doesn't
132 133 * really copy the bigint like the function name implies.
133 134 */
134 135 dst->big_value = malloc(dst->big_value_len);
135 136 if (dst->big_value == NULL)
136 137 return (CKR_HOST_MEMORY);
137 138
138 139 (void) memcpy(dst->big_value, &(src.big_value[offset]),
139 140 dst->big_value_len);
140 141 return (CKR_OK);
141 142 }
142 143
143 144
144 145 /* Encode RSA private key in ASN.1 BER syntax. */
145 146 static CK_RV
146 147 rsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
147 148 {
148 149 CK_RV rv = CKR_OK;
149 150 BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
150 151 BerValue *key_octs = NULL, *p8obj_octs = NULL;
151 152 int version = SOFT_ASN_VERSION;
152 153 biginteger_t tmp_pad = { NULL, 0 };
153 154
154 155 /*
155 156 * The ASN.1 syntax for an RSA private key is:
156 157 *
157 158 * PKCS#8 \* PrivateKeyInfo *\
158 159 * ---------------------------------
159 160 * Sequence {
160 161 * version INTEGER;
161 162 * Sequence { \* PrivateKeyAlgorithm *\
162 163 * OID 0x06, \* RSA algorithm OID *\
163 164 * param(NULL)
164 165 * }
165 166 * RSAPrivateKey OCTETSTRING =
166 167 * PKCS#1 \* RSAPrivateKey *\
167 168 * ---------------------------
168 169 * Sequence {
169 170 * version INTEGER,
170 171 * modulus INTEGER,
171 172 * publicExponent INTEGER,
172 173 * privateExponent INTEGER,
173 174 * prime1 INTEGER,
174 175 * prime2 INTEGER,
175 176 * exponent1 INTEGER,
176 177 * exponent2 INTEGER,
177 178 * coefficient INTEGER
178 179 * }
179 180 * }
180 181 *
181 182 * The code below starts building the innermost octets
182 183 * RSAPrivateKey, and then builds the PrivateKeyInfo
183 184 * sequence around that octet string. The BER syntax
184 185 * used in this function is (others may be possible):
185 186 * { i { to n } { i to to to to to to to to } }
186 187 * where "i" is for integers with fixed size
187 188 * where "to" is for integers that vary in size (length + value)
188 189 * where "n" is for nulls
189 190 * where "{}" delimit sequences
190 191 */
191 192
192 193 /* RSAPrivateKey ... */
193 194 if ((key_asn = ber_alloc()) == NULLBER)
194 195 return (CKR_HOST_MEMORY);
195 196
196 197 /* ... begin-sequence { version, */
197 198 if (ber_printf(key_asn, "{i", version) == -1) {
198 199 rv = CKR_GENERAL_ERROR;
199 200 goto cleanup_rsapri2asn;
200 201 }
201 202
202 203 /* ... modulus, */
203 204 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_MOD(objp), &tmp_pad)) != CKR_OK)
204 205 goto cleanup_rsapri2asn;
205 206 if (ber_printf(key_asn, "to", LBER_INTEGER,
206 207 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
207 208 rv = CKR_GENERAL_ERROR;
208 209 goto cleanup_rsapri2asn;
209 210 }
210 211
211 212 /* ... public exponent, */
212 213 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PUBEXPO(objp), &tmp_pad)) !=
213 214 CKR_OK)
214 215 goto cleanup_rsapri2asn;
215 216
216 217 else if (ber_printf(key_asn, "to", LBER_INTEGER, tmp_pad.big_value,
217 218 tmp_pad.big_value_len) == -1) {
218 219 rv = CKR_GENERAL_ERROR;
219 220 goto cleanup_rsapri2asn;
220 221 }
221 222
222 223 /* ... private exponent, */
223 224 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIEXPO(objp), &tmp_pad)) !=
224 225 CKR_OK)
225 226 goto cleanup_rsapri2asn;
226 227 if (ber_printf(key_asn, "to", LBER_INTEGER,
227 228 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
228 229 rv = CKR_GENERAL_ERROR;
229 230 goto cleanup_rsapri2asn;
230 231 }
231 232
232 233 /* ... prime 1, */
233 234 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME1(objp), &tmp_pad)) !=
234 235 CKR_OK)
235 236 goto cleanup_rsapri2asn;
236 237 else if (ber_printf(key_asn, "to", LBER_INTEGER,
237 238 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
238 239 rv = CKR_GENERAL_ERROR;
239 240 goto cleanup_rsapri2asn;
240 241 }
241 242
242 243 /* ... prime 2, */
243 244 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME2(objp), &tmp_pad)) !=
244 245 CKR_OK)
245 246 goto cleanup_rsapri2asn;
246 247 else if (ber_printf(key_asn, "to", LBER_INTEGER,
247 248 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
248 249 rv = CKR_GENERAL_ERROR;
249 250 goto cleanup_rsapri2asn;
250 251 }
251 252
252 253 /* ... exponent 1, */
253 254 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO1(objp), &tmp_pad)) != CKR_OK)
254 255 goto cleanup_rsapri2asn;
255 256 else if (ber_printf(key_asn, "to", LBER_INTEGER,
256 257 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
257 258 rv = CKR_GENERAL_ERROR;
258 259 goto cleanup_rsapri2asn;
259 260 }
260 261
261 262 /* ... exponent 2, */
262 263 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO2(objp), &tmp_pad)) != CKR_OK)
263 264 goto cleanup_rsapri2asn;
264 265 else if (ber_printf(key_asn, "to", LBER_INTEGER,
265 266 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
266 267 rv = CKR_GENERAL_ERROR;
267 268 goto cleanup_rsapri2asn;
268 269 }
269 270
270 271 /* ... coefficient } end-sequence */
271 272 if ((rv = pad_bigint_attr(OBJ_PRI_RSA_COEF(objp), &tmp_pad)) != CKR_OK)
272 273 goto cleanup_rsapri2asn;
273 274 else if (ber_printf(key_asn, "to}", LBER_INTEGER,
274 275 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
275 276 rv = CKR_GENERAL_ERROR;
276 277 goto cleanup_rsapri2asn;
277 278 }
278 279
279 280 /* Convert key ASN.1 to octet string. */
280 281 if (ber_flatten(key_asn, &key_octs) == -1) {
281 282 rv = CKR_GENERAL_ERROR;
282 283 goto cleanup_rsapri2asn;
283 284 }
284 285
285 286 /* PKCS#8 PrivateKeyInfo ... */
286 287 if ((p8obj_asn = ber_alloc()) == NULLBER) {
287 288 rv = CKR_HOST_MEMORY;
288 289 goto cleanup_rsapri2asn;
289 290 }
290 291
291 292 /*
292 293 * Embed key octet string into PKCS#8 object ASN.1:
293 294 * begin-sequence {
294 295 * version
295 296 * begin-sequence {
296 297 * OID,
297 298 * NULL
298 299 * } end-sequence
299 300 * RSAPrivateKey
300 301 * } end-sequence
301 302 */
302 303 if (ber_printf(p8obj_asn, "{i{ton}o}", version,
303 304 OID_TAG, RSA_OID, sizeof (RSA_OID), /* NULL parameter, */
304 305 key_octs->bv_val, key_octs->bv_len) == -1) {
305 306 rv = CKR_GENERAL_ERROR;
306 307 goto cleanup_rsapri2asn;
307 308 }
308 309
309 310 /* Convert PKCS#8 object ASN.1 to octet string. */
310 311 if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
311 312 rv = CKR_GENERAL_ERROR;
312 313 goto cleanup_rsapri2asn;
313 314 }
314 315
315 316 /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
316 317 /*
317 318 * If the user passes in a null buf, then buf_len is set.
318 319 * If the user passes in a value with buf_len, then it can
319 320 * be checked to see if the accompanying buf is big enough.
320 321 * If it is, the octet string is copied into a pre-malloc'd
321 322 * buf; otherwise the user must resize buf and call again.
322 323 * In either case, buf_len is reset to the corrected size.
323 324 * See PKCS#11 section 11.2.
324 325 */
325 326 #ifdef _LP64
326 327 /* LINTED E_CAST_INT_TO_SMALL_INT */
327 328 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
328 329 #else
329 330 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
330 331 #endif
↓ open down ↓ |
230 lines elided |
↑ open up ↑ |
331 332 *buf_len = p8obj_octs->bv_len;
332 333 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
333 334 goto cleanup_rsapri2asn;
334 335 }
335 336
336 337 *buf_len = p8obj_octs->bv_len;
337 338 (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
338 339
339 340 cleanup_rsapri2asn:
340 341
341 - if (tmp_pad.big_value != NULL) {
342 - (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
343 - free(tmp_pad.big_value);
344 - }
342 + freezero(tmp_pad.big_value, tmp_pad.big_value_len);
345 343
346 344 if (key_asn != NULLBER)
347 345 ber_free(key_asn, 1);
348 346
349 347 if (key_octs != NULL)
350 348 ber_bvfree(key_octs);
351 349
352 350 if (p8obj_asn != NULLBER)
353 351 ber_free(p8obj_asn, 1);
354 352
355 353 if (p8obj_octs != NULL)
356 354 ber_bvfree(p8obj_octs);
357 355
358 356 return (rv);
359 357 }
360 358
361 359 /* Encode DSA private key in ASN.1 BER syntax. */
362 360 static CK_RV
363 361 dsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
364 362 {
365 363 CK_RV rv = CKR_OK;
366 364 BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
367 365 BerValue *key_octs = NULL, *p8obj_octs = NULL;
368 366 int version = SOFT_ASN_VERSION;
369 367 biginteger_t tmp_pad = { NULL, 0 };
370 368
371 369 /*
372 370 * The ASN.1 syntax for a DSA private key is:
373 371 *
374 372 * PKCS#8 \* PrivateKeyInfo *\
375 373 * ---------------------------------
376 374 * Sequence {
377 375 * version INTEGER;
378 376 * Sequence { \* PrivateKeyAlgorithm *\
379 377 * OID 0x06, \* DSA algorithm OID *\
380 378 * param(DSS-params) OCTETSTRING =
381 379 * PKCS#? \* DSSParameter *\
382 380 * ----------------------------------
383 381 * Sequence {
384 382 * prime INTEGER,
385 383 * subprime INTEGER,
386 384 * base INTEGER,
387 385 * }
388 386 * }
389 387 * DSAPrivateKey OCTETSTRING =
390 388 * PKCS#1 \* DSAPrivateKey *\
391 389 * ---------------------------
392 390 * value INTEGER
393 391 * }
394 392 *
395 393 * The code below starts building the innermost octets
396 394 * DSAPrivateKey, and then builds the PrivateKeyInfo
397 395 * sequence around that octet string. The BER syntax
398 396 * used in this function is (others may be possible):
399 397 * { i { to { to to to } } to }
400 398 * where "i" is for integers with fixed size
401 399 * where "to" is for integers that vary in size (length + value)
402 400 * where "{}" delimit sequences
403 401 */
404 402
405 403 /* DSAPrivateKey ... */
406 404 if ((key_asn = ber_alloc()) == NULLBER)
407 405 return (CKR_HOST_MEMORY);
408 406
409 407 /* ... value */
410 408 if ((rv = pad_bigint_attr(OBJ_PRI_DSA_VALUE(objp), &tmp_pad)) != CKR_OK)
411 409 goto cleanup_dsapri2asn;
412 410 if (ber_printf(key_asn, "to", LBER_INTEGER,
413 411 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
414 412 rv = CKR_GENERAL_ERROR;
415 413 goto cleanup_dsapri2asn;
416 414 }
417 415
418 416 /* Convert key ASN.1 to octet string. */
419 417 if (ber_flatten(key_asn, &key_octs) == -1) {
420 418 rv = CKR_GENERAL_ERROR;
421 419 goto cleanup_dsapri2asn;
422 420 }
423 421
424 422 /* PKCS#8 PrivateKeyInfo ... */
425 423 if ((p8obj_asn = ber_alloc()) == NULLBER) {
426 424 rv = CKR_HOST_MEMORY;
427 425 goto cleanup_dsapri2asn;
428 426 }
429 427
430 428 /*
431 429 * Start off the PKCS#8 object ASN.1:
432 430 * begin-sequence {
433 431 * version
434 432 * begin-sequence {
435 433 * OID,
436 434 * ...
437 435 */
438 436 if (ber_printf(p8obj_asn, "{i{to", version,
439 437 OID_TAG, DSA_OID, sizeof (DSA_OID)) == -1) {
440 438 rv = CKR_GENERAL_ERROR;
441 439 goto cleanup_dsapri2asn;
442 440 }
443 441
444 442 /*
445 443 * Add DSS parameters:
446 444 * ...
447 445 * begin-sequence {
448 446 * prime,
449 447 * ...
450 448 */
451 449 if ((rv = pad_bigint_attr(OBJ_PRI_DSA_PRIME(objp), &tmp_pad)) != CKR_OK)
452 450 goto cleanup_dsapri2asn;
453 451 if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
454 452 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
455 453 rv = CKR_GENERAL_ERROR;
456 454 goto cleanup_dsapri2asn;
457 455 }
458 456
459 457 /*
460 458 * ...
461 459 * subprime,
462 460 * ...
463 461 */
464 462 if ((rv = pad_bigint_attr(OBJ_PRI_DSA_SUBPRIME(objp), &tmp_pad)) !=
465 463 CKR_OK)
466 464 goto cleanup_dsapri2asn;
467 465 if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
468 466 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
469 467 rv = CKR_GENERAL_ERROR;
470 468 goto cleanup_dsapri2asn;
471 469 }
472 470
473 471 /*
474 472 * ...
475 473 * base
476 474 * } end-sequence
477 475 */
478 476 if ((rv = pad_bigint_attr(OBJ_PRI_DSA_BASE(objp), &tmp_pad)) != CKR_OK)
479 477 goto cleanup_dsapri2asn;
480 478 if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
481 479 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
482 480 rv = CKR_GENERAL_ERROR;
483 481 goto cleanup_dsapri2asn;
484 482 }
485 483
486 484 /*
487 485 * Add the key octet string:
488 486 * } end-sequence
489 487 * DSAPrivateKey
490 488 * } end-sequence
491 489 */
492 490 if (ber_printf(p8obj_asn, "}o}",
493 491 key_octs->bv_val, key_octs->bv_len) == -1) {
494 492 rv = CKR_GENERAL_ERROR;
495 493 goto cleanup_dsapri2asn;
496 494 }
497 495
498 496 /* Convert PKCS#8 object ASN.1 to octet string. */
499 497 if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
500 498 rv = CKR_GENERAL_ERROR;
501 499 goto cleanup_dsapri2asn;
502 500 }
503 501
504 502 /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
505 503 /*
506 504 * If the user passes in a null buf, then buf_len is set.
507 505 * If the user passes in a value with buf_len, then it can
508 506 * be checked to see if the accompanying buf is big enough.
509 507 * If it is, the octet string is copied into a pre-malloc'd
510 508 * buf; otherwise the user must resize buf and call again.
511 509 * In either case, buf_len is reset to the corrected size.
512 510 * See PKCS#11 section 11.2.
513 511 */
514 512 #ifdef _LP64
515 513 /* LINTED E_CAST_INT_TO_SMALL_INT */
516 514 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
517 515 #else
518 516 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
519 517 #endif
↓ open down ↓ |
165 lines elided |
↑ open up ↑ |
520 518 *buf_len = p8obj_octs->bv_len;
521 519 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
522 520 goto cleanup_dsapri2asn;
523 521 }
524 522
525 523 *buf_len = p8obj_octs->bv_len;
526 524 (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
527 525
528 526 cleanup_dsapri2asn:
529 527
530 - if (tmp_pad.big_value != NULL) {
531 - (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
532 - free(tmp_pad.big_value);
533 - }
528 + freezero(tmp_pad.big_value, tmp_pad.big_value_len);
534 529
535 530 if (key_asn != NULLBER)
536 531 ber_free(key_asn, 1);
537 532
538 533 if (key_octs != NULL)
539 534 ber_bvfree(key_octs);
540 535
541 536 if (p8obj_asn != NULLBER)
542 537 ber_free(p8obj_asn, 1);
543 538
544 539 if (p8obj_octs != NULL)
545 540 ber_bvfree(p8obj_octs);
546 541
547 542 return (rv);
548 543 }
549 544
550 545 /* Encode DH private key in ASN.1 BER syntax. */
551 546 static CK_RV
552 547 dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
553 548 {
554 549 CK_RV rv = CKR_OK;
555 550 BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
556 551 BerValue *key_octs = NULL, *p8obj_octs = NULL;
557 552 int version = SOFT_ASN_VERSION;
558 553 biginteger_t tmp_pad = { NULL, 0 };
559 554
560 555 /*
561 556 * The ASN.1 syntax for a DH private key is:
562 557 *
563 558 * PKCS#8 \* PrivateKeyInfo *\
564 559 * ---------------------------------
565 560 * Sequence {
566 561 * version INTEGER;
567 562 * Sequence { \* PrivateKeyAlgorithm *\
568 563 * OID 0x06, \* DH algorithm OID *\
569 564 * param(DH-params) OCTETSTRING =
570 565 * PKCS#3 \* DHParameter *\
571 566 * -------------------------
572 567 * Sequence {
573 568 * prime INTEGER,
574 569 * base INTEGER
575 570 * }
576 571 * }
577 572 * DHPrivateKey OCTETSTRING =
578 573 * PKCS#1 \* DHPrivateKey *\
579 574 * --------------------------
580 575 * value INTEGER
581 576 * }
582 577 *
583 578 * The code below starts building the innermost octets
584 579 * DHPrivateKey, and then builds the PrivateKeyInfo
585 580 * sequence around that octet string. The BER syntax
586 581 * used in this function is (others may be possible):
587 582 * { i { to { to to } } to }
588 583 * where "i" is for integers with fixed size
589 584 * where "to" is for integers that vary in size (length + value)
590 585 * where "{}" delimit sequences
591 586 */
592 587
593 588 /* DHPrivateKey ... */
594 589 if ((key_asn = ber_alloc()) == NULLBER)
595 590 return (CKR_HOST_MEMORY);
596 591
597 592 /* ... value */
598 593 if ((rv = pad_bigint_attr(OBJ_PRI_DH_VALUE(objp), &tmp_pad)) != CKR_OK)
599 594 goto cleanup_dhpri2asn;
600 595 if (ber_printf(key_asn, "to", LBER_INTEGER,
601 596 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
602 597 rv = CKR_GENERAL_ERROR;
603 598 goto cleanup_dhpri2asn;
604 599 }
605 600
606 601 /* Convert key ASN.1 to octet string. */
607 602 if (ber_flatten(key_asn, &key_octs) == -1) {
608 603 rv = CKR_GENERAL_ERROR;
609 604 goto cleanup_dhpri2asn;
610 605 }
611 606
612 607 /* PKCS#8 PrivateKeyInfo ... */
613 608 if ((p8obj_asn = ber_alloc()) == NULLBER) {
614 609 rv = CKR_HOST_MEMORY;
615 610 goto cleanup_dhpri2asn;
616 611 }
617 612
618 613 /*
619 614 * Start off the PKCS#8 object ASN.1:
620 615 * begin-sequence {
621 616 * version
622 617 * begin-sequence {
623 618 * OID,
624 619 * ...
625 620 */
626 621 if (ber_printf(p8obj_asn, "{i{to", version,
627 622 OID_TAG, DH_OID, sizeof (DH_OID)) == -1) {
628 623 rv = CKR_GENERAL_ERROR;
629 624 goto cleanup_dhpri2asn;
630 625 }
631 626
632 627 /*
633 628 * Add DH parameters:
634 629 * ...
635 630 * begin-sequence {
636 631 * prime,
637 632 * ...
638 633 */
639 634 if ((rv = pad_bigint_attr(OBJ_PRI_DH_PRIME(objp), &tmp_pad)) != CKR_OK)
640 635 goto cleanup_dhpri2asn;
641 636 if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
642 637 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
643 638 rv = CKR_GENERAL_ERROR;
644 639 goto cleanup_dhpri2asn;
645 640 }
646 641
647 642 /*
648 643 * ...
649 644 * base
650 645 * } end-sequence
651 646 */
652 647 if ((rv = pad_bigint_attr(OBJ_PRI_DH_BASE(objp), &tmp_pad)) != CKR_OK)
653 648 goto cleanup_dhpri2asn;
654 649 if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
655 650 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
656 651 rv = CKR_GENERAL_ERROR;
657 652 goto cleanup_dhpri2asn;
658 653 }
659 654
660 655 /*
661 656 * Add the key octet string:
662 657 * } end-sequence
663 658 * DSAPrivateKey
664 659 * } end-sequence
665 660 */
666 661 if (ber_printf(p8obj_asn, "}o}",
667 662 key_octs->bv_val, key_octs->bv_len) == -1) {
668 663 rv = CKR_GENERAL_ERROR;
669 664 goto cleanup_dhpri2asn;
670 665 }
671 666
672 667 /* Convert PKCS#8 object ASN.1 to octet string. */
673 668 if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
674 669 rv = CKR_GENERAL_ERROR;
675 670 goto cleanup_dhpri2asn;
676 671 }
677 672
678 673 /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
679 674 /*
680 675 * If the user passes in a null buf, then buf_len is set.
681 676 * If the user passes in a value with buf_len, then it can
682 677 * be checked to see if the accompanying buf is big enough.
683 678 * If it is, the octet string is copied into a pre-malloc'd
684 679 * buf; otherwise the user must resize buf and call again.
685 680 * In either case, buf_len is reset to the corrected size.
686 681 * See PKCS#11 section 11.2.
687 682 */
688 683 #ifdef _LP64
689 684 /* LINTED E_CAST_INT_TO_SMALL_INT */
690 685 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
691 686 #else
692 687 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
693 688 #endif
↓ open down ↓ |
150 lines elided |
↑ open up ↑ |
694 689 *buf_len = p8obj_octs->bv_len;
695 690 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
696 691 goto cleanup_dhpri2asn;
697 692 }
698 693
699 694 *buf_len = p8obj_octs->bv_len;
700 695 (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
701 696
702 697 cleanup_dhpri2asn:
703 698
704 - if (tmp_pad.big_value != NULL) {
705 - (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
706 - free(tmp_pad.big_value);
707 - }
699 + freezero(tmp_pad.big_value, tmp_pad.big_value_len);
708 700
709 701 if (key_asn != NULLBER)
710 702 ber_free(key_asn, 1);
711 703
712 704 if (key_octs != NULL)
713 705 ber_bvfree(key_octs);
714 706
715 707 if (p8obj_asn != NULLBER)
716 708 ber_free(p8obj_asn, 1);
717 709
718 710 if (p8obj_octs != NULL)
719 711 ber_bvfree(p8obj_octs);
720 712
721 713 return (rv);
722 714 }
723 715
724 716 /* Encode DH X9.42 private key in ASN.1 BER syntax. */
725 717 static CK_RV
726 718 x942_dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
727 719 {
728 720 CK_RV rv = CKR_OK;
729 721 BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
730 722 BerValue *key_octs = NULL, *p8obj_octs = NULL;
731 723 int version = SOFT_ASN_VERSION;
732 724 biginteger_t tmp_pad = { NULL, 0 };
733 725
734 726 /*
735 727 * The ASN.1 syntax for a X9.42 DH private key is:
736 728 *
737 729 * PKCS#8 \* PrivateKeyInfo *\
738 730 * ---------------------------------
739 731 * Sequence {
740 732 * version INTEGER;
741 733 * Sequence { \* PrivateKeyAlgorithm *\
742 734 * OID 0x06, \* DH X9.42 algorithm OID *\
743 735 * param(DH-params) OCTETSTRING =
744 736 * PKCS#3 \* DHParameter *\
745 737 * -------------------------
746 738 * Sequence {
747 739 * prime INTEGER,
748 740 * base INTEGER,
749 741 * subprime INTEGER \* for X9.42 *\
750 742 * }
751 743 * }
752 744 * DHPrivateKey OCTETSTRING =
753 745 * PKCS#1 \* DHPrivateKey *\
754 746 * --------------------------
755 747 * value INTEGER
756 748 * }
757 749 *
758 750 * The code below starts building the innermost octets
759 751 * DHPrivateKey, and then builds the PrivateKeyInfo
760 752 * sequence around that octet string. The BER syntax
761 753 * used in this function is (others may be possible):
762 754 * { i { to { to to } } to }
763 755 * where "i" is for integers with fixed size
764 756 * where "to" is for integers that vary in size (length + value)
765 757 * where "{}" delimit sequences
766 758 */
767 759
768 760 /* DHPrivateKey ... */
769 761 if ((key_asn = ber_alloc()) == NULLBER)
770 762 return (CKR_HOST_MEMORY);
771 763
772 764 /* ... value */
773 765 if ((rv = pad_bigint_attr(OBJ_PRI_DH942_VALUE(objp), &tmp_pad)) !=
774 766 CKR_OK)
775 767 goto cleanup_x942dhpri2asn;
776 768 if (ber_printf(key_asn, "to", LBER_INTEGER,
777 769 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
778 770 rv = CKR_GENERAL_ERROR;
779 771 goto cleanup_x942dhpri2asn;
780 772 }
781 773
782 774 /* Convert key ASN.1 to octet string. */
783 775 if (ber_flatten(key_asn, &key_octs) == -1) {
784 776 rv = CKR_GENERAL_ERROR;
785 777 goto cleanup_x942dhpri2asn;
786 778 }
787 779
788 780 /* PKCS#8 PrivateKeyInfo ... */
789 781 if ((p8obj_asn = ber_alloc()) == NULLBER) {
790 782 rv = CKR_HOST_MEMORY;
791 783 goto cleanup_x942dhpri2asn;
792 784 }
793 785
794 786 /*
795 787 * Start off the PKCS#8 object ASN.1:
796 788 * begin-sequence {
797 789 * version
798 790 * begin-sequence {
799 791 * OID,
800 792 * ...
801 793 */
802 794 if (ber_printf(p8obj_asn, "{i{to", version,
803 795 OID_TAG, DH942_OID, sizeof (DH942_OID)) == -1) {
804 796 rv = CKR_GENERAL_ERROR;
805 797 goto cleanup_x942dhpri2asn;
806 798 }
807 799
808 800 /*
809 801 * Add DH parameters:
810 802 * ...
811 803 * begin-sequence {
812 804 * prime,
813 805 * ...
814 806 */
815 807 if ((rv = pad_bigint_attr(OBJ_PRI_DH942_PRIME(objp), &tmp_pad)) !=
816 808 CKR_OK)
817 809 goto cleanup_x942dhpri2asn;
818 810 if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
819 811 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
820 812 rv = CKR_GENERAL_ERROR;
821 813 goto cleanup_x942dhpri2asn;
822 814 }
823 815
824 816 /*
825 817 * ...
826 818 * base,
827 819 * ...
828 820 */
829 821 if ((rv = pad_bigint_attr(OBJ_PRI_DH942_BASE(objp), &tmp_pad)) !=
830 822 CKR_OK)
831 823 goto cleanup_x942dhpri2asn;
832 824 if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
833 825 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
834 826 rv = CKR_GENERAL_ERROR;
835 827 goto cleanup_x942dhpri2asn;
836 828 }
837 829
838 830 /*
839 831 * ...
840 832 * subprime
841 833 * } end-sequence
842 834 */
843 835 if ((rv = pad_bigint_attr(OBJ_PRI_DH942_SUBPRIME(objp), &tmp_pad)) !=
844 836 CKR_OK)
845 837 goto cleanup_x942dhpri2asn;
846 838 if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
847 839 tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
848 840 rv = CKR_GENERAL_ERROR;
849 841 goto cleanup_x942dhpri2asn;
850 842 }
851 843
852 844 /*
853 845 * Add the key octet string:
854 846 * } end-sequence
855 847 * DHPrivateKey
856 848 * } end-sequence
857 849 */
858 850 if (ber_printf(p8obj_asn, "}o}",
859 851 key_octs->bv_val, key_octs->bv_len) == -1) {
860 852 rv = CKR_GENERAL_ERROR;
861 853 goto cleanup_x942dhpri2asn;
862 854 }
863 855
864 856 /* Convert PKCS#8 object ASN.1 to octet string. */
865 857 if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
866 858 rv = CKR_GENERAL_ERROR;
867 859 goto cleanup_x942dhpri2asn;
868 860 }
869 861
870 862 /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
871 863 /*
872 864 * If the user passes in a null buf, then buf_len is set.
873 865 * If the user passes in a value with buf_len, then it can
874 866 * be checked to see if the accompanying buf is big enough.
875 867 * If it is, the octet string is copied into a pre-malloc'd
876 868 * buf; otherwise the user must resize buf and call again.
877 869 * In either case, buf_len is reset to the corrected size.
878 870 * See PKCS#11 section 11.2.
879 871 */
880 872 #ifdef _LP64
881 873 /* LINTED E_CAST_INT_TO_SMALL_INT */
882 874 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
883 875 #else
884 876 if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
885 877 #endif
↓ open down ↓ |
168 lines elided |
↑ open up ↑ |
886 878 *buf_len = p8obj_octs->bv_len;
887 879 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
888 880 goto cleanup_x942dhpri2asn;
889 881 }
890 882
891 883 *buf_len = p8obj_octs->bv_len;
892 884 (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
893 885
894 886 cleanup_x942dhpri2asn:
895 887
896 - if (tmp_pad.big_value != NULL) {
897 - (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
898 - free(tmp_pad.big_value);
899 - }
888 + freezero(tmp_pad.big_value, tmp_pad.big_value_len);
900 889
901 890 if (key_asn != NULLBER)
902 891 ber_free(key_asn, 1);
903 892
904 893 if (key_octs != NULL)
905 894 ber_bvfree(key_octs);
906 895
907 896 if (p8obj_asn != NULLBER)
908 897 ber_free(p8obj_asn, 1);
909 898
910 899 if (p8obj_octs != NULL)
911 900 ber_bvfree(p8obj_octs);
912 901
913 902 return (rv);
914 903 }
915 904
916 905 /*
917 906 * Encode the object key from the soft_object_t into ASN.1 format.
918 907 */
919 908 CK_RV
920 909 soft_object_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
921 910 {
922 911 CK_OBJECT_CLASS class = objp->class;
923 912 CK_KEY_TYPE keytype = objp->key_type;
924 913
925 914 switch (class) {
926 915
927 916 case CKO_PRIVATE_KEY:
928 917 switch (keytype) {
929 918 case CKK_RSA:
930 919 return (rsa_pri_to_asn1(objp, buf, buf_len));
931 920
932 921 case CKK_DSA:
933 922 return (dsa_pri_to_asn1(objp, buf, buf_len));
934 923
935 924 case CKK_DH:
936 925 return (dh_pri_to_asn1(objp, buf, buf_len));
937 926
938 927 case CKK_X9_42_DH:
939 928 return (x942_dh_pri_to_asn1(objp, buf, buf_len));
940 929
941 930 default:
942 931 return (CKR_FUNCTION_NOT_SUPPORTED);
943 932 } /* keytype */
944 933
945 934 default:
946 935 return (CKR_FUNCTION_NOT_SUPPORTED);
947 936
948 937 } /* class */
949 938 }
950 939
951 940 /* Decode ASN.1 BER syntax into RSA private key. */
952 941 static CK_RV
953 942 asn1_to_rsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
954 943 {
955 944 CK_RV rv = CKR_OK;
956 945 BerValue p8obj_octs, key_octs;
957 946 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
958 947 ber_len_t size, tmplen;
959 948 char *cookie;
960 949 int version;
961 950 uchar_t oid[sizeof (RSA_OID) + 1];
962 951 biginteger_t tmp, tmp_nopad = { NULL, 0 };
963 952
964 953 p8obj_octs.bv_val = (char *)buf;
965 954 #ifdef _LP64
966 955 /* LINTED E_CAST_INT_TO_SMALL_INT */
967 956 p8obj_octs.bv_len = (ber_len_t)buf_len;
968 957 #else
969 958 p8obj_octs.bv_len = (ber_len_t)buf_len;
970 959 #endif
971 960
972 961 key_octs.bv_val = NULL;
973 962 key_octs.bv_len = 0;
974 963
975 964 /* Decode PKCS#8 object ASN.1, verifying it is RSA private key. */
976 965 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
977 966 return (CKR_GENERAL_ERROR);
978 967
979 968 /* PKCS#8 PrivateKeyInfo ... */
980 969 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
981 970 rv = CKR_WRAPPED_KEY_INVALID;
982 971 goto cleanup_asn2rsapri;
983 972 }
984 973 /* ... begin-sequence { version, */
985 974 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
986 975
987 976 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
988 977 rv = CKR_WRAPPED_KEY_INVALID;
989 978 goto cleanup_asn2rsapri;
990 979 }
991 980 /* ... begin-sequence { */
992 981 (void) ber_scanf(p8obj_asn, "{");
993 982
994 983 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
995 984 rv = CKR_WRAPPED_KEY_INVALID;
996 985 goto cleanup_asn2rsapri;
997 986 }
998 987 /* ... OID, \* RSA algorithm OID *\ */
999 988 if (size != sizeof (RSA_OID)) {
1000 989 rv = CKR_FUNCTION_NOT_SUPPORTED;
1001 990 goto cleanup_asn2rsapri;
1002 991 }
1003 992 size = sizeof (oid);
1004 993 (void) ber_scanf(p8obj_asn, "s", oid, &size);
1005 994 if (memcmp(oid, RSA_OID, size) != 0) {
1006 995 rv = CKR_FUNCTION_NOT_SUPPORTED;
1007 996 goto cleanup_asn2rsapri;
1008 997 }
1009 998
1010 999 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_NULL) {
1011 1000 rv = CKR_WRAPPED_KEY_INVALID;
1012 1001 goto cleanup_asn2rsapri;
1013 1002 }
1014 1003 /* ... param(NULL) } end-sequence */
1015 1004 (void) ber_scanf(p8obj_asn, "n"); /* "n}" ? */
1016 1005
1017 1006 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1018 1007 rv = CKR_WRAPPED_KEY_INVALID;
1019 1008 goto cleanup_asn2rsapri;
1020 1009 }
1021 1010 /* ... RSAPrivateKey } end-sequence */
1022 1011 key_octs.bv_len = size + 1;
1023 1012 if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1024 1013 rv = CKR_HOST_MEMORY;
1025 1014 goto cleanup_asn2rsapri;
1026 1015 }
1027 1016 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */
1028 1017 key_octs.bv_val, &key_octs.bv_len);
1029 1018
1030 1019 /* Decode key octet string into softtoken key object. */
1031 1020 if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1032 1021 rv = CKR_GENERAL_ERROR;
1033 1022 goto cleanup_asn2rsapri;
1034 1023 }
1035 1024
1036 1025 /* ... begin-sequence { version, */
1037 1026 if (ber_first_element(key_asn, &size, &cookie) != LBER_INTEGER) {
1038 1027 rv = CKR_WRAPPED_KEY_INVALID;
1039 1028 goto cleanup_asn2rsapri;
1040 1029 }
1041 1030 (void) ber_scanf(key_asn, "i", &version); /* "{i" ? */
1042 1031
1043 1032 /* ... modulus, */
1044 1033 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1045 1034 rv = CKR_WRAPPED_KEY_INVALID;
1046 1035 goto cleanup_asn2rsapri;
1047 1036 }
1048 1037 if (size > MAX_RSA_KEY) {
1049 1038 rv = CKR_FUNCTION_NOT_SUPPORTED;
1050 1039 goto cleanup_asn2rsapri;
1051 1040 }
1052 1041 tmplen = size + 1;
1053 1042 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1054 1043 rv = CKR_HOST_MEMORY;
1055 1044 goto cleanup_asn2rsapri;
1056 1045 }
1057 1046 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1058 1047 tmp.big_value_len = tmplen;
1059 1048 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1060 1049 free(tmp.big_value);
1061 1050 goto cleanup_asn2rsapri;
1062 1051 }
1063 1052 free(tmp.big_value);
1064 1053 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_MOD(keyp));
1065 1054
1066 1055 /* ... public exponent, */
1067 1056 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1068 1057 rv = CKR_WRAPPED_KEY_INVALID;
1069 1058 goto error_asn2rsapri;
1070 1059 }
1071 1060 if (size > MAX_RSA_KEY) {
1072 1061 rv = CKR_FUNCTION_NOT_SUPPORTED;
1073 1062 goto error_asn2rsapri;
1074 1063 }
1075 1064 tmplen = size + 1;
1076 1065 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1077 1066 rv = CKR_HOST_MEMORY;
1078 1067 goto error_asn2rsapri;
1079 1068 }
1080 1069 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1081 1070 tmp.big_value_len = tmplen;
1082 1071 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1083 1072 free(tmp.big_value);
1084 1073 goto error_asn2rsapri;
1085 1074 }
1086 1075 free(tmp.big_value);
1087 1076 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PUBEXPO(keyp));
1088 1077
1089 1078 /* ... private exponent, */
1090 1079 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1091 1080 rv = CKR_WRAPPED_KEY_INVALID;
1092 1081 goto error_asn2rsapri;
1093 1082 }
1094 1083 if (size > MAX_RSA_KEY) {
1095 1084 rv = CKR_FUNCTION_NOT_SUPPORTED;
1096 1085 goto error_asn2rsapri;
1097 1086 }
1098 1087 tmplen = size + 1;
1099 1088 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1100 1089 rv = CKR_HOST_MEMORY;
1101 1090 goto error_asn2rsapri;
1102 1091 }
1103 1092 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1104 1093 tmp.big_value_len = tmplen;
1105 1094 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1106 1095 free(tmp.big_value);
1107 1096 goto error_asn2rsapri;
1108 1097 }
1109 1098 free(tmp.big_value);
1110 1099 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIEXPO(keyp));
1111 1100
1112 1101 /* ... prime 1, */
1113 1102 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1114 1103 rv = CKR_WRAPPED_KEY_INVALID;
1115 1104 goto error_asn2rsapri;
1116 1105 }
1117 1106 if (size > MAX_RSA_KEY) {
1118 1107 rv = CKR_FUNCTION_NOT_SUPPORTED;
1119 1108 goto error_asn2rsapri;
1120 1109 }
1121 1110 tmplen = size + 1;
1122 1111 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1123 1112 rv = CKR_HOST_MEMORY;
1124 1113 goto error_asn2rsapri;
1125 1114 }
1126 1115 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1127 1116 tmp.big_value_len = tmplen;
1128 1117 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1129 1118 free(tmp.big_value);
1130 1119 goto error_asn2rsapri;
1131 1120 }
1132 1121 free(tmp.big_value);
1133 1122 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME1(keyp));
1134 1123
1135 1124 /* ... prime 2, */
1136 1125 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1137 1126 rv = CKR_WRAPPED_KEY_INVALID;
1138 1127 goto error_asn2rsapri;
1139 1128 }
1140 1129 if (size > MAX_RSA_KEY) {
1141 1130 rv = CKR_FUNCTION_NOT_SUPPORTED;
1142 1131 goto error_asn2rsapri;
1143 1132 }
1144 1133 tmplen = size + 1;
1145 1134 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1146 1135 rv = CKR_HOST_MEMORY;
1147 1136 goto error_asn2rsapri;
1148 1137 }
1149 1138 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1150 1139 tmp.big_value_len = tmplen;
1151 1140 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1152 1141 free(tmp.big_value);
1153 1142 goto error_asn2rsapri;
1154 1143 }
1155 1144 free(tmp.big_value);
1156 1145 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME2(keyp));
1157 1146
1158 1147 /* ... exponent 1, */
1159 1148 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1160 1149 rv = CKR_WRAPPED_KEY_INVALID;
1161 1150 goto error_asn2rsapri;
1162 1151 }
1163 1152 if (size > MAX_RSA_KEY) {
1164 1153 rv = CKR_FUNCTION_NOT_SUPPORTED;
1165 1154 goto error_asn2rsapri;
1166 1155 }
1167 1156 tmplen = size + 1;
1168 1157 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1169 1158 rv = CKR_HOST_MEMORY;
1170 1159 goto error_asn2rsapri;
1171 1160 }
1172 1161 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1173 1162 tmp.big_value_len = tmplen;
1174 1163 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1175 1164 free(tmp.big_value);
1176 1165 goto error_asn2rsapri;
1177 1166 }
1178 1167 free(tmp.big_value);
1179 1168 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO1(keyp));
1180 1169
1181 1170 /* ... exponent 2, */
1182 1171 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1183 1172 rv = CKR_WRAPPED_KEY_INVALID;
1184 1173 goto error_asn2rsapri;
1185 1174 }
1186 1175 if (size > MAX_RSA_KEY) {
1187 1176 rv = CKR_FUNCTION_NOT_SUPPORTED;
1188 1177 goto error_asn2rsapri;
1189 1178 }
1190 1179 tmplen = size + 1;
1191 1180 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1192 1181 rv = CKR_HOST_MEMORY;
1193 1182 goto error_asn2rsapri;
1194 1183 }
1195 1184 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1196 1185 tmp.big_value_len = tmplen;
1197 1186 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1198 1187 free(tmp.big_value);
1199 1188 goto error_asn2rsapri;
1200 1189 }
1201 1190 free(tmp.big_value);
1202 1191 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO2(keyp));
1203 1192
1204 1193 /* ... coefficient } end-sequence */
1205 1194 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1206 1195 rv = CKR_WRAPPED_KEY_INVALID;
1207 1196 goto error_asn2rsapri;
1208 1197 }
1209 1198 if (size > MAX_RSA_KEY) {
1210 1199 rv = CKR_FUNCTION_NOT_SUPPORTED;
1211 1200 goto error_asn2rsapri;
1212 1201 }
1213 1202 tmplen = size + 1;
1214 1203 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1215 1204 rv = CKR_HOST_MEMORY;
1216 1205 goto error_asn2rsapri;
1217 1206 }
1218 1207 (void) ber_scanf(key_asn, "s", /* "s}" ? */
1219 1208 tmp.big_value, &tmplen);
1220 1209 tmp.big_value_len = tmplen;
1221 1210 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1222 1211 free(tmp.big_value);
1223 1212 goto error_asn2rsapri;
1224 1213 }
1225 1214 free(tmp.big_value);
1226 1215 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_COEF(keyp));
1227 1216
1228 1217 goto cleanup_asn2rsapri;
1229 1218
1230 1219 error_asn2rsapri:
1231 1220
1232 1221 bigint_attr_cleanup(KEY_PRI_RSA_MOD(keyp));
↓ open down ↓ |
323 lines elided |
↑ open up ↑ |
1233 1222 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(keyp));
1234 1223 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(keyp));
1235 1224 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(keyp));
1236 1225 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(keyp));
1237 1226 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(keyp));
1238 1227 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(keyp));
1239 1228 bigint_attr_cleanup(KEY_PRI_RSA_COEF(keyp));
1240 1229
1241 1230 cleanup_asn2rsapri:
1242 1231
1243 - if (tmp_nopad.big_value != NULL) {
1244 - (void) memset(tmp_nopad.big_value, 0x0,
1245 - tmp_nopad.big_value_len);
1246 - free(tmp_nopad.big_value);
1247 - }
1232 + freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1248 1233
1249 1234 if (p8obj_asn != NULLBER)
1250 1235 ber_free(p8obj_asn, 1);
1251 1236
1252 1237 if (key_octs.bv_val != NULL)
1253 1238 free(key_octs.bv_val);
1254 1239
1255 1240 if (key_asn != NULLBER)
1256 1241 ber_free(key_asn, 1);
1257 1242
1258 1243 return (rv);
1259 1244 }
1260 1245
1261 1246 /* Decode ASN.1 BER syntax into DSA private key. */
1262 1247 static CK_RV
1263 1248 asn1_to_dsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1264 1249 {
1265 1250 CK_RV rv = CKR_OK;
1266 1251 BerValue p8obj_octs, key_octs;
1267 1252 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
1268 1253 ber_len_t size, tmplen;
1269 1254 char *cookie;
1270 1255 int version;
1271 1256 uchar_t oid[sizeof (DSA_OID) + 1];
1272 1257 biginteger_t tmp, tmp_nopad = { NULL, 0 };
1273 1258
1274 1259 p8obj_octs.bv_val = (char *)buf;
1275 1260 #ifdef _LP64
1276 1261 /* LINTED E_CAST_INT_TO_SMALL_INT */
1277 1262 p8obj_octs.bv_len = (ber_len_t)buf_len;
1278 1263 #else
1279 1264 p8obj_octs.bv_len = (ber_len_t)buf_len;
1280 1265 #endif
1281 1266
1282 1267 key_octs.bv_val = NULL;
1283 1268 key_octs.bv_len = 0;
1284 1269
1285 1270 /* Decode PKCS#8 object ASN.1, verifying it is DSA private key. */
1286 1271 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1287 1272 return (CKR_GENERAL_ERROR);
1288 1273
1289 1274 /* PKCS#8 PrivateKeyInfo ... */
1290 1275 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1291 1276 rv = CKR_WRAPPED_KEY_INVALID;
1292 1277 goto cleanup_asn2dsapri;
1293 1278 }
1294 1279 /* ... begin-sequence { version, */
1295 1280 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
1296 1281
1297 1282 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1298 1283 rv = CKR_WRAPPED_KEY_INVALID;
1299 1284 goto cleanup_asn2dsapri;
1300 1285 }
1301 1286 /* ... begin-sequence { */
1302 1287 (void) ber_scanf(p8obj_asn, "{");
1303 1288
1304 1289 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1305 1290 rv = CKR_WRAPPED_KEY_INVALID;
1306 1291 goto cleanup_asn2dsapri;
1307 1292 }
1308 1293 /* ... OID, \* DSA algorithm OID *\ */
1309 1294 if (size != sizeof (DSA_OID)) {
1310 1295 rv = CKR_FUNCTION_NOT_SUPPORTED;
1311 1296 goto cleanup_asn2dsapri;
1312 1297 }
1313 1298 size = sizeof (oid);
1314 1299 (void) ber_scanf(p8obj_asn, "s", oid, &size);
1315 1300 if (memcmp(oid, DSA_OID, size) != 0) {
1316 1301 rv = CKR_FUNCTION_NOT_SUPPORTED;
1317 1302 goto cleanup_asn2dsapri;
1318 1303 }
1319 1304
1320 1305 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1321 1306 rv = CKR_WRAPPED_KEY_INVALID;
1322 1307 goto cleanup_asn2dsapri;
1323 1308 }
1324 1309 /* ... begin-sequence { */
1325 1310 (void) ber_scanf(p8obj_asn, "{");
1326 1311
1327 1312 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1328 1313 rv = CKR_WRAPPED_KEY_INVALID;
1329 1314 goto cleanup_asn2dsapri;
1330 1315 }
1331 1316 /* ... prime, */
1332 1317 if (size > MAX_DSA_KEY) {
1333 1318 rv = CKR_FUNCTION_NOT_SUPPORTED;
1334 1319 goto cleanup_asn2dsapri;
1335 1320 }
1336 1321 tmplen = size + 1;
1337 1322 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1338 1323 rv = CKR_HOST_MEMORY;
1339 1324 goto cleanup_asn2dsapri;
1340 1325 }
1341 1326 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1342 1327 tmp.big_value_len = tmplen;
1343 1328 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1344 1329 free(tmp.big_value);
1345 1330 goto cleanup_asn2dsapri;
1346 1331 }
1347 1332 free(tmp.big_value);
1348 1333 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_PRIME(keyp));
1349 1334
1350 1335 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1351 1336 rv = CKR_WRAPPED_KEY_INVALID;
1352 1337 goto error_asn2dsapri;
1353 1338 }
1354 1339 /* ... subprime, */
1355 1340 if (size > MAX_DSA_KEY) {
1356 1341 rv = CKR_FUNCTION_NOT_SUPPORTED;
1357 1342 goto error_asn2dsapri;
1358 1343 }
1359 1344 tmplen = size + 1;
1360 1345 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1361 1346 rv = CKR_HOST_MEMORY;
1362 1347 goto error_asn2dsapri;
1363 1348 }
1364 1349 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1365 1350 tmp.big_value_len = tmplen;
1366 1351 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1367 1352 free(tmp.big_value);
1368 1353 goto error_asn2dsapri;
1369 1354 }
1370 1355 free(tmp.big_value);
1371 1356 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_SUBPRIME(keyp));
1372 1357
1373 1358 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1374 1359 rv = CKR_WRAPPED_KEY_INVALID;
1375 1360 goto error_asn2dsapri;
1376 1361 }
1377 1362 /* ... base } end-sequence } end-sequence */
1378 1363 if (size > MAX_DSA_KEY) {
1379 1364 rv = CKR_FUNCTION_NOT_SUPPORTED;
1380 1365 goto error_asn2dsapri;
1381 1366 }
1382 1367 tmplen = size + 1;
1383 1368 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1384 1369 rv = CKR_HOST_MEMORY;
1385 1370 goto error_asn2dsapri;
1386 1371 }
1387 1372 (void) ber_scanf(p8obj_asn, "s", /* "s}}" ? */
1388 1373 tmp.big_value, &tmplen);
1389 1374 tmp.big_value_len = tmplen;
1390 1375 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1391 1376 free(tmp.big_value);
1392 1377 goto error_asn2dsapri;
1393 1378 }
1394 1379 free(tmp.big_value);
1395 1380 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_BASE(keyp));
1396 1381
1397 1382 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1398 1383 rv = CKR_WRAPPED_KEY_INVALID;
1399 1384 goto error_asn2dsapri;
1400 1385 }
1401 1386 /* ... DSAPrivateKey } end-sequence */
1402 1387 key_octs.bv_len = size + 1;
1403 1388 if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1404 1389 rv = CKR_HOST_MEMORY;
1405 1390 goto error_asn2dsapri;
1406 1391 }
1407 1392 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */
1408 1393 key_octs.bv_val, &key_octs.bv_len);
1409 1394
1410 1395 /* Decode key octet string into softtoken key object. */
1411 1396 if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1412 1397 rv = CKR_GENERAL_ERROR;
1413 1398 goto error_asn2dsapri;
1414 1399 }
1415 1400
1416 1401 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1417 1402 rv = CKR_WRAPPED_KEY_INVALID;
1418 1403 goto error_asn2dsapri;
1419 1404 }
1420 1405 /* ... value } end-sequence */
1421 1406 if (size > MAX_DSA_KEY) {
1422 1407 rv = CKR_FUNCTION_NOT_SUPPORTED;
1423 1408 goto error_asn2dsapri;
1424 1409 }
1425 1410 tmplen = size + 1;
1426 1411 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1427 1412 rv = CKR_HOST_MEMORY;
1428 1413 goto error_asn2dsapri;
1429 1414 }
1430 1415 (void) ber_scanf(key_asn, "s", /* "s}" ? */
1431 1416 tmp.big_value, &tmplen);
1432 1417 tmp.big_value_len = tmplen;
1433 1418 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1434 1419 free(tmp.big_value);
1435 1420 goto error_asn2dsapri;
1436 1421 }
1437 1422 free(tmp.big_value);
1438 1423 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_VALUE(keyp));
1439 1424
1440 1425 goto cleanup_asn2dsapri;
↓ open down ↓ |
183 lines elided |
↑ open up ↑ |
1441 1426
1442 1427 error_asn2dsapri:
1443 1428
1444 1429 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(keyp));
1445 1430 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(keyp));
1446 1431 bigint_attr_cleanup(KEY_PRI_DSA_BASE(keyp));
1447 1432 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(keyp));
1448 1433
1449 1434 cleanup_asn2dsapri:
1450 1435
1451 - if (tmp_nopad.big_value != NULL) {
1452 - (void) memset(tmp_nopad.big_value, 0x0,
1453 - tmp_nopad.big_value_len);
1454 - free(tmp_nopad.big_value);
1455 - }
1436 + freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1456 1437
1457 1438 if (p8obj_asn != NULLBER)
1458 1439 ber_free(p8obj_asn, 1);
1459 1440
1460 1441 if (key_octs.bv_val != NULL)
1461 1442 free(key_octs.bv_val);
1462 1443
1463 1444 if (key_asn != NULLBER)
1464 1445 ber_free(key_asn, 1);
1465 1446
1466 1447 return (rv);
1467 1448 }
1468 1449
1469 1450 /* Decode ASN.1 BER syntax into DH private key. */
1470 1451 static CK_RV
1471 1452 asn1_to_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1472 1453 {
1473 1454 CK_RV rv = CKR_OK;
1474 1455 BerValue p8obj_octs, key_octs;
1475 1456 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
1476 1457 ber_len_t size, tmplen;
1477 1458 char *cookie;
1478 1459 int version;
1479 1460 uchar_t oid[sizeof (DH_OID) + 1];
1480 1461 biginteger_t tmp, tmp_nopad = { NULL, 0 };
1481 1462
1482 1463 p8obj_octs.bv_val = (char *)buf;
1483 1464 #ifdef _LP64
1484 1465 /* LINTED E_CAST_INT_TO_SMALL_INT */
1485 1466 p8obj_octs.bv_len = (ber_len_t)buf_len;
1486 1467 #else
1487 1468 p8obj_octs.bv_len = (ber_len_t)buf_len;
1488 1469 #endif
1489 1470
1490 1471 key_octs.bv_val = NULL;
1491 1472 key_octs.bv_len = 0;
1492 1473
1493 1474 /* Decode PKCS#8 object ASN.1, verifying it is DH private key. */
1494 1475 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1495 1476 return (CKR_GENERAL_ERROR);
1496 1477
1497 1478 /* PKCS#8 PrivateKeyInfo ... */
1498 1479 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1499 1480 rv = CKR_WRAPPED_KEY_INVALID;
1500 1481 goto cleanup_asn2dhpri;
1501 1482 }
1502 1483 /* ... begin-sequence { version, */
1503 1484 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
1504 1485
1505 1486 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1506 1487 rv = CKR_WRAPPED_KEY_INVALID;
1507 1488 goto cleanup_asn2dhpri;
1508 1489 }
1509 1490 /* ... begin-sequence { */
1510 1491 (void) ber_scanf(p8obj_asn, "{");
1511 1492
1512 1493 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1513 1494 rv = CKR_WRAPPED_KEY_INVALID;
1514 1495 goto cleanup_asn2dhpri;
1515 1496 }
1516 1497 /* ... OID, \* DH algorithm OID *\ */
1517 1498 if (size != sizeof (DH_OID)) {
1518 1499 rv = CKR_FUNCTION_NOT_SUPPORTED;
1519 1500 goto cleanup_asn2dhpri;
1520 1501 }
1521 1502 size = sizeof (oid);
1522 1503 (void) ber_scanf(p8obj_asn, "s", oid, &size);
1523 1504 if (memcmp(oid, DH_OID, size) != 0) {
1524 1505 rv = CKR_FUNCTION_NOT_SUPPORTED;
1525 1506 goto cleanup_asn2dhpri;
1526 1507 }
1527 1508
1528 1509 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1529 1510 rv = CKR_WRAPPED_KEY_INVALID;
1530 1511 goto cleanup_asn2dhpri;
1531 1512 }
1532 1513 /* ... begin-sequence { */
1533 1514 (void) ber_scanf(p8obj_asn, "{");
1534 1515
1535 1516 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1536 1517 rv = CKR_WRAPPED_KEY_INVALID;
1537 1518 goto cleanup_asn2dhpri;
1538 1519 }
1539 1520 /* ... prime, */
1540 1521 if (size > MAX_DH_KEY) {
1541 1522 rv = CKR_FUNCTION_NOT_SUPPORTED;
1542 1523 goto cleanup_asn2dhpri;
1543 1524 }
1544 1525 tmplen = size + 1;
1545 1526 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1546 1527 rv = CKR_HOST_MEMORY;
1547 1528 goto cleanup_asn2dhpri;
1548 1529 }
1549 1530 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1550 1531 tmp.big_value_len = tmplen;
1551 1532 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1552 1533 free(tmp.big_value);
1553 1534 goto cleanup_asn2dhpri;
1554 1535 }
1555 1536 free(tmp.big_value);
1556 1537 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_PRIME(keyp));
1557 1538
1558 1539 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1559 1540 rv = CKR_WRAPPED_KEY_INVALID;
1560 1541 goto error_asn2dhpri;
1561 1542 }
1562 1543 /* ... base } end-sequence } end-sequence */
1563 1544 if (size > MAX_DH_KEY) {
1564 1545 rv = CKR_FUNCTION_NOT_SUPPORTED;
1565 1546 goto error_asn2dhpri;
1566 1547 }
1567 1548 tmplen = size + 1;
1568 1549 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1569 1550 rv = CKR_HOST_MEMORY;
1570 1551 goto error_asn2dhpri;
1571 1552 }
1572 1553 (void) ber_scanf(p8obj_asn, "s", /* "s}}" ? */
1573 1554 tmp.big_value, &tmplen);
1574 1555 tmp.big_value_len = tmplen;
1575 1556 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1576 1557 free(tmp.big_value);
1577 1558 goto error_asn2dhpri;
1578 1559 }
1579 1560 free(tmp.big_value);
1580 1561 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_BASE(keyp));
1581 1562
1582 1563 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1583 1564 rv = CKR_WRAPPED_KEY_INVALID;
1584 1565 goto error_asn2dhpri;
1585 1566 }
1586 1567 /* ... DHPrivateKey } end-sequence */
1587 1568 key_octs.bv_len = size + 1;
1588 1569 if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1589 1570 rv = CKR_HOST_MEMORY;
1590 1571 goto error_asn2dhpri;
1591 1572 }
1592 1573 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */
1593 1574 key_octs.bv_val, &key_octs.bv_len);
1594 1575
1595 1576 /* Decode key octet string into softtoken key object. */
1596 1577 if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1597 1578 rv = CKR_GENERAL_ERROR;
1598 1579 goto error_asn2dhpri;
1599 1580 }
1600 1581
1601 1582 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1602 1583 rv = CKR_WRAPPED_KEY_INVALID;
1603 1584 goto error_asn2dhpri;
1604 1585 }
1605 1586 /* ... value } end-sequence */
1606 1587 if (size > MAX_DH_KEY) {
1607 1588 rv = CKR_FUNCTION_NOT_SUPPORTED;
1608 1589 goto error_asn2dhpri;
1609 1590 }
1610 1591 tmplen = size + 1;
1611 1592 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1612 1593 rv = CKR_HOST_MEMORY;
1613 1594 goto error_asn2dhpri;
1614 1595 }
1615 1596 (void) ber_scanf(key_asn, "s", /* "s}" ? */
1616 1597 tmp.big_value, &tmplen);
1617 1598 tmp.big_value_len = tmplen;
1618 1599 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1619 1600 free(tmp.big_value);
1620 1601 goto error_asn2dhpri;
1621 1602 }
1622 1603 free(tmp.big_value);
1623 1604 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_VALUE(keyp));
1624 1605
↓ open down ↓ |
159 lines elided |
↑ open up ↑ |
1625 1606 goto cleanup_asn2dhpri;
1626 1607
1627 1608 error_asn2dhpri:
1628 1609
1629 1610 bigint_attr_cleanup(KEY_PRI_DH_PRIME(keyp));
1630 1611 bigint_attr_cleanup(KEY_PRI_DH_BASE(keyp));
1631 1612 bigint_attr_cleanup(KEY_PRI_DH_VALUE(keyp));
1632 1613
1633 1614 cleanup_asn2dhpri:
1634 1615
1635 - if (tmp_nopad.big_value != NULL) {
1636 - (void) memset(tmp_nopad.big_value, 0x0,
1637 - tmp_nopad.big_value_len);
1638 - free(tmp_nopad.big_value);
1639 - }
1616 + freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1640 1617
1641 1618 if (p8obj_asn != NULLBER)
1642 1619 ber_free(p8obj_asn, 1);
1643 1620
1644 1621 if (key_octs.bv_val != NULL)
1645 1622 free(key_octs.bv_val);
1646 1623
1647 1624 if (key_asn != NULLBER)
1648 1625 ber_free(key_asn, 1);
1649 1626
1650 1627 return (rv);
1651 1628 }
1652 1629
1653 1630 /* Decode ASN.1 BER syntax into DH X9.42 private key. */
1654 1631 static CK_RV
1655 1632 asn1_to_x942_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1656 1633 {
1657 1634 CK_RV rv = CKR_OK;
1658 1635 BerValue p8obj_octs, key_octs;
1659 1636 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
1660 1637 ber_len_t size, tmplen;
1661 1638 char *cookie;
1662 1639 int version;
1663 1640 uchar_t oid[sizeof (DH942_OID) + 1];
1664 1641 biginteger_t tmp, tmp_nopad = { NULL, 0 };
1665 1642
1666 1643 p8obj_octs.bv_val = (char *)buf;
1667 1644 #ifdef _LP64
1668 1645 /* LINTED E_CAST_INT_TO_SMALL_INT */
1669 1646 p8obj_octs.bv_len = (ber_len_t)buf_len;
1670 1647 #else
1671 1648 p8obj_octs.bv_len = (ber_len_t)buf_len;
1672 1649 #endif
1673 1650
1674 1651 key_octs.bv_val = NULL;
1675 1652 key_octs.bv_len = 0;
1676 1653
1677 1654 /* Decode PKCS#8 object ASN.1, verifying it is DH X9.42 private key. */
1678 1655 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1679 1656 return (CKR_GENERAL_ERROR);
1680 1657
1681 1658 /* PKCS#8 PrivateKeyInfo ... */
1682 1659 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1683 1660 rv = CKR_WRAPPED_KEY_INVALID;
1684 1661 goto cleanup_asn2x942dhpri;
1685 1662 }
1686 1663 /* ... begin-sequence { version, */
1687 1664 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
1688 1665
1689 1666 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1690 1667 rv = CKR_WRAPPED_KEY_INVALID;
1691 1668 goto cleanup_asn2x942dhpri;
1692 1669 }
1693 1670 /* ... begin-sequence { */
1694 1671 (void) ber_scanf(p8obj_asn, "{");
1695 1672
1696 1673 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1697 1674 rv = CKR_WRAPPED_KEY_INVALID;
1698 1675 goto cleanup_asn2x942dhpri;
1699 1676 }
1700 1677 /* ... OID, \* DH X9.42 algorithm OID *\ */
1701 1678 if (size != sizeof (DH942_OID)) {
1702 1679 rv = CKR_FUNCTION_NOT_SUPPORTED;
1703 1680 goto cleanup_asn2x942dhpri;
1704 1681 }
1705 1682 size = sizeof (oid);
1706 1683 (void) ber_scanf(p8obj_asn, "s", oid, &size);
1707 1684 if (memcmp(oid, DH942_OID, size) != 0) {
1708 1685 rv = CKR_FUNCTION_NOT_SUPPORTED;
1709 1686 goto cleanup_asn2x942dhpri;
1710 1687 }
1711 1688
1712 1689 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1713 1690 rv = CKR_WRAPPED_KEY_INVALID;
1714 1691 goto cleanup_asn2x942dhpri;
1715 1692 }
1716 1693 /* ... begin-sequence { */
1717 1694 (void) ber_scanf(p8obj_asn, "{");
1718 1695
1719 1696 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1720 1697 rv = CKR_WRAPPED_KEY_INVALID;
1721 1698 goto cleanup_asn2x942dhpri;
1722 1699 }
1723 1700 /* ... prime, */
1724 1701 if (size > MAX_DH942_KEY) {
1725 1702 rv = CKR_FUNCTION_NOT_SUPPORTED;
1726 1703 goto cleanup_asn2x942dhpri;
1727 1704 }
1728 1705 tmplen = size + 1;
1729 1706 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1730 1707 rv = CKR_HOST_MEMORY;
1731 1708 goto cleanup_asn2x942dhpri;
1732 1709 }
1733 1710 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1734 1711 tmp.big_value_len = tmplen;
1735 1712 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1736 1713 free(tmp.big_value);
1737 1714 goto cleanup_asn2x942dhpri;
1738 1715 }
1739 1716 free(tmp.big_value);
1740 1717 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_PRIME(keyp));
1741 1718
1742 1719 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1743 1720 rv = CKR_WRAPPED_KEY_INVALID;
1744 1721 goto error_asn2x942dhpri;
1745 1722 }
1746 1723 /* ... base, */
1747 1724 if (size > MAX_DH942_KEY) {
1748 1725 rv = CKR_FUNCTION_NOT_SUPPORTED;
1749 1726 goto error_asn2x942dhpri;
1750 1727 }
1751 1728 tmplen = size + 1;
1752 1729 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1753 1730 rv = CKR_HOST_MEMORY;
1754 1731 goto error_asn2x942dhpri;
1755 1732 }
1756 1733 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1757 1734 tmp.big_value_len = tmplen;
1758 1735 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1759 1736 free(tmp.big_value);
1760 1737 goto error_asn2x942dhpri;
1761 1738 }
1762 1739 free(tmp.big_value);
1763 1740 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_BASE(keyp));
1764 1741
1765 1742 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1766 1743 rv = CKR_WRAPPED_KEY_INVALID;
1767 1744 goto error_asn2x942dhpri;
1768 1745 }
1769 1746 /* ... subprime } end-sequence } end-sequence */
1770 1747 if (size > MAX_DH942_KEY) {
1771 1748 rv = CKR_FUNCTION_NOT_SUPPORTED;
1772 1749 goto error_asn2x942dhpri;
1773 1750 }
1774 1751 tmplen = size + 1;
1775 1752 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1776 1753 rv = CKR_HOST_MEMORY;
1777 1754 goto error_asn2x942dhpri;
1778 1755 }
1779 1756 (void) ber_scanf(p8obj_asn, "s", /* "s}}" ? */
1780 1757 tmp.big_value, &tmplen);
1781 1758 tmp.big_value_len = tmplen;
1782 1759 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1783 1760 free(tmp.big_value);
1784 1761 goto error_asn2x942dhpri;
1785 1762 }
1786 1763 free(tmp.big_value);
1787 1764 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_SUBPRIME(keyp));
1788 1765
1789 1766 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1790 1767 rv = CKR_WRAPPED_KEY_INVALID;
1791 1768 goto error_asn2x942dhpri;
1792 1769 }
1793 1770 /* ... DHPrivateKey } end-sequence */
1794 1771 key_octs.bv_len = size + 1;
1795 1772 if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1796 1773 rv = CKR_HOST_MEMORY;
1797 1774 goto error_asn2x942dhpri;
1798 1775 }
1799 1776 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */
1800 1777 key_octs.bv_val, &key_octs.bv_len);
1801 1778
1802 1779 /* Decode key octet string into softtoken key object. */
1803 1780 if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1804 1781 rv = CKR_GENERAL_ERROR;
1805 1782 goto error_asn2x942dhpri;
1806 1783 }
1807 1784
1808 1785 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1809 1786 rv = CKR_WRAPPED_KEY_INVALID;
1810 1787 goto error_asn2x942dhpri;
1811 1788 }
1812 1789 /* ... value } end-sequence */
1813 1790 if (size > MAX_DH942_KEY) {
1814 1791 rv = CKR_FUNCTION_NOT_SUPPORTED;
1815 1792 goto error_asn2x942dhpri;
1816 1793 }
1817 1794 tmplen = size + 1;
1818 1795 if ((tmp.big_value = malloc(tmplen)) == NULL) {
1819 1796 rv = CKR_HOST_MEMORY;
1820 1797 goto error_asn2x942dhpri;
1821 1798 }
1822 1799 (void) ber_scanf(key_asn, "s", /* "s}" ? */
1823 1800 tmp.big_value, &tmplen);
1824 1801 tmp.big_value_len = tmplen;
1825 1802 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1826 1803 free(tmp.big_value);
1827 1804 goto error_asn2x942dhpri;
1828 1805 }
1829 1806 free(tmp.big_value);
1830 1807 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_VALUE(keyp));
1831 1808
1832 1809 goto cleanup_asn2x942dhpri;
↓ open down ↓ |
183 lines elided |
↑ open up ↑ |
1833 1810
1834 1811 error_asn2x942dhpri:
1835 1812
1836 1813 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(keyp));
1837 1814 bigint_attr_cleanup(KEY_PRI_DH942_BASE(keyp));
1838 1815 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(keyp));
1839 1816 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(keyp));
1840 1817
1841 1818 cleanup_asn2x942dhpri:
1842 1819
1843 - if (tmp_nopad.big_value != NULL) {
1844 - (void) memset(tmp_nopad.big_value, 0x0,
1845 - tmp_nopad.big_value_len);
1846 - free(tmp_nopad.big_value);
1847 - }
1820 + freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1848 1821
1849 1822 if (p8obj_asn != NULLBER)
1850 1823 ber_free(p8obj_asn, 1);
1851 1824
1852 1825 if (key_octs.bv_val != NULL)
1853 1826 free(key_octs.bv_val);
1854 1827
1855 1828 if (key_asn != NULLBER)
1856 1829 ber_free(key_asn, 1);
1857 1830
1858 1831 return (rv);
1859 1832 }
1860 1833
1861 1834 /*
1862 1835 * Decode the object key from ASN.1 format into soft_object_t.
1863 1836 */
1864 1837 CK_RV
1865 1838 soft_asn1_to_object(soft_object_t *objp, uchar_t *buf, ulong_t buf_len)
1866 1839 {
1867 - CK_RV rv = CKR_OK;
1840 + CK_RV rv = CKR_OK;
1868 1841 CK_OBJECT_CLASS class = objp->class;
1869 1842 CK_KEY_TYPE keytype = objp->key_type;
1870 1843 private_key_obj_t *pvk;
1871 1844
1872 1845 switch (class) {
1873 1846
1874 1847 case CKO_PRIVATE_KEY:
1875 1848 /* Allocate storage for Private Key Object. */
1876 1849 if ((pvk = calloc(1, sizeof (private_key_obj_t))) == NULL) {
1877 1850 rv = CKR_HOST_MEMORY;
1878 1851 return (rv);
1879 1852 }
1880 1853
1881 1854 switch (keytype) {
1882 1855 case CKK_RSA:
1883 1856 rv = asn1_to_rsa_pri(pvk, buf, buf_len);
1884 1857 break;
1885 1858
1886 1859 case CKK_DSA:
1887 1860 rv = asn1_to_dsa_pri(pvk, buf, buf_len);
1888 1861 break;
1889 1862
1890 1863 case CKK_DH:
1891 1864 rv = asn1_to_dh_pri(pvk, buf, buf_len);
1892 1865 break;
1893 1866
1894 1867 case CKK_X9_42_DH:
1895 1868 rv = asn1_to_x942_dh_pri(pvk, buf, buf_len);
1896 1869 break;
1897 1870
1898 1871 default:
1899 1872 rv = CKR_FUNCTION_NOT_SUPPORTED;
1900 1873 break;
1901 1874
1902 1875 } /* keytype */
1903 1876
1904 1877 if (rv != CKR_OK)
1905 1878 free(pvk);
1906 1879 else
1907 1880 objp->object_class_u.private_key = pvk;
1908 1881 break;
1909 1882
1910 1883 default:
1911 1884 rv = CKR_FUNCTION_NOT_SUPPORTED;
1912 1885 break;
1913 1886
1914 1887 } /* class */
1915 1888
1916 1889 return (rv);
1917 1890 }
↓ open down ↓ |
40 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX