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