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