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