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