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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <arpa/inet.h> 30 #include <errno.h> 31 #include <sys/sysmacros.h> 32 #include <netdb.h> /* hostent */ 33 #include <netinet/in.h> 34 #include <openssl/rsa.h> 35 #include <security/cryptoki.h> 36 #include <security/pkcs11.h> 37 #include <cryptoutil.h> 38 #include <stdio.h> 39 #include <strings.h> 40 #include <sys/socket.h> 41 #include <libscf.h> 42 #include <inet/kssl/kssl.h> 43 #include "kssladm.h" 44 45 void 46 usage_create(boolean_t do_print) 47 { 48 if (do_print) 49 (void) fprintf(stderr, "Usage:\n"); 50 (void) fprintf(stderr, "kssladm create" 51 " -f pkcs11 [-d softtoken_directory] -T <token_label>" 52 " -C <certificate_label> -x <proxy_port>" 53 " [-h <ca_certchain_file>]" 54 " [options] [<server_address>] [<server_port>]\n"); 55 56 (void) fprintf(stderr, "kssladm create" 57 " -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>" 58 " [options] [<server_address>] [<server_port>]\n"); 59 60 (void) fprintf(stderr, "kssladm create" 61 " -f pem -i <cert_and_key_pemfile> -x <proxy_port>" 62 " [options] [<server_address>] [<server_port>]\n"); 63 64 (void) fprintf(stderr, "options are:\n" 65 "\t[-c <ciphersuites>]\n" 66 "\t[-p <password_file>]\n" 67 "\t[-t <ssl_session_cache_timeout>]\n" 68 "\t[-z <ssl_session_cache_size>]\n" 69 "\t[-v]\n"); 70 } 71 72 static uchar_t * 73 get_cert_val(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE cert_obj, int *len) 74 { 75 CK_RV rv; 76 uchar_t *buf; 77 CK_ATTRIBUTE cert_attrs[] = {{CKA_VALUE, NULL_PTR, 0}}; 78 79 /* the certs ... */ 80 rv = C_GetAttributeValue(sess, cert_obj, cert_attrs, 1); 81 if (rv != CKR_OK) { 82 (void) fprintf(stderr, "Cannot get cert size." 83 " error = %s\n", pkcs11_strerror(rv)); 84 return (NULL); 85 } 86 87 buf = malloc(cert_attrs[0].ulValueLen); 88 if (buf == NULL) 89 return (NULL); 90 cert_attrs[0].pValue = buf; 91 92 rv = C_GetAttributeValue(sess, cert_obj, cert_attrs, 1); 93 if (rv != CKR_OK) { 94 (void) fprintf(stderr, "Cannot get cert value." 95 " error = %s\n", pkcs11_strerror(rv)); 96 free(buf); 97 return (NULL); 98 } 99 100 *len = cert_attrs[0].ulValueLen; 101 return (buf); 102 } 103 104 #define OPT_ATTR_CNT 6 105 #define MAX_ATTR_CNT 16 106 107 int known_attr_cnt = 0; 108 109 #define CKA_TOKEN_INDEX 1 110 /* 111 * The order of the attributes must stay in the same order 112 * as in the attribute template, privkey_tmpl, in load_from_pkcs11(). 113 */ 114 CK_ATTRIBUTE key_gattrs[MAX_ATTR_CNT] = { 115 {CKA_MODULUS, NULL_PTR, 0}, 116 {CKA_TOKEN, NULL_PTR, 0}, 117 {CKA_CLASS, NULL_PTR, 0}, 118 {CKA_KEY_TYPE, NULL_PTR, 0}, 119 }; 120 CK_ATTRIBUTE known_cert_attrs[1]; 121 122 /* 123 * Everything is allocated in one single contiguous buffer. 124 * The layout is the following: 125 * . the kssl_params_t structure 126 * . optional buffer containing pin (if key is non extractable) 127 * . the array of key attribute structs, (value of ck_attrs) 128 * . the key attributes values (values of ck_attrs[i].ck_value); 129 * . the array of sizes of the certificates, (referred to as sc_sizes[]) 130 * . the certificates values (referred to as sc_certs[]) 131 * 132 * The address of the certs and key attributes values are offsets 133 * from the beginning of the big buffer. sc_sizes_offset points 134 * to sc_sizes[0] and sc_certs_offset points to sc_certs[0]. 135 */ 136 static kssl_params_t * 137 pkcs11_to_kssl(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE privkey_obj, 138 boolean_t is_nxkey, int *paramsize, char *label, char *pin, int pinlen) 139 { 140 int i; 141 CK_RV rv; 142 int total_attr_cnt; 143 uint32_t cert_size, bufsize; 144 char *buf; 145 kssl_key_t *key; 146 kssl_params_t *kssl_params; 147 CK_ATTRIBUTE privkey_opt_attrs[OPT_ATTR_CNT] = { 148 {CKA_PUBLIC_EXPONENT, NULL_PTR, 0}, 149 {CKA_PRIME_1, NULL_PTR, 0}, 150 {CKA_PRIME_2, NULL_PTR, 0}, 151 {CKA_EXPONENT_1, NULL_PTR, 0}, 152 {CKA_EXPONENT_2, NULL_PTR, 0}, 153 {CKA_COEFFICIENT, NULL_PTR, 0} 154 }; 155 kssl_object_attribute_t kssl_attrs[MAX_ATTR_CNT]; 156 157 /* Get the certificate size */ 158 bufsize = sizeof (kssl_params_t); 159 cert_size = (uint32_t)known_cert_attrs[0].ulValueLen; 160 bufsize += cert_size + MAX_CHAIN_LENGTH * sizeof (uint32_t); 161 162 /* These are attributes for which we have the value and length */ 163 for (i = 0; i < known_attr_cnt; i++) { 164 bufsize += sizeof (crypto_object_attribute_t) + 165 key_gattrs[i].ulValueLen; 166 } 167 total_attr_cnt = known_attr_cnt; 168 169 if (!is_nxkey) { 170 /* Add CKA_PRIVATE_EXPONENT for extractable key */ 171 key_gattrs[total_attr_cnt].type = CKA_PRIVATE_EXPONENT; 172 key_gattrs[total_attr_cnt].pValue = NULL_PTR; 173 key_gattrs[total_attr_cnt].ulValueLen = 0; 174 175 rv = C_GetAttributeValue(sess, privkey_obj, 176 &key_gattrs[total_attr_cnt], 1); 177 if (rv != CKR_OK) { 178 (void) fprintf(stderr, 179 "Cannot get private key object attribute." 180 " error = %s\n", pkcs11_strerror(rv)); 181 return (NULL); 182 } 183 184 bufsize += sizeof (crypto_object_attribute_t) + 185 key_gattrs[total_attr_cnt].ulValueLen; 186 total_attr_cnt++; 187 } 188 189 /* 190 * Get the optional key attributes. The return values could be 191 * CKR_ATTRIBUTE_TYPE_INVALID with ulValueLen set to -1 OR 192 * CKR_OK with ulValueLen set to 0. The latter is done by 193 * soft token and seems dubious. 194 */ 195 if (!is_nxkey) { 196 rv = C_GetAttributeValue(sess, privkey_obj, privkey_opt_attrs, 197 OPT_ATTR_CNT); 198 if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) { 199 (void) fprintf(stderr, 200 "Cannot get private key object attributes." 201 " error = %s\n", pkcs11_strerror(rv)); 202 return (NULL); 203 } 204 205 for (i = 0; i < OPT_ATTR_CNT; i++) { 206 if (privkey_opt_attrs[i].ulValueLen == (CK_ULONG)-1 || 207 privkey_opt_attrs[i].ulValueLen == 0) 208 continue; 209 /* Structure copy */ 210 key_gattrs[total_attr_cnt] = privkey_opt_attrs[i]; 211 bufsize += sizeof (crypto_object_attribute_t) + 212 privkey_opt_attrs[i].ulValueLen; 213 total_attr_cnt++; 214 } 215 } else 216 bufsize += pinlen; 217 218 /* Add 4-byte cushion as sc_sizes[0] needs 32-bit alignment */ 219 bufsize += sizeof (uint32_t); 220 221 /* Now the big memory allocation */ 222 if ((buf = calloc(bufsize, 1)) == NULL) { 223 (void) fprintf(stderr, 224 "Cannot allocate memory for the kssl_params " 225 "and values\n"); 226 return (NULL); 227 } 228 229 /* LINTED */ 230 kssl_params = (kssl_params_t *)buf; 231 232 buf = (char *)(kssl_params + 1); 233 234 if (is_nxkey) { 235 kssl_params->kssl_is_nxkey = 1; 236 bcopy(label, kssl_params->kssl_token.toklabel, 237 CRYPTO_EXT_SIZE_LABEL); 238 kssl_params->kssl_token.pinlen = pinlen; 239 kssl_params->kssl_token.tokpin_offset = 240 buf - (char *)kssl_params; 241 kssl_params->kssl_token.ck_rv = 0; 242 bcopy(pin, buf, pinlen); 243 buf += pinlen; 244 } 245 246 /* the keys attributes structs array */ 247 key = &kssl_params->kssl_privkey; 248 key->ks_format = CRYPTO_KEY_ATTR_LIST; 249 key->ks_count = total_attr_cnt; 250 key->ks_attrs_offset = buf - (char *)kssl_params; 251 buf += total_attr_cnt * sizeof (kssl_object_attribute_t); 252 253 /* These are attributes for which we already have the value */ 254 for (i = 0; i < known_attr_cnt; i++) { 255 bcopy(key_gattrs[i].pValue, buf, key_gattrs[i].ulValueLen); 256 kssl_attrs[i].ka_type = key_gattrs[i].type; 257 kssl_attrs[i].ka_value_offset = buf - (char *)kssl_params; 258 kssl_attrs[i].ka_value_len = key_gattrs[i].ulValueLen; 259 buf += key_gattrs[i].ulValueLen; 260 } 261 262 if (total_attr_cnt > known_attr_cnt) { 263 /* These are attributes for which we need to get the value */ 264 for (i = known_attr_cnt; i < total_attr_cnt; i++) { 265 key_gattrs[i].pValue = buf; 266 kssl_attrs[i].ka_type = key_gattrs[i].type; 267 kssl_attrs[i].ka_value_offset = 268 buf - (char *)kssl_params; 269 kssl_attrs[i].ka_value_len = key_gattrs[i].ulValueLen; 270 buf += key_gattrs[i].ulValueLen; 271 } 272 273 rv = C_GetAttributeValue(sess, privkey_obj, 274 &key_gattrs[known_attr_cnt], 275 total_attr_cnt - known_attr_cnt); 276 if (rv != CKR_OK) { 277 (void) fprintf(stderr, 278 "Cannot get private key object attributes." 279 " error = %s\n", pkcs11_strerror(rv)); 280 return (NULL); 281 } 282 } 283 284 bcopy(kssl_attrs, ((char *)kssl_params) + key->ks_attrs_offset, 285 total_attr_cnt * sizeof (kssl_object_attribute_t)); 286 287 buf = (char *)P2ROUNDUP((uintptr_t)buf, sizeof (uint32_t)); 288 kssl_params->kssl_certs.sc_count = 1; 289 bcopy(&cert_size, buf, sizeof (uint32_t)); 290 kssl_params->kssl_certs.sc_sizes_offset = buf - (char *)kssl_params; 291 buf += MAX_CHAIN_LENGTH * sizeof (uint32_t); 292 293 /* now the certs values */ 294 bcopy(known_cert_attrs[0].pValue, buf, known_cert_attrs[0].ulValueLen); 295 free(known_cert_attrs[0].pValue); 296 kssl_params->kssl_certs.sc_certs_offset = buf - (char *)kssl_params; 297 298 *paramsize = bufsize; 299 bzero(pin, pinlen); 300 (void) C_Logout(sess); 301 (void) C_CloseSession(sess); 302 return (kssl_params); 303 } 304 305 #define max_num_cert 32 306 307 static kssl_params_t * 308 load_from_pkcs11(const char *token_label, const char *password_file, 309 const char *certname, int *bufsize) 310 { 311 static CK_BBOOL true = TRUE; 312 static CK_BBOOL false = FALSE; 313 314 CK_RV rv; 315 CK_SLOT_ID slot; 316 CK_SLOT_ID_PTR pk11_slots; 317 CK_ULONG slotcnt = 10; 318 CK_TOKEN_INFO token_info; 319 CK_SESSION_HANDLE sess; 320 static CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; 321 static CK_CERTIFICATE_TYPE cert_type = CKC_X_509; 322 CK_ATTRIBUTE cert_tmpl[4] = { 323 {CKA_TOKEN, &true, sizeof (true)}, 324 {CKA_LABEL, NULL_PTR, 0}, 325 {CKA_CLASS, &cert_class, sizeof (cert_class)}, 326 {CKA_CERTIFICATE_TYPE, &cert_type, sizeof (cert_type)} 327 }; 328 CK_ULONG cert_tmpl_count = 4, cert_obj_count = 1; 329 CK_OBJECT_HANDLE cert_obj, privkey_obj; 330 CK_OBJECT_HANDLE cert_objs[max_num_cert]; 331 static CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY; 332 static CK_KEY_TYPE privkey_type = CKK_RSA; 333 CK_ATTRIBUTE privkey_tmpl[] = { 334 /* 335 * The order of attributes must stay in the same order 336 * as in the global attribute array, key_gattrs. 337 */ 338 {CKA_MODULUS, NULL_PTR, 0}, 339 {CKA_TOKEN, &true, sizeof (true)}, 340 {CKA_CLASS, &privkey_class, sizeof (privkey_class)}, 341 {CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)} 342 }; 343 CK_ULONG privkey_tmpl_count = 4, privkey_obj_count = 1; 344 CK_BBOOL is_extractable; 345 CK_ATTRIBUTE privkey_attrs[1] = { 346 {CKA_EXTRACTABLE, NULL_PTR, 0}, 347 }; 348 boolean_t bingo = B_FALSE; 349 int i, blen, mlen; 350 uchar_t *mval, *ber_buf; 351 char token_label_padded[sizeof (token_info.label) + 1]; 352 char passphrase[MAX_PIN_LENGTH]; 353 CK_ULONG ulPinLen; 354 355 (void) snprintf(token_label_padded, sizeof (token_label_padded), 356 "%-32s", token_label); 357 358 rv = C_Initialize(NULL_PTR); 359 360 if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 361 (void) fprintf(stderr, 362 "Cannot initialize PKCS#11. error = %s\n", 363 pkcs11_strerror(rv)); 364 return (NULL); 365 } 366 367 /* Get slot count */ 368 rv = C_GetSlotList(1, NULL_PTR, &slotcnt); 369 if (rv != CKR_OK || slotcnt == 0) { 370 (void) fprintf(stderr, 371 "Cannot get PKCS#11 slot list. error = %s\n", 372 pkcs11_strerror(rv)); 373 return (NULL); 374 } 375 376 pk11_slots = calloc(slotcnt, sizeof (CK_SLOT_ID)); 377 if (pk11_slots == NULL) { 378 (void) fprintf(stderr, 379 "Cannot get memory for %ld slots\n", slotcnt); 380 return (NULL); 381 } 382 383 rv = C_GetSlotList(1, pk11_slots, &slotcnt); 384 if (rv != CKR_OK) { 385 (void) fprintf(stderr, 386 "Cannot get PKCS#11 slot list. error = %s\n", 387 pkcs11_strerror(rv)); 388 return (NULL); 389 } 390 391 if (verbose) 392 (void) printf("Found %ld slots\n", slotcnt); 393 394 /* Search the token that matches the label */ 395 while (slotcnt > 0) { 396 rv = C_GetTokenInfo(pk11_slots[--slotcnt], &token_info); 397 if (rv != CKR_OK) 398 continue; 399 400 if (verbose) 401 (void) printf("slot [%ld] = %s\n", 402 slotcnt, token_info.label); 403 if (memcmp(token_label_padded, token_info.label, 404 sizeof (token_info.label)) == 0) { 405 bingo = B_TRUE; 406 slot = pk11_slots[slotcnt]; 407 break; 408 } 409 if (verbose) { 410 token_info.label[31] = '\0'; 411 (void) printf("found slot [%s]\n", token_info.label); 412 } 413 } 414 415 if (!bingo) { 416 (void) fprintf(stderr, "no matching PKCS#11 token found\n"); 417 return (NULL); 418 } 419 420 rv = C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, 421 &sess); 422 if (rv != CKR_OK) { 423 (void) fprintf(stderr, "Cannot open session. error = %s\n", 424 pkcs11_strerror(rv)); 425 return (NULL); 426 } 427 428 /* 429 * Some tokens may not be setting CKF_LOGIN_REQUIRED. So, we do 430 * not check for this flag and always login to be safe. 431 */ 432 ulPinLen = get_passphrase(password_file, passphrase, 433 sizeof (passphrase)); 434 if (ulPinLen == 0) { 435 (void) fprintf(stderr, "Unable to read passphrase"); 436 return (NULL); 437 } 438 439 rv = C_Login(sess, CKU_USER, (CK_UTF8CHAR_PTR)passphrase, 440 ulPinLen); 441 if (rv != CKR_OK) { 442 (void) fprintf(stderr, "Cannot login to the token." 443 " error = %s\n", pkcs11_strerror(rv)); 444 return (NULL); 445 } 446 447 cert_tmpl[1].pValue = (CK_VOID_PTR) certname; 448 cert_tmpl[1].ulValueLen = strlen(certname); 449 450 rv = C_FindObjectsInit(sess, cert_tmpl, cert_tmpl_count); 451 if (rv != CKR_OK) { 452 (void) fprintf(stderr, 453 "Cannot initialize cert search." 454 " error = %s\n", pkcs11_strerror(rv)); 455 return (NULL); 456 } 457 458 rv = C_FindObjects(sess, cert_objs, 459 (certname == NULL ? 1 : max_num_cert), &cert_obj_count); 460 if (rv != CKR_OK) { 461 (void) fprintf(stderr, 462 "Cannot retrieve cert object. error = %s\n", 463 pkcs11_strerror(rv)); 464 return (NULL); 465 } 466 467 /* Who cares if this fails! */ 468 (void) C_FindObjectsFinal(sess); 469 if (verbose) 470 (void) printf("found %ld certificates\n", cert_obj_count); 471 472 if (cert_obj_count == 0) { 473 (void) fprintf(stderr, "\"%s\" not found.\n", certname); 474 (void) fprintf(stderr, "no certs. bye.\n"); 475 return (NULL); 476 } 477 478 cert_obj = cert_objs[0]; 479 480 /* Get the modulus value from the certificate */ 481 ber_buf = get_cert_val(sess, cert_obj, &blen); 482 if (ber_buf == NULL) { 483 (void) fprintf(stderr, 484 "Cannot get certificate data for \"%s\".\n", certname); 485 return (NULL); 486 } 487 488 /* Store it for later use. We free the buffer at that time. */ 489 known_cert_attrs[0].type = CKA_VALUE; 490 known_cert_attrs[0].pValue = ber_buf; 491 known_cert_attrs[0].ulValueLen = blen; 492 493 mval = get_modulus(ber_buf, blen, &mlen); 494 if (mval == NULL) { 495 (void) fprintf(stderr, 496 "Cannot get Modulus in certificate \"%s\".\n", certname); 497 return (NULL); 498 } 499 500 /* Now get the private key */ 501 privkey_tmpl[0].pValue = mval; 502 privkey_tmpl[0].ulValueLen = mlen; 503 504 rv = C_FindObjectsInit(sess, privkey_tmpl, privkey_tmpl_count); 505 if (rv != CKR_OK) { 506 (void) fprintf(stderr, "Cannot intialize private key search." 507 " error = %s\n", pkcs11_strerror(rv)); 508 return (NULL); 509 } 510 511 rv = C_FindObjects(sess, &privkey_obj, 1, &privkey_obj_count); 512 if (rv != CKR_OK) { 513 (void) fprintf(stderr, "Cannot retrieve private key object " 514 " error = %s\n", pkcs11_strerror(rv)); 515 return (NULL); 516 } 517 /* Who cares if this fails! */ 518 (void) C_FindObjectsFinal(sess); 519 520 if (privkey_obj_count == 0) { 521 (void) fprintf(stderr, "no private keys. bye.\n"); 522 return (NULL); 523 } 524 525 (void) printf("found %ld private keys\n", privkey_obj_count); 526 if (verbose) { 527 (void) printf("private key attributes: \n"); 528 (void) printf("\tmodulus: size %d \n", mlen); 529 } 530 531 /* 532 * Store it for later use. The index of the attributes 533 * is the same in both the structures. 534 */ 535 known_attr_cnt = privkey_tmpl_count; 536 for (i = 0; i < privkey_tmpl_count; i++) 537 key_gattrs[i] = privkey_tmpl[i]; 538 539 /* 540 * Get CKA_EXTRACTABLE value. We set the default value 541 * TRUE if the token returns CKR_ATTRIBUTE_TYPE_INVALID. 542 * The token would supply this attribute if the key 543 * is not extractable. 544 */ 545 privkey_attrs[0].pValue = &is_extractable; 546 privkey_attrs[0].ulValueLen = sizeof (is_extractable); 547 rv = C_GetAttributeValue(sess, privkey_obj, privkey_attrs, 1); 548 if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) { 549 (void) fprintf(stderr, 550 "Cannot get CKA_EXTRACTABLE attribute." 551 " error = %s\n", pkcs11_strerror(rv)); 552 return (NULL); 553 } 554 555 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) 556 is_extractable = TRUE; 557 key_gattrs[known_attr_cnt++] = privkey_attrs[0]; 558 559 if (is_extractable) { 560 /* Now wrap the key, then unwrap it */ 561 CK_BYTE aes_key_val[16] = { 562 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 563 static CK_BYTE aes_param[16] = { 564 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 565 CK_MECHANISM aes_cbc_pad_mech = {CKM_AES_CBC_PAD, aes_param, 16}; 566 CK_OBJECT_HANDLE aes_key_obj, sess_privkey_obj; 567 CK_BYTE *wrapped_privkey; 568 CK_ULONG wrapped_privkey_len; 569 570 CK_ATTRIBUTE unwrap_tmpl[] = { 571 /* code below depends on the following attribute order */ 572 {CKA_TOKEN, &false, sizeof (false)}, 573 {CKA_CLASS, &privkey_class, sizeof (privkey_class)}, 574 {CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)}, 575 {CKA_SENSITIVE, &false, sizeof (false)}, 576 {CKA_PRIVATE, &false, sizeof (false)} 577 }; 578 579 rv = SUNW_C_KeyToObject(sess, CKM_AES_CBC_PAD, aes_key_val, 16, 580 &aes_key_obj); 581 582 if (rv != CKR_OK) { 583 (void) fprintf(stderr, 584 "Cannot create wrapping key. error = %s\n", 585 pkcs11_strerror(rv)); 586 return (NULL); 587 } 588 589 /* get the size of the wrapped key */ 590 rv = C_WrapKey(sess, &aes_cbc_pad_mech, aes_key_obj, privkey_obj, 591 NULL, &wrapped_privkey_len); 592 if (rv != CKR_OK) { 593 (void) fprintf(stderr, "Cannot get key size. error = %s\n", 594 pkcs11_strerror(rv)); 595 return (NULL); 596 } 597 598 wrapped_privkey = malloc(wrapped_privkey_len * sizeof (CK_BYTE)); 599 if (wrapped_privkey == NULL) { 600 return (NULL); 601 } 602 603 /* do the actual key wrapping */ 604 rv = C_WrapKey(sess, &aes_cbc_pad_mech, aes_key_obj, privkey_obj, 605 wrapped_privkey, &wrapped_privkey_len); 606 if (rv != CKR_OK) { 607 (void) fprintf(stderr, "Cannot wrap private key. error = %s\n", 608 pkcs11_strerror(rv)); 609 return (NULL); 610 } 611 (void) printf("private key successfully wrapped, " 612 "wrapped blob length: %ld\n", 613 wrapped_privkey_len); 614 615 rv = C_UnwrapKey(sess, &aes_cbc_pad_mech, aes_key_obj, 616 wrapped_privkey, wrapped_privkey_len, 617 unwrap_tmpl, 5, &sess_privkey_obj); 618 if (rv != CKR_OK) { 619 (void) fprintf(stderr, "Cannot unwrap private key." 620 " error = %s\n", pkcs11_strerror(rv)); 621 return (NULL); 622 } 623 (void) printf("session private key successfully unwrapped\n"); 624 625 privkey_obj = sess_privkey_obj; 626 /* Store the one modified attribute and the two new attributes. */ 627 key_gattrs[CKA_TOKEN_INDEX] = unwrap_tmpl[0]; 628 key_gattrs[known_attr_cnt++] = unwrap_tmpl[3]; 629 key_gattrs[known_attr_cnt++] = unwrap_tmpl[4]; 630 } 631 632 return (pkcs11_to_kssl(sess, privkey_obj, !is_extractable, bufsize, 633 token_label_padded, passphrase, ulPinLen)); 634 } 635 636 #define MAX_OPENSSL_ATTR_CNT 8 637 638 /* 639 * See the comments for pkcs11_to_kssl() for the layout of the 640 * returned buffer. 641 */ 642 static kssl_params_t * 643 openssl_to_kssl(RSA *rsa, int ncerts, uchar_t *cert_bufs[], int *cert_sizes, 644 int *paramsize) 645 { 646 int i, tcsize; 647 kssl_params_t *kssl_params; 648 kssl_key_t *key; 649 char *buf; 650 uint32_t bufsize; 651 kssl_object_attribute_t kssl_attrs[MAX_OPENSSL_ATTR_CNT]; 652 kssl_object_attribute_t kssl_tmpl_attrs[MAX_OPENSSL_ATTR_CNT] = { 653 {SUN_CKA_MODULUS, NULL, 0}, 654 {SUN_CKA_PUBLIC_EXPONENT, NULL, 0}, 655 {SUN_CKA_PRIVATE_EXPONENT, NULL, 0}, 656 {SUN_CKA_PRIME_1, NULL, 0}, 657 {SUN_CKA_PRIME_2, NULL, 0}, 658 {SUN_CKA_EXPONENT_1, NULL, 0}, 659 {SUN_CKA_EXPONENT_2, NULL, 0}, 660 {SUN_CKA_COEFFICIENT, NULL, 0} 661 }; 662 BIGNUM *priv_key_bignums[MAX_OPENSSL_ATTR_CNT]; 663 int attr_cnt; 664 665 tcsize = 0; 666 for (i = 0; i < ncerts; i++) 667 tcsize += cert_sizes[i]; 668 669 bufsize = sizeof (kssl_params_t); 670 bufsize += (tcsize + MAX_CHAIN_LENGTH * sizeof (uint32_t)); 671 672 /* and the key attributes */ 673 priv_key_bignums[0] = rsa->n; /* MODULUS */ 674 priv_key_bignums[1] = rsa->e; /* PUBLIC_EXPONENT */ 675 priv_key_bignums[2] = rsa->d; /* PRIVATE_EXPONENT */ 676 priv_key_bignums[3] = rsa->p; /* PRIME_1 */ 677 priv_key_bignums[4] = rsa->q; /* PRIME_2 */ 678 priv_key_bignums[5] = rsa->dmp1; /* EXPONENT_1 */ 679 priv_key_bignums[6] = rsa->dmq1; /* EXPONENT_2 */ 680 priv_key_bignums[7] = rsa->iqmp; /* COEFFICIENT */ 681 682 if (rsa->n == NULL || rsa->d == NULL) { 683 (void) fprintf(stderr, 684 "missing required attributes in private key.\n"); 685 return (NULL); 686 } 687 688 attr_cnt = 0; 689 for (i = 0; i < MAX_OPENSSL_ATTR_CNT; i++) { 690 if (priv_key_bignums[i] == NULL) 691 continue; 692 kssl_attrs[attr_cnt].ka_type = kssl_tmpl_attrs[i].ka_type; 693 kssl_attrs[attr_cnt].ka_value_len = 694 BN_num_bytes(priv_key_bignums[i]); 695 bufsize += sizeof (crypto_object_attribute_t) + 696 kssl_attrs[attr_cnt].ka_value_len; 697 attr_cnt++; 698 } 699 700 /* Add 4-byte cushion as sc_sizes[0] needs 32-bit alignment */ 701 bufsize += sizeof (uint32_t); 702 703 /* Now the big memory allocation */ 704 if ((buf = calloc(bufsize, 1)) == NULL) { 705 (void) fprintf(stderr, 706 "Cannot allocate memory for the kssl_params " 707 "and values\n"); 708 return (NULL); 709 } 710 711 /* LINTED */ 712 kssl_params = (kssl_params_t *)buf; 713 714 buf = (char *)(kssl_params + 1); 715 716 /* the keys attributes structs array */ 717 key = &kssl_params->kssl_privkey; 718 key->ks_format = CRYPTO_KEY_ATTR_LIST; 719 key->ks_count = attr_cnt; 720 key->ks_attrs_offset = buf - (char *)kssl_params; 721 buf += attr_cnt * sizeof (kssl_object_attribute_t); 722 723 attr_cnt = 0; 724 /* then the key attributes values */ 725 for (i = 0; i < MAX_OPENSSL_ATTR_CNT; i++) { 726 if (priv_key_bignums[i] == NULL) 727 continue; 728 (void) BN_bn2bin(priv_key_bignums[i], (unsigned char *)buf); 729 kssl_attrs[attr_cnt].ka_value_offset = 730 buf - (char *)kssl_params; 731 buf += kssl_attrs[attr_cnt].ka_value_len; 732 attr_cnt++; 733 } 734 735 bcopy(kssl_attrs, ((char *)kssl_params) + key->ks_attrs_offset, 736 attr_cnt * sizeof (kssl_object_attribute_t)); 737 738 buf = (char *)P2ROUNDUP((uintptr_t)buf, sizeof (uint32_t)); 739 kssl_params->kssl_certs.sc_count = ncerts; 740 bcopy(cert_sizes, buf, ncerts * sizeof (uint32_t)); 741 kssl_params->kssl_certs.sc_sizes_offset = buf - (char *)kssl_params; 742 buf += MAX_CHAIN_LENGTH * sizeof (uint32_t); 743 744 kssl_params->kssl_certs.sc_certs_offset = buf - (char *)kssl_params; 745 /* now the certs values */ 746 for (i = 0; i < ncerts; i++) { 747 bcopy(cert_bufs[i], buf, cert_sizes[i]); 748 buf += cert_sizes[i]; 749 } 750 751 *paramsize = bufsize; 752 return (kssl_params); 753 } 754 755 static kssl_params_t * 756 add_cacerts(kssl_params_t *old_params, const char *cacert_chain_file, 757 const char *password_file) 758 { 759 int i, ncerts, newlen; 760 int *cert_sizes; 761 uint32_t certlen = 0; 762 char *buf; 763 uchar_t **cert_bufs; 764 kssl_params_t *kssl_params; 765 766 ncerts = 0; 767 cert_bufs = PEM_get_rsa_key_certs(cacert_chain_file, 768 (char *)password_file, NULL, &cert_sizes, &ncerts); 769 if (cert_bufs == NULL || ncerts == 0) { 770 bzero(old_params, old_params->kssl_params_size); 771 free(old_params); 772 return (NULL); 773 } 774 775 if (verbose) { 776 (void) printf("%d certificates read successfully\n", ncerts); 777 } 778 779 newlen = old_params->kssl_params_size; 780 for (i = 0; i < ncerts; i++) 781 newlen += cert_sizes[i]; 782 783 /* 784 * Get a bigger structure and update the 785 * fields to account for the additional certs. 786 */ 787 kssl_params = realloc(old_params, newlen); 788 789 kssl_params->kssl_params_size = newlen; 790 kssl_params->kssl_certs.sc_count += ncerts; 791 792 /* Put the cert_sizes starting from sc_sizes[1] */ 793 buf = (char *)kssl_params; 794 buf += kssl_params->kssl_certs.sc_sizes_offset; 795 bcopy(buf, &certlen, sizeof (uint32_t)); 796 buf += sizeof (uint32_t); 797 bcopy(cert_sizes, buf, ncerts * sizeof (uint32_t)); 798 799 /* Put the cert_bufs starting from sc_certs[1] */ 800 buf = (char *)kssl_params; 801 buf += kssl_params->kssl_certs.sc_certs_offset; 802 buf += certlen; 803 804 /* now the certs values */ 805 for (i = 0; i < ncerts; i++) { 806 bcopy(cert_bufs[i], buf, cert_sizes[i]); 807 buf += cert_sizes[i]; 808 } 809 810 for (i = 0; i < ncerts; i++) 811 free(cert_bufs[i]); 812 free(cert_bufs); 813 free(cert_sizes); 814 815 return (kssl_params); 816 } 817 818 static kssl_params_t * 819 load_from_pem(const char *filename, const char *password_file, int *paramsize) 820 { 821 uchar_t **cert_bufs; 822 int *cert_sizes, ncerts, i; 823 RSA *rsa; 824 kssl_params_t *kssl_params; 825 826 ncerts = 0; 827 cert_bufs = PEM_get_rsa_key_certs(filename, (char *)password_file, 828 &rsa, &cert_sizes, &ncerts); 829 if (rsa == NULL || cert_bufs == NULL || ncerts == 0) { 830 return (NULL); 831 } 832 833 if (verbose) 834 (void) printf("%d certificates read successfully\n", ncerts); 835 836 kssl_params = openssl_to_kssl(rsa, ncerts, cert_bufs, 837 cert_sizes, paramsize); 838 839 for (i = 0; i < ncerts; i++) 840 free(cert_bufs[i]); 841 free(cert_bufs); 842 free(cert_sizes); 843 RSA_free(rsa); 844 return (kssl_params); 845 } 846 847 static kssl_params_t * 848 load_from_pkcs12(const char *filename, const char *password_file, 849 int *paramsize) 850 { 851 RSA *rsa; 852 kssl_params_t *kssl_params; 853 uchar_t **cert_bufs; 854 int *cert_sizes, ncerts, i; 855 856 ncerts = 0; 857 cert_bufs = PKCS12_get_rsa_key_certs(filename, password_file, &rsa, 858 &cert_sizes, &ncerts); 859 if (cert_bufs == NULL || ncerts == 0) { 860 (void) fprintf(stderr, 861 "Unable to read cert and/or key from %s\n", filename); 862 return (NULL); 863 } 864 865 if (verbose) 866 (void) printf("%d certificates read successfully\n", ncerts); 867 868 kssl_params = openssl_to_kssl(rsa, ncerts, cert_bufs, 869 cert_sizes, paramsize); 870 871 for (i = 0; i < ncerts; i++) 872 free(cert_bufs[i]); 873 free(cert_bufs); 874 free(cert_sizes); 875 876 RSA_free(rsa); 877 return (kssl_params); 878 } 879 880 881 int 882 parse_and_set_addr(char *server_address, char *server_port, 883 struct sockaddr_in *addr) 884 { 885 if (server_port == NULL) { 886 return (-1); 887 } 888 889 if (server_address == NULL) { 890 addr->sin_addr.s_addr = INADDR_ANY; 891 } else { 892 addr->sin_addr.s_addr = inet_addr(server_address); 893 if ((int)addr->sin_addr.s_addr == -1) { 894 struct hostent *hp; 895 896 if ((hp = gethostbyname(server_address)) == NULL) { 897 (void) fprintf(stderr, 898 "Error: Unknown host: %s\n", 899 server_address); 900 return (-1); 901 } 902 903 (void) memcpy(&addr->sin_addr.s_addr, 904 hp->h_addr_list[0], 905 sizeof (addr->sin_addr.s_addr)); 906 } 907 } 908 909 errno = 0; 910 addr->sin_port = strtol(server_port, NULL, 10); 911 if (addr->sin_port == 0 || errno != 0) { 912 (void) fprintf(stderr, "Error: Invalid Port value: %s\n", 913 server_port); 914 return (-1); 915 } 916 917 return (0); 918 } 919 920 /* 921 * The order of the ciphers is important. It is used as the 922 * default order (when -c is not specified). 923 */ 924 struct csuite { 925 const char *suite; 926 uint16_t val; 927 boolean_t seen; 928 } cipher_suites[CIPHER_SUITE_COUNT - 1] = { 929 {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, B_FALSE}, 930 {"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5, B_FALSE}, 931 {"rsa_3des_ede_cbc_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, B_FALSE}, 932 {"rsa_des_cbc_sha", SSL_RSA_WITH_DES_CBC_SHA, B_FALSE}, 933 }; 934 935 static int 936 check_suites(char *suites, uint16_t *sarray) 937 { 938 int i; 939 int err = 0; 940 char *suite; 941 int sindx = 0; 942 943 if (suites != NULL) { 944 for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) 945 sarray[i] = CIPHER_NOTSET; 946 } else { 947 for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) 948 sarray[i] = cipher_suites[i].val; 949 return (err); 950 } 951 952 suite = strtok(suites, ","); 953 do { 954 for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) { 955 if (strcasecmp(suite, cipher_suites[i].suite) == 0) { 956 if (!cipher_suites[i].seen) { 957 sarray[sindx++] = cipher_suites[i].val; 958 cipher_suites[i].seen = B_TRUE; 959 } 960 break; 961 } 962 } 963 964 if (i == (CIPHER_SUITE_COUNT - 1)) { 965 (void) fprintf(stderr, 966 "Unknown Cipher suite name: %s\n", suite); 967 err++; 968 } 969 } while ((suite = strtok(NULL, ",")) != NULL); 970 971 return (err); 972 } 973 974 int 975 do_create(int argc, char *argv[]) 976 { 977 const char *softtoken_dir = NULL; 978 const char *token_label = NULL; 979 const char *password_file = NULL; 980 const char *cert_key_file = NULL; 981 const char *cacert_chain_file = NULL; 982 const char *certname = NULL; 983 char *suites = NULL; 984 uint32_t timeout = DEFAULT_SID_TIMEOUT; 985 uint32_t scache_size = DEFAULT_SID_CACHE_NENTRIES; 986 uint16_t kssl_suites[CIPHER_SUITE_COUNT - 1]; 987 int proxy_port = -1; 988 struct sockaddr_in server_addr; 989 char *format = NULL; 990 char *port, *addr; 991 char c; 992 int pcnt; 993 kssl_params_t *kssl_params; 994 int bufsize; 995 996 argc -= 1; 997 argv += 1; 998 999 while ((c = getopt(argc, argv, "vT:d:f:h:i:p:c:C:t:x:z:")) != -1) { 1000 switch (c) { 1001 case 'd': 1002 softtoken_dir = optarg; 1003 break; 1004 case 'c': 1005 suites = optarg; 1006 break; 1007 case 'C': 1008 certname = optarg; 1009 break; 1010 case 'f': 1011 format = optarg; 1012 break; 1013 case 'h': 1014 cacert_chain_file = optarg; 1015 break; 1016 case 'i': 1017 cert_key_file = optarg; 1018 break; 1019 case 'T': 1020 token_label = optarg; 1021 break; 1022 case 'p': 1023 password_file = optarg; 1024 break; 1025 case 't': 1026 timeout = atoi(optarg); 1027 break; 1028 case 'x': 1029 proxy_port = atoi(optarg); 1030 break; 1031 case 'v': 1032 verbose = B_TRUE; 1033 break; 1034 case 'z': 1035 scache_size = atoi(optarg); 1036 break; 1037 default: 1038 goto err; 1039 } 1040 } 1041 1042 pcnt = argc - optind; 1043 if (pcnt == 0) { 1044 port = "443"; /* default SSL port */ 1045 addr = NULL; 1046 } else if (pcnt == 1) { 1047 port = argv[optind]; 1048 addr = NULL; 1049 } else if (pcnt == 2) { 1050 addr = argv[optind]; 1051 port = argv[optind + 1]; 1052 } else { 1053 goto err; 1054 } 1055 1056 if (parse_and_set_addr(addr, port, &server_addr) < 0) { 1057 goto err; 1058 } 1059 1060 if (verbose) { 1061 (void) printf("addr=%s, port = %d\n", 1062 inet_ntoa(server_addr.sin_addr), server_addr.sin_port); 1063 } 1064 1065 if (format == NULL || proxy_port == -1) { 1066 goto err; 1067 } 1068 1069 if (check_suites(suites, kssl_suites) != 0) { 1070 goto err; 1071 } 1072 1073 if (strcmp(format, "pkcs11") == 0) { 1074 if (token_label == NULL || certname == NULL) { 1075 goto err; 1076 } 1077 if (softtoken_dir != NULL) { 1078 (void) setenv("SOFTTOKEN_DIR", softtoken_dir, 1); 1079 if (verbose) { 1080 (void) printf( 1081 "SOFTTOKEN_DIR=%s\n", 1082 getenv("SOFTTOKEN_DIR")); 1083 } 1084 } 1085 kssl_params = load_from_pkcs11( 1086 token_label, password_file, certname, &bufsize); 1087 } else if (strcmp(format, "pkcs12") == 0) { 1088 if (cert_key_file == NULL) { 1089 goto err; 1090 } 1091 kssl_params = load_from_pkcs12( 1092 cert_key_file, password_file, &bufsize); 1093 } else if (strcmp(format, "pem") == 0) { 1094 if (cert_key_file == NULL) { 1095 goto err; 1096 } 1097 kssl_params = load_from_pem( 1098 cert_key_file, password_file, &bufsize); 1099 } else { 1100 (void) fprintf(stderr, "Unsupported cert format: %s\n", format); 1101 goto err; 1102 } 1103 1104 if (kssl_params == NULL) { 1105 return (FAILURE); 1106 } 1107 1108 bcopy(kssl_suites, kssl_params->kssl_suites, 1109 sizeof (kssl_params->kssl_suites)); 1110 kssl_params->kssl_params_size = bufsize; 1111 kssl_params->kssl_addr = server_addr; 1112 kssl_params->kssl_session_cache_timeout = timeout; 1113 kssl_params->kssl_proxy_port = proxy_port; 1114 kssl_params->kssl_session_cache_size = scache_size; 1115 1116 if (cacert_chain_file != NULL) { 1117 kssl_params = add_cacerts(kssl_params, cacert_chain_file, 1118 password_file); 1119 if (kssl_params == NULL) { 1120 return (FAILURE); 1121 } 1122 } 1123 1124 if (kssl_send_command((char *)kssl_params, KSSL_ADD_ENTRY) < 0) { 1125 int err = CRYPTO_FAILED; 1126 1127 if (kssl_params->kssl_is_nxkey) 1128 err = kssl_params->kssl_token.ck_rv; 1129 (void) fprintf(stderr, 1130 "Error loading cert and key: 0x%x\n", err); 1131 return (FAILURE); 1132 } 1133 1134 if (verbose) 1135 (void) printf("Successfully loaded cert and key\n"); 1136 1137 bzero(kssl_params, bufsize); 1138 free(kssl_params); 1139 return (SUCCESS); 1140 1141 err: 1142 usage_create(B_TRUE); 1143 return (SMF_EXIT_ERR_CONFIG); 1144 } 1145