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