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 goto cleanup_asn2rsapri; 1053 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_MOD(keyp)); 1054 1055 /* ... public exponent, */ 1056 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1057 rv = CKR_WRAPPED_KEY_INVALID; 1058 goto error_asn2rsapri; 1059 } 1060 if (size > MAX_RSA_KEY) { 1061 rv = CKR_FUNCTION_NOT_SUPPORTED; 1062 goto error_asn2rsapri; 1063 } 1064 tmplen = size + 1; 1065 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1066 rv = CKR_HOST_MEMORY; 1067 goto error_asn2rsapri; 1068 } 1069 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen); 1070 tmp.big_value_len = tmplen; 1071 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1072 goto error_asn2rsapri; 1073 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PUBEXPO(keyp)); 1074 1075 /* ... private exponent, */ 1076 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1077 rv = CKR_WRAPPED_KEY_INVALID; 1078 goto error_asn2rsapri; 1079 } 1080 if (size > MAX_RSA_KEY) { 1081 rv = CKR_FUNCTION_NOT_SUPPORTED; 1082 goto error_asn2rsapri; 1083 } 1084 tmplen = size + 1; 1085 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1086 rv = CKR_HOST_MEMORY; 1087 goto error_asn2rsapri; 1088 } 1089 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen); 1090 tmp.big_value_len = tmplen; 1091 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1092 goto error_asn2rsapri; 1093 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIEXPO(keyp)); 1094 1095 /* ... prime 1, */ 1096 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1097 rv = CKR_WRAPPED_KEY_INVALID; 1098 goto error_asn2rsapri; 1099 } 1100 if (size > MAX_RSA_KEY) { 1101 rv = CKR_FUNCTION_NOT_SUPPORTED; 1102 goto error_asn2rsapri; 1103 } 1104 tmplen = size + 1; 1105 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1106 rv = CKR_HOST_MEMORY; 1107 goto error_asn2rsapri; 1108 } 1109 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen); 1110 tmp.big_value_len = tmplen; 1111 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1112 goto error_asn2rsapri; 1113 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME1(keyp)); 1114 1115 /* ... prime 2, */ 1116 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1117 rv = CKR_WRAPPED_KEY_INVALID; 1118 goto error_asn2rsapri; 1119 } 1120 if (size > MAX_RSA_KEY) { 1121 rv = CKR_FUNCTION_NOT_SUPPORTED; 1122 goto error_asn2rsapri; 1123 } 1124 tmplen = size + 1; 1125 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1126 rv = CKR_HOST_MEMORY; 1127 goto error_asn2rsapri; 1128 } 1129 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen); 1130 tmp.big_value_len = tmplen; 1131 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1132 goto error_asn2rsapri; 1133 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME2(keyp)); 1134 1135 /* ... exponent 1, */ 1136 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1137 rv = CKR_WRAPPED_KEY_INVALID; 1138 goto error_asn2rsapri; 1139 } 1140 if (size > MAX_RSA_KEY) { 1141 rv = CKR_FUNCTION_NOT_SUPPORTED; 1142 goto error_asn2rsapri; 1143 } 1144 tmplen = size + 1; 1145 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1146 rv = CKR_HOST_MEMORY; 1147 goto error_asn2rsapri; 1148 } 1149 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen); 1150 tmp.big_value_len = tmplen; 1151 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1152 goto error_asn2rsapri; 1153 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO1(keyp)); 1154 1155 /* ... exponent 2, */ 1156 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1157 rv = CKR_WRAPPED_KEY_INVALID; 1158 goto error_asn2rsapri; 1159 } 1160 if (size > MAX_RSA_KEY) { 1161 rv = CKR_FUNCTION_NOT_SUPPORTED; 1162 goto error_asn2rsapri; 1163 } 1164 tmplen = size + 1; 1165 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1166 rv = CKR_HOST_MEMORY; 1167 goto error_asn2rsapri; 1168 } 1169 (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen); 1170 tmp.big_value_len = tmplen; 1171 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1172 goto error_asn2rsapri; 1173 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO2(keyp)); 1174 1175 /* ... coefficient } end-sequence */ 1176 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1177 rv = CKR_WRAPPED_KEY_INVALID; 1178 goto error_asn2rsapri; 1179 } 1180 if (size > MAX_RSA_KEY) { 1181 rv = CKR_FUNCTION_NOT_SUPPORTED; 1182 goto error_asn2rsapri; 1183 } 1184 tmplen = size + 1; 1185 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1186 rv = CKR_HOST_MEMORY; 1187 goto error_asn2rsapri; 1188 } 1189 (void) ber_scanf(key_asn, "s", /* "s}" ? */ 1190 tmp.big_value, &tmplen); 1191 tmp.big_value_len = tmplen; 1192 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1193 goto error_asn2rsapri; 1194 copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_COEF(keyp)); 1195 1196 goto cleanup_asn2rsapri; 1197 1198 error_asn2rsapri: 1199 1200 bigint_attr_cleanup(KEY_PRI_RSA_MOD(keyp)); 1201 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(keyp)); 1202 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(keyp)); 1203 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(keyp)); 1204 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(keyp)); 1205 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(keyp)); 1206 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(keyp)); 1207 bigint_attr_cleanup(KEY_PRI_RSA_COEF(keyp)); 1208 1209 cleanup_asn2rsapri: 1210 1211 if (tmp_nopad.big_value != NULL) { 1212 (void) memset(tmp_nopad.big_value, 0x0, 1213 tmp_nopad.big_value_len); 1214 free(tmp_nopad.big_value); 1215 } 1216 1217 if (p8obj_asn != NULLBER) 1218 ber_free(p8obj_asn, 1); 1219 1220 if (key_octs.bv_val != NULL) 1221 free(key_octs.bv_val); 1222 1223 if (key_asn != NULLBER) 1224 ber_free(key_asn, 1); 1225 1226 return (rv); 1227 } 1228 1229 /* Decode ASN.1 BER syntax into DSA private key. */ 1230 static CK_RV 1231 asn1_to_dsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len) 1232 { 1233 CK_RV rv = CKR_OK; 1234 BerValue p8obj_octs, key_octs; 1235 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER; 1236 ber_len_t size, tmplen; 1237 char *cookie; 1238 int version; 1239 uchar_t oid[sizeof (DSA_OID) + 1]; 1240 biginteger_t tmp, tmp_nopad = { NULL, 0 }; 1241 1242 p8obj_octs.bv_val = (char *)buf; 1243 #ifdef _LP64 1244 /* LINTED E_CAST_INT_TO_SMALL_INT */ 1245 p8obj_octs.bv_len = (ber_len_t)buf_len; 1246 #else 1247 p8obj_octs.bv_len = (ber_len_t)buf_len; 1248 #endif 1249 1250 key_octs.bv_val = NULL; 1251 key_octs.bv_len = 0; 1252 1253 /* Decode PKCS#8 object ASN.1, verifying it is DSA private key. */ 1254 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER) 1255 return (CKR_GENERAL_ERROR); 1256 1257 /* PKCS#8 PrivateKeyInfo ... */ 1258 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) { 1259 rv = CKR_WRAPPED_KEY_INVALID; 1260 goto cleanup_asn2dsapri; 1261 } 1262 /* ... begin-sequence { version, */ 1263 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */ 1264 1265 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) { 1266 rv = CKR_WRAPPED_KEY_INVALID; 1267 goto cleanup_asn2dsapri; 1268 } 1269 /* ... begin-sequence { */ 1270 (void) ber_scanf(p8obj_asn, "{"); 1271 1272 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) { 1273 rv = CKR_WRAPPED_KEY_INVALID; 1274 goto cleanup_asn2dsapri; 1275 } 1276 /* ... OID, \* DSA algorithm OID *\ */ 1277 if (size != sizeof (DSA_OID)) { 1278 rv = CKR_FUNCTION_NOT_SUPPORTED; 1279 goto cleanup_asn2dsapri; 1280 } 1281 size = sizeof (oid); 1282 (void) ber_scanf(p8obj_asn, "s", oid, &size); 1283 if (memcmp(oid, DSA_OID, size) != 0) { 1284 rv = CKR_FUNCTION_NOT_SUPPORTED; 1285 goto cleanup_asn2dsapri; 1286 } 1287 1288 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) { 1289 rv = CKR_WRAPPED_KEY_INVALID; 1290 goto cleanup_asn2dsapri; 1291 } 1292 /* ... begin-sequence { */ 1293 (void) ber_scanf(p8obj_asn, "{"); 1294 1295 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1296 rv = CKR_WRAPPED_KEY_INVALID; 1297 goto cleanup_asn2dsapri; 1298 } 1299 /* ... prime, */ 1300 if (size > MAX_DSA_KEY) { 1301 rv = CKR_FUNCTION_NOT_SUPPORTED; 1302 goto cleanup_asn2dsapri; 1303 } 1304 tmplen = size + 1; 1305 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1306 rv = CKR_HOST_MEMORY; 1307 goto cleanup_asn2dsapri; 1308 } 1309 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen); 1310 tmp.big_value_len = tmplen; 1311 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1312 goto cleanup_asn2dsapri; 1313 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_PRIME(keyp)); 1314 1315 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1316 rv = CKR_WRAPPED_KEY_INVALID; 1317 goto error_asn2dsapri; 1318 } 1319 /* ... subprime, */ 1320 if (size > MAX_DSA_KEY) { 1321 rv = CKR_FUNCTION_NOT_SUPPORTED; 1322 goto error_asn2dsapri; 1323 } 1324 tmplen = size + 1; 1325 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1326 rv = CKR_HOST_MEMORY; 1327 goto error_asn2dsapri; 1328 } 1329 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen); 1330 tmp.big_value_len = tmplen; 1331 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1332 goto error_asn2dsapri; 1333 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_SUBPRIME(keyp)); 1334 1335 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1336 rv = CKR_WRAPPED_KEY_INVALID; 1337 goto error_asn2dsapri; 1338 } 1339 /* ... base } end-sequence } end-sequence */ 1340 if (size > MAX_DSA_KEY) { 1341 rv = CKR_FUNCTION_NOT_SUPPORTED; 1342 goto error_asn2dsapri; 1343 } 1344 tmplen = size + 1; 1345 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1346 rv = CKR_HOST_MEMORY; 1347 goto error_asn2dsapri; 1348 } 1349 (void) ber_scanf(p8obj_asn, "s", /* "s}}" ? */ 1350 tmp.big_value, &tmplen); 1351 tmp.big_value_len = tmplen; 1352 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1353 goto error_asn2dsapri; 1354 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_BASE(keyp)); 1355 1356 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) { 1357 rv = CKR_WRAPPED_KEY_INVALID; 1358 goto error_asn2dsapri; 1359 } 1360 /* ... DSAPrivateKey } end-sequence */ 1361 key_octs.bv_len = size + 1; 1362 if ((key_octs.bv_val = malloc(size + 1)) == NULL) { 1363 rv = CKR_HOST_MEMORY; 1364 goto error_asn2dsapri; 1365 } 1366 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */ 1367 key_octs.bv_val, &key_octs.bv_len); 1368 1369 /* Decode key octet string into softtoken key object. */ 1370 if ((key_asn = ber_init(&key_octs)) == NULLBER) { 1371 rv = CKR_GENERAL_ERROR; 1372 goto error_asn2dsapri; 1373 } 1374 1375 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1376 rv = CKR_WRAPPED_KEY_INVALID; 1377 goto error_asn2dsapri; 1378 } 1379 /* ... value } end-sequence */ 1380 if (size > MAX_DSA_KEY) { 1381 rv = CKR_FUNCTION_NOT_SUPPORTED; 1382 goto error_asn2dsapri; 1383 } 1384 tmplen = size + 1; 1385 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1386 rv = CKR_HOST_MEMORY; 1387 goto error_asn2dsapri; 1388 } 1389 (void) ber_scanf(key_asn, "s", /* "s}" ? */ 1390 tmp.big_value, &tmplen); 1391 tmp.big_value_len = tmplen; 1392 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1393 goto error_asn2dsapri; 1394 copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_VALUE(keyp)); 1395 1396 goto cleanup_asn2dsapri; 1397 1398 error_asn2dsapri: 1399 1400 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(keyp)); 1401 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(keyp)); 1402 bigint_attr_cleanup(KEY_PRI_DSA_BASE(keyp)); 1403 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(keyp)); 1404 1405 cleanup_asn2dsapri: 1406 1407 if (tmp_nopad.big_value != NULL) { 1408 (void) memset(tmp_nopad.big_value, 0x0, 1409 tmp_nopad.big_value_len); 1410 free(tmp_nopad.big_value); 1411 } 1412 1413 if (p8obj_asn != NULLBER) 1414 ber_free(p8obj_asn, 1); 1415 1416 if (key_octs.bv_val != NULL) 1417 free(key_octs.bv_val); 1418 1419 if (key_asn != NULLBER) 1420 ber_free(key_asn, 1); 1421 1422 return (rv); 1423 } 1424 1425 /* Decode ASN.1 BER syntax into DH private key. */ 1426 static CK_RV 1427 asn1_to_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len) 1428 { 1429 CK_RV rv = CKR_OK; 1430 BerValue p8obj_octs, key_octs; 1431 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER; 1432 ber_len_t size, tmplen; 1433 char *cookie; 1434 int version; 1435 uchar_t oid[sizeof (DH_OID) + 1]; 1436 biginteger_t tmp, tmp_nopad = { NULL, 0 }; 1437 1438 p8obj_octs.bv_val = (char *)buf; 1439 #ifdef _LP64 1440 /* LINTED E_CAST_INT_TO_SMALL_INT */ 1441 p8obj_octs.bv_len = (ber_len_t)buf_len; 1442 #else 1443 p8obj_octs.bv_len = (ber_len_t)buf_len; 1444 #endif 1445 1446 key_octs.bv_val = NULL; 1447 key_octs.bv_len = 0; 1448 1449 /* Decode PKCS#8 object ASN.1, verifying it is DH private key. */ 1450 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER) 1451 return (CKR_GENERAL_ERROR); 1452 1453 /* PKCS#8 PrivateKeyInfo ... */ 1454 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) { 1455 rv = CKR_WRAPPED_KEY_INVALID; 1456 goto cleanup_asn2dhpri; 1457 } 1458 /* ... begin-sequence { version, */ 1459 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */ 1460 1461 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) { 1462 rv = CKR_WRAPPED_KEY_INVALID; 1463 goto cleanup_asn2dhpri; 1464 } 1465 /* ... begin-sequence { */ 1466 (void) ber_scanf(p8obj_asn, "{"); 1467 1468 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) { 1469 rv = CKR_WRAPPED_KEY_INVALID; 1470 goto cleanup_asn2dhpri; 1471 } 1472 /* ... OID, \* DH algorithm OID *\ */ 1473 if (size != sizeof (DH_OID)) { 1474 rv = CKR_FUNCTION_NOT_SUPPORTED; 1475 goto cleanup_asn2dhpri; 1476 } 1477 size = sizeof (oid); 1478 (void) ber_scanf(p8obj_asn, "s", oid, &size); 1479 if (memcmp(oid, DH_OID, size) != 0) { 1480 rv = CKR_FUNCTION_NOT_SUPPORTED; 1481 goto cleanup_asn2dhpri; 1482 } 1483 1484 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) { 1485 rv = CKR_WRAPPED_KEY_INVALID; 1486 goto cleanup_asn2dhpri; 1487 } 1488 /* ... begin-sequence { */ 1489 (void) ber_scanf(p8obj_asn, "{"); 1490 1491 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1492 rv = CKR_WRAPPED_KEY_INVALID; 1493 goto cleanup_asn2dhpri; 1494 } 1495 /* ... prime, */ 1496 if (size > MAX_DH_KEY) { 1497 rv = CKR_FUNCTION_NOT_SUPPORTED; 1498 goto cleanup_asn2dhpri; 1499 } 1500 tmplen = size + 1; 1501 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1502 rv = CKR_HOST_MEMORY; 1503 goto cleanup_asn2dhpri; 1504 } 1505 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen); 1506 tmp.big_value_len = tmplen; 1507 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1508 goto cleanup_asn2dhpri; 1509 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_PRIME(keyp)); 1510 1511 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1512 rv = CKR_WRAPPED_KEY_INVALID; 1513 goto error_asn2dhpri; 1514 } 1515 /* ... base } end-sequence } end-sequence */ 1516 if (size > MAX_DH_KEY) { 1517 rv = CKR_FUNCTION_NOT_SUPPORTED; 1518 goto error_asn2dhpri; 1519 } 1520 tmplen = size + 1; 1521 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1522 rv = CKR_HOST_MEMORY; 1523 goto error_asn2dhpri; 1524 } 1525 (void) ber_scanf(p8obj_asn, "s", /* "s}}" ? */ 1526 tmp.big_value, &tmplen); 1527 tmp.big_value_len = tmplen; 1528 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1529 goto error_asn2dhpri; 1530 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_BASE(keyp)); 1531 1532 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) { 1533 rv = CKR_WRAPPED_KEY_INVALID; 1534 goto error_asn2dhpri; 1535 } 1536 /* ... DHPrivateKey } end-sequence */ 1537 key_octs.bv_len = size + 1; 1538 if ((key_octs.bv_val = malloc(size + 1)) == NULL) { 1539 rv = CKR_HOST_MEMORY; 1540 goto error_asn2dhpri; 1541 } 1542 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */ 1543 key_octs.bv_val, &key_octs.bv_len); 1544 1545 /* Decode key octet string into softtoken key object. */ 1546 if ((key_asn = ber_init(&key_octs)) == NULLBER) { 1547 rv = CKR_GENERAL_ERROR; 1548 goto error_asn2dhpri; 1549 } 1550 1551 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1552 rv = CKR_WRAPPED_KEY_INVALID; 1553 goto error_asn2dhpri; 1554 } 1555 /* ... value } end-sequence */ 1556 if (size > MAX_DH_KEY) { 1557 rv = CKR_FUNCTION_NOT_SUPPORTED; 1558 goto error_asn2dhpri; 1559 } 1560 tmplen = size + 1; 1561 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1562 rv = CKR_HOST_MEMORY; 1563 goto error_asn2dhpri; 1564 } 1565 (void) ber_scanf(key_asn, "s", /* "s}" ? */ 1566 tmp.big_value, &tmplen); 1567 tmp.big_value_len = tmplen; 1568 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1569 goto error_asn2dhpri; 1570 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_VALUE(keyp)); 1571 1572 goto cleanup_asn2dhpri; 1573 1574 error_asn2dhpri: 1575 1576 bigint_attr_cleanup(KEY_PRI_DH_PRIME(keyp)); 1577 bigint_attr_cleanup(KEY_PRI_DH_BASE(keyp)); 1578 bigint_attr_cleanup(KEY_PRI_DH_VALUE(keyp)); 1579 1580 cleanup_asn2dhpri: 1581 1582 if (tmp_nopad.big_value != NULL) { 1583 (void) memset(tmp_nopad.big_value, 0x0, 1584 tmp_nopad.big_value_len); 1585 free(tmp_nopad.big_value); 1586 } 1587 1588 if (p8obj_asn != NULLBER) 1589 ber_free(p8obj_asn, 1); 1590 1591 if (key_octs.bv_val != NULL) 1592 free(key_octs.bv_val); 1593 1594 if (key_asn != NULLBER) 1595 ber_free(key_asn, 1); 1596 1597 return (rv); 1598 } 1599 1600 /* Decode ASN.1 BER syntax into DH X9.42 private key. */ 1601 static CK_RV 1602 asn1_to_x942_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len) 1603 { 1604 CK_RV rv = CKR_OK; 1605 BerValue p8obj_octs, key_octs; 1606 BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER; 1607 ber_len_t size, tmplen; 1608 char *cookie; 1609 int version; 1610 uchar_t oid[sizeof (DH942_OID) + 1]; 1611 biginteger_t tmp, tmp_nopad = { NULL, 0 }; 1612 1613 p8obj_octs.bv_val = (char *)buf; 1614 #ifdef _LP64 1615 /* LINTED E_CAST_INT_TO_SMALL_INT */ 1616 p8obj_octs.bv_len = (ber_len_t)buf_len; 1617 #else 1618 p8obj_octs.bv_len = (ber_len_t)buf_len; 1619 #endif 1620 1621 key_octs.bv_val = NULL; 1622 key_octs.bv_len = 0; 1623 1624 /* Decode PKCS#8 object ASN.1, verifying it is DH X9.42 private key. */ 1625 if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER) 1626 return (CKR_GENERAL_ERROR); 1627 1628 /* PKCS#8 PrivateKeyInfo ... */ 1629 if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) { 1630 rv = CKR_WRAPPED_KEY_INVALID; 1631 goto cleanup_asn2x942dhpri; 1632 } 1633 /* ... begin-sequence { version, */ 1634 (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */ 1635 1636 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) { 1637 rv = CKR_WRAPPED_KEY_INVALID; 1638 goto cleanup_asn2x942dhpri; 1639 } 1640 /* ... begin-sequence { */ 1641 (void) ber_scanf(p8obj_asn, "{"); 1642 1643 if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) { 1644 rv = CKR_WRAPPED_KEY_INVALID; 1645 goto cleanup_asn2x942dhpri; 1646 } 1647 /* ... OID, \* DH X9.42 algorithm OID *\ */ 1648 if (size != sizeof (DH942_OID)) { 1649 rv = CKR_FUNCTION_NOT_SUPPORTED; 1650 goto cleanup_asn2x942dhpri; 1651 } 1652 size = sizeof (oid); 1653 (void) ber_scanf(p8obj_asn, "s", oid, &size); 1654 if (memcmp(oid, DH942_OID, size) != 0) { 1655 rv = CKR_FUNCTION_NOT_SUPPORTED; 1656 goto cleanup_asn2x942dhpri; 1657 } 1658 1659 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) { 1660 rv = CKR_WRAPPED_KEY_INVALID; 1661 goto cleanup_asn2x942dhpri; 1662 } 1663 /* ... begin-sequence { */ 1664 (void) ber_scanf(p8obj_asn, "{"); 1665 1666 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1667 rv = CKR_WRAPPED_KEY_INVALID; 1668 goto cleanup_asn2x942dhpri; 1669 } 1670 /* ... prime, */ 1671 if (size > MAX_DH942_KEY) { 1672 rv = CKR_FUNCTION_NOT_SUPPORTED; 1673 goto cleanup_asn2x942dhpri; 1674 } 1675 tmplen = size + 1; 1676 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1677 rv = CKR_HOST_MEMORY; 1678 goto cleanup_asn2x942dhpri; 1679 } 1680 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen); 1681 tmp.big_value_len = tmplen; 1682 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1683 goto cleanup_asn2x942dhpri; 1684 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_PRIME(keyp)); 1685 1686 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1687 rv = CKR_WRAPPED_KEY_INVALID; 1688 goto error_asn2x942dhpri; 1689 } 1690 /* ... base, */ 1691 if (size > MAX_DH942_KEY) { 1692 rv = CKR_FUNCTION_NOT_SUPPORTED; 1693 goto error_asn2x942dhpri; 1694 } 1695 tmplen = size + 1; 1696 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1697 rv = CKR_HOST_MEMORY; 1698 goto error_asn2x942dhpri; 1699 } 1700 (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen); 1701 tmp.big_value_len = tmplen; 1702 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1703 goto error_asn2x942dhpri; 1704 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_BASE(keyp)); 1705 1706 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) { 1707 rv = CKR_WRAPPED_KEY_INVALID; 1708 goto error_asn2x942dhpri; 1709 } 1710 /* ... subprime } end-sequence } end-sequence */ 1711 if (size > MAX_DH942_KEY) { 1712 rv = CKR_FUNCTION_NOT_SUPPORTED; 1713 goto error_asn2x942dhpri; 1714 } 1715 tmplen = size + 1; 1716 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1717 rv = CKR_HOST_MEMORY; 1718 goto error_asn2x942dhpri; 1719 } 1720 (void) ber_scanf(p8obj_asn, "s", /* "s}}" ? */ 1721 tmp.big_value, &tmplen); 1722 tmp.big_value_len = tmplen; 1723 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1724 goto error_asn2x942dhpri; 1725 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_SUBPRIME(keyp)); 1726 1727 if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) { 1728 rv = CKR_WRAPPED_KEY_INVALID; 1729 goto error_asn2x942dhpri; 1730 } 1731 /* ... DHPrivateKey } end-sequence */ 1732 key_octs.bv_len = size + 1; 1733 if ((key_octs.bv_val = malloc(size + 1)) == NULL) { 1734 rv = CKR_HOST_MEMORY; 1735 goto error_asn2x942dhpri; 1736 } 1737 (void) ber_scanf(p8obj_asn, "s", /* "s}" ? */ 1738 key_octs.bv_val, &key_octs.bv_len); 1739 1740 /* Decode key octet string into softtoken key object. */ 1741 if ((key_asn = ber_init(&key_octs)) == NULLBER) { 1742 rv = CKR_GENERAL_ERROR; 1743 goto error_asn2x942dhpri; 1744 } 1745 1746 if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) { 1747 rv = CKR_WRAPPED_KEY_INVALID; 1748 goto error_asn2x942dhpri; 1749 } 1750 /* ... value } end-sequence */ 1751 if (size > MAX_DH942_KEY) { 1752 rv = CKR_FUNCTION_NOT_SUPPORTED; 1753 goto error_asn2x942dhpri; 1754 } 1755 tmplen = size + 1; 1756 if ((tmp.big_value = malloc(tmplen)) == NULL) { 1757 rv = CKR_HOST_MEMORY; 1758 goto error_asn2x942dhpri; 1759 } 1760 (void) ber_scanf(key_asn, "s", /* "s}" ? */ 1761 tmp.big_value, &tmplen); 1762 tmp.big_value_len = tmplen; 1763 if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) 1764 goto error_asn2x942dhpri; 1765 copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_VALUE(keyp)); 1766 1767 goto cleanup_asn2x942dhpri; 1768 1769 error_asn2x942dhpri: 1770 1771 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(keyp)); 1772 bigint_attr_cleanup(KEY_PRI_DH942_BASE(keyp)); 1773 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(keyp)); 1774 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(keyp)); 1775 1776 cleanup_asn2x942dhpri: 1777 1778 if (tmp_nopad.big_value != NULL) { 1779 (void) memset(tmp_nopad.big_value, 0x0, 1780 tmp_nopad.big_value_len); 1781 free(tmp_nopad.big_value); 1782 } 1783 1784 if (p8obj_asn != NULLBER) 1785 ber_free(p8obj_asn, 1); 1786 1787 if (key_octs.bv_val != NULL) 1788 free(key_octs.bv_val); 1789 1790 if (key_asn != NULLBER) 1791 ber_free(key_asn, 1); 1792 1793 return (rv); 1794 } 1795 1796 /* 1797 * Decode the object key from ASN.1 format into soft_object_t. 1798 */ 1799 CK_RV 1800 soft_asn1_to_object(soft_object_t *objp, uchar_t *buf, ulong_t buf_len) 1801 { 1802 CK_RV rv = CKR_OK; 1803 CK_OBJECT_CLASS class = objp->class; 1804 CK_KEY_TYPE keytype = objp->key_type; 1805 private_key_obj_t *pvk; 1806 1807 switch (class) { 1808 1809 case CKO_PRIVATE_KEY: 1810 /* Allocate storage for Private Key Object. */ 1811 if ((pvk = calloc(1, sizeof (private_key_obj_t))) == NULL) { 1812 rv = CKR_HOST_MEMORY; 1813 return (rv); 1814 } 1815 1816 switch (keytype) { 1817 case CKK_RSA: 1818 rv = asn1_to_rsa_pri(pvk, buf, buf_len); 1819 break; 1820 1821 case CKK_DSA: 1822 rv = asn1_to_dsa_pri(pvk, buf, buf_len); 1823 break; 1824 1825 case CKK_DH: 1826 rv = asn1_to_dh_pri(pvk, buf, buf_len); 1827 break; 1828 1829 case CKK_X9_42_DH: 1830 rv = asn1_to_x942_dh_pri(pvk, buf, buf_len); 1831 break; 1832 1833 default: 1834 rv = CKR_FUNCTION_NOT_SUPPORTED; 1835 break; 1836 1837 } /* keytype */ 1838 1839 if (rv != CKR_OK) 1840 free(pvk); 1841 else 1842 objp->object_class_u.private_key = pvk; 1843 break; 1844 1845 default: 1846 rv = CKR_FUNCTION_NOT_SUPPORTED; 1847 break; 1848 1849 } /* class */ 1850 1851 return (rv); 1852 } 1853