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