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