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