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