1 /* 2 * ==================================================================== 3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * licensing@OpenSSL.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@cryptsoft.com). 53 * 54 */ 55 56 /* 57 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 58 * Use is subject to license terms. 59 */ 60 61 /* 62 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. 63 */ 64 65 #pragma ident "%Z%%M% %I% %E% SMI" 66 67 #include <stdio.h> 68 #include <strings.h> 69 #include <stdlib.h> 70 71 #include <openssl/crypto.h> 72 #include <openssl/err.h> 73 #include <openssl/x509.h> 74 #include <openssl/ssl.h> 75 76 #include <openssl/pkcs12.h> 77 #include <p12aux.h> 78 #include <auxutil.h> 79 #include <p12err.h> 80 81 /* 82 * sunw_cryto_init() does crypto-specific initialization. 83 * 84 * Arguments: 85 * None. 86 * 87 * Returns: 88 * None. 89 */ 90 void 91 sunw_crypto_init(void) 92 { 93 OpenSSL_add_all_algorithms(); 94 SSL_load_error_strings(); 95 ERR_load_SUNW_strings(); 96 (void) SSL_library_init(); 97 } 98 99 /* 100 * sunw_split_certs() - Given a list of certs and a list of private keys, 101 * moves certs which match one of the keys to a different stack. 102 * 103 * Arguments: 104 * allkeys - Points to a stack of private keys to search. 105 * allcerts - Points to a stack of certs to be searched. 106 * keycerts - Points to address of a stack of certs with matching private 107 * keys. They are moved from 'allcerts'. This may not be NULL 108 * when called. If *keycerts is NULL upon entry, a new stack will 109 * be allocated. Otherwise, it must be a valid STACK_OF(509). 110 * nocerts - Points to address of a stack for keys which have no matching 111 * certs. Keys are moved from 'allkeys' here when they have no 112 * matching certs. If this is NULL, matchless keys will be 113 * discarded. 114 * 115 * Notes: If an error occurs while moving certs, the cert being move may be 116 * lost. 'keycerts' may only contain part of the matching certs. The number 117 * of certs successfully moved can be found by checking sk_X509_num(keycerts). 118 * 119 * If there is a key which does not have a matching cert, it is moved to 120 * the list nocerts. 121 * 122 * If all certs are removed from 'certs' and/or 'pkeys', it will be the 123 * caller's responsibility to free the empty stacks. 124 * 125 * Returns: 126 * < 0 - An error returned. Call ERR_get_error() to get errors information. 127 * Where possible, memory has been freed. 128 * >= 0 - The number of certs moved from 'cert' to 'pkcerts'. 129 */ 130 int 131 sunw_split_certs(STACK_OF(EVP_PKEY) *allkeys, STACK_OF(X509) *allcerts, 132 STACK_OF(X509) **keycerts, STACK_OF(EVP_PKEY) **nocerts) 133 { 134 STACK_OF(X509) *matching; 135 STACK_OF(EVP_PKEY) *nomatch; 136 EVP_PKEY *tmpkey; 137 X509 *tmpcert; 138 int count = 0; 139 int found; 140 int res; 141 int i; 142 int k; 143 144 *keycerts = NULL; 145 if (nocerts != NULL) 146 *nocerts = NULL; 147 nomatch = NULL; 148 149 if ((matching = sk_X509_new_null()) == NULL) { 150 SUNWerr(SUNW_F_SPLIT_CERTS, SUNW_R_MEMORY_FAILURE); 151 return (-1); 152 } 153 *keycerts = matching; 154 155 k = 0; 156 while (k < sk_EVP_PKEY_num(allkeys)) { 157 found = 0; 158 tmpkey = sk_EVP_PKEY_value(allkeys, k); 159 160 for (i = 0; i < sk_X509_num(allcerts); i++) { 161 tmpcert = sk_X509_value(allcerts, i); 162 res = X509_check_private_key(tmpcert, tmpkey); 163 if (res != 0) { 164 count++; 165 found = 1; 166 tmpcert = sk_X509_delete(allcerts, i); 167 if (sk_X509_push(matching, tmpcert) == 0) { 168 X509_free(tmpcert); 169 SUNWerr(SUNW_F_SPLIT_CERTS, 170 SUNW_R_MEMORY_FAILURE); 171 return (-1); 172 } 173 break; 174 } 175 } 176 if (found != 0) { 177 /* 178 * Found a match - keep the key & check out the next 179 * one. 180 */ 181 k++; 182 } else { 183 /* 184 * No cert matching this key. Move the key if 185 * possible or discard it. Don't increment the 186 * index. 187 */ 188 if (nocerts == NULL) { 189 tmpkey = sk_EVP_PKEY_delete(allkeys, k); 190 sunw_evp_pkey_free(tmpkey); 191 } else { 192 if (*nocerts == NULL) { 193 nomatch = sk_EVP_PKEY_new_null(); 194 if (nomatch == NULL) { 195 SUNWerr(SUNW_F_SPLIT_CERTS, 196 SUNW_R_MEMORY_FAILURE); 197 return (-1); 198 } 199 *nocerts = nomatch; 200 } 201 tmpkey = sk_EVP_PKEY_delete(allkeys, k); 202 if (sk_EVP_PKEY_push(nomatch, tmpkey) == 0) { 203 sunw_evp_pkey_free(tmpkey); 204 SUNWerr(SUNW_F_SPLIT_CERTS, 205 SUNW_R_MEMORY_FAILURE); 206 return (-1); 207 } 208 } 209 } 210 } 211 212 return (count); 213 } 214 215 /* 216 * sunw_evp_pkey_free() Given an EVP_PKEY structure, free any attributes 217 * that are attached. Then free the EVP_PKEY itself. 218 * 219 * This is a replacement for EVP_PKEY_free() for the sunw stuff. 220 * It should be used in places where EVP_PKEY_free would be used, 221 * including calls to sk_EVP_PKEY_pop_free(). 222 * 223 * Arguments: 224 * pkey - Entry which potentially has attributes to be freed. 225 * 226 * Returns: 227 * None. 228 */ 229 void 230 sunw_evp_pkey_free(EVP_PKEY *pkey) 231 { 232 if (pkey != NULL) { 233 if (pkey->attributes != NULL) { 234 sk_X509_ATTRIBUTE_pop_free(pkey->attributes, 235 X509_ATTRIBUTE_free); 236 pkey->attributes = NULL; 237 } 238 EVP_PKEY_free(pkey); 239 } 240 } 241 242 /* 243 * sunw_set_localkeyid() sets the localkeyid in a cert, a private key or 244 * both. Any existing localkeyid will be discarded. 245 * 246 * Arguments: 247 * keyid_str- A byte string with the localkeyid to set 248 * keyid_len- Length of the keyid byte string. 249 * pkey - Points to a private key to set the keyidstr in. 250 * cert - Points to a cert to set the keyidstr in. 251 * 252 * Note that setting a keyid into a cert which will not be written out as 253 * a PKCS12 cert is pointless since it will be lost. 254 * 255 * Returns: 256 * 0 - Success. 257 * < 0 - An error occurred. It was probably an error in allocating 258 * memory. The error will be set in the error stack. Call 259 * ERR_get_error() to get specific information. 260 */ 261 int 262 sunw_set_localkeyid(const char *keyid_str, int keyid_len, EVP_PKEY *pkey, 263 X509 *cert) 264 { 265 X509_ATTRIBUTE *attr = NULL; 266 ASN1_STRING *str = NULL; 267 ASN1_TYPE *keyid = NULL; 268 int retval = -1; 269 int i; 270 271 if (cert != NULL) { 272 if (X509_keyid_set1(cert, (uchar_t *)keyid_str, keyid_len) 273 == 0) { 274 SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_SET_LKID_ERR); 275 goto cleanup; 276 } 277 } 278 if (pkey != NULL) { 279 str = (ASN1_STRING *)M_ASN1_OCTET_STRING_new(); 280 if (str == NULL || 281 M_ASN1_OCTET_STRING_set(str, keyid_str, keyid_len) == 0 || 282 (keyid = ASN1_TYPE_new()) == NULL) { 283 SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 284 goto cleanup; 285 } 286 287 ASN1_TYPE_set(keyid, V_ASN1_OCTET_STRING, str); 288 str = NULL; 289 290 attr = type2attrib(keyid, NID_localKeyID); 291 if (attr == NULL) { 292 /* 293 * Error already on stack 294 */ 295 goto cleanup; 296 } 297 keyid = NULL; 298 299 if (pkey->attributes == NULL) { 300 pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 301 if (pkey->attributes == NULL) { 302 SUNWerr(SUNW_F_SET_LOCALKEYID, 303 SUNW_R_MEMORY_FAILURE); 304 goto cleanup; 305 } 306 } else { 307 i = find_attr_by_nid(pkey->attributes, NID_localKeyID); 308 if (i >= 0) 309 sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 310 } 311 if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) { 312 SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 313 goto cleanup; 314 } 315 attr = NULL; 316 } 317 retval = 0; 318 319 cleanup: 320 if (str != NULL) 321 ASN1_STRING_free(str); 322 if (keyid != NULL) 323 ASN1_TYPE_free(keyid); 324 if (attr != NULL) 325 X509_ATTRIBUTE_free(attr); 326 327 return (retval); 328 } 329 330 /* 331 * sunw_get_pkey_localkeyid() gets the localkeyid from a private key. It can 332 * optionally remove the value found. 333 * 334 * Arguments: 335 * dowhat - What to do with the attributes (remove them or copy them). 336 * pkey - Points to a private key to set the keyidstr in. 337 * keyid_str- Points to a location which will receive the pointer to 338 * a byte string containing the binary localkeyid. Note that 339 * this is a copy, and the caller must free it. 340 * keyid_len- Length of keyid_str. 341 * 342 * Returns: 343 * >= 0 - The number of characters in the keyid returned. 344 * < 0 - An error occurred. It was probably an error in allocating 345 * memory. The error will be set in the error stack. Call 346 * ERR_get_error() to get specific information. 347 */ 348 int 349 sunw_get_pkey_localkeyid(getdo_actions_t dowhat, EVP_PKEY *pkey, 350 char **keyid_str, int *keyid_len) 351 { 352 X509_ATTRIBUTE *attr = NULL; 353 ASN1_OCTET_STRING *str = NULL; 354 ASN1_TYPE *ty = NULL; 355 int len = 0; 356 int i; 357 358 if (keyid_str != NULL) 359 *keyid_str = NULL; 360 if (keyid_len != NULL) 361 *keyid_len = 0; 362 363 if (pkey == NULL || pkey->attributes == NULL) { 364 return (0); 365 } 366 367 if ((i = find_attr_by_nid(pkey->attributes, NID_localKeyID)) < 0) { 368 return (0); 369 } 370 attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 371 372 if ((ty = attrib2type(attr)) == NULL || 373 ty->type != V_ASN1_OCTET_STRING) { 374 return (0); 375 } 376 377 if (dowhat == GETDO_DEL) { 378 attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 379 if (attr != NULL) 380 X509_ATTRIBUTE_free(attr); 381 return (0); 382 } 383 384 str = ty->value.octet_string; 385 len = str->length; 386 if ((*keyid_str = malloc(len)) == NULL) { 387 SUNWerr(SUNW_F_GET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 388 return (-1); 389 } 390 391 (void) memcpy(*keyid_str, str->data, len); 392 *keyid_len = len; 393 394 return (len); 395 } 396 397 /* 398 * sunw_get_pkey_fname() gets the friendlyName from a private key. It can 399 * optionally remove the value found. 400 * 401 * Arguments: 402 * dowhat - What to do with the attributes (remove them or copy them). 403 * pkey - Points to a private key to get the frientlyname from 404 * fname - Points to a location which will receive the pointer to a 405 * byte string with the ASCII friendlyname 406 * 407 * Returns: 408 * >= 0 - The number of characters in the frienlyname returned. 409 * < 0 - An error occurred. It was probably an error in allocating 410 * memory. The error will be set in the error stack. Call 411 * ERR_get_error() to get specific information. 412 */ 413 int 414 sunw_get_pkey_fname(getdo_actions_t dowhat, EVP_PKEY *pkey, char **fname) 415 { 416 X509_ATTRIBUTE *attr = NULL; 417 ASN1_BMPSTRING *str = NULL; 418 ASN1_TYPE *ty = NULL; 419 int len = 0; 420 int i; 421 422 if (fname != NULL) 423 *fname = NULL; 424 425 if (pkey == NULL || pkey->attributes == NULL) { 426 return (0); 427 } 428 429 if ((i = find_attr_by_nid(pkey->attributes, NID_friendlyName)) < 0) { 430 return (0); 431 } 432 attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 433 434 if ((ty = attrib2type(attr)) == NULL || 435 ty->type != V_ASN1_BMPSTRING) { 436 return (0); 437 } 438 439 if (dowhat == GETDO_DEL) { 440 attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 441 if (attr != NULL) 442 X509_ATTRIBUTE_free(attr); 443 return (0); 444 } 445 446 str = ty->value.bmpstring; 447 #if OPENSSL_VERSION_NUMBER < 0x10000000L 448 *fname = uni2asc(str->data, str->length); 449 #else 450 *fname = OPENSSL_uni2asc(str->data, str->length); 451 #endif 452 if (*fname == NULL) { 453 SUNWerr(SUNW_F_GET_PKEY_FNAME, SUNW_R_MEMORY_FAILURE); 454 return (-1); 455 } 456 457 len = strlen(*fname); 458 459 return (len); 460 } 461 462 /* 463 * sunw_find_localkeyid() searches stacks of certs and private keys, 464 * and returns the first matching cert/private key found. 465 * 466 * Look for a keyid in a stack of certs. if 'certs' is NULL and 'pkeys' is 467 * not NULL, search the list of private keys. Move the matching cert to 468 * 'matching_cert' and its matching private key to 'matching_pkey'. If no 469 * cert or keys match, no match occurred. 470 * 471 * Arguments: 472 * keyid_str- A byte string with the localkeyid to match 473 * keyid_len- Length of the keyid byte string. 474 * pkeys - Points to a stack of private keys which match the certs. 475 * This may be NULL, in which case no keys are returned. 476 * certs - Points to a stack of certs to search. If NULL, search the 477 * stack of keys instead. 478 * matching_pkey 479 * - Pointer to receive address of first matching pkey found. 480 * 'matching_pkey' must not be NULL; '*matching_pkey' will be 481 * reset. 482 * matching_cert 483 * - Pointer to receive address of first matching cert found. 484 * 'matching_cert' must not be NULL; '*matching_cert' will be 485 * reset. 486 * 487 * Returns: 488 * < 0 - An error returned. Call ERR_get_error() to get errors information. 489 * Where possible, memory has been freed. 490 * >= 0 - Objects were found and returned. Which objects are indicated by 491 * which bits are set (FOUND_PKEY and/or FOUND_CERT). 492 */ 493 int 494 sunw_find_localkeyid(char *keyid_str, int len, STACK_OF(EVP_PKEY) *pkeys, 495 STACK_OF(X509) *certs, EVP_PKEY **matching_pkey, X509 **matching_cert) 496 { 497 ASN1_STRING *cmpstr = NULL; 498 EVP_PKEY *tmp_pkey = NULL; 499 X509 *tmp_cert = NULL; 500 int retval = 0; 501 502 /* If NULL arguments, this is an error */ 503 if (keyid_str == NULL || 504 (pkeys == NULL || certs == NULL) || 505 (pkeys != NULL && matching_pkey == NULL) || 506 (certs != NULL && matching_cert == NULL)) { 507 SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_INVALID_ARG); 508 return (-1); 509 } 510 511 if (matching_pkey != NULL) 512 *matching_pkey = NULL; 513 if (matching_cert != NULL) 514 *matching_cert = NULL; 515 516 cmpstr = (ASN1_STRING *)M_ASN1_OCTET_STRING_new(); 517 if (cmpstr == NULL || 518 M_ASN1_OCTET_STRING_set(cmpstr, keyid_str, len) == 0) { 519 SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 520 return (-1); 521 } 522 523 retval = find_attr(NID_localKeyID, cmpstr, pkeys, &tmp_pkey, certs, 524 &tmp_cert); 525 if (retval == 0) { 526 ASN1_STRING_free(cmpstr); 527 return (retval); 528 } 529 530 if (matching_pkey != NULL) 531 *matching_pkey = tmp_pkey; 532 if (matching_cert != NULL) 533 *matching_cert = tmp_cert; 534 535 return (retval); 536 } 537 538 /* 539 * sunw_find_fname() searches stacks of certs and private keys for one with 540 * a matching friendlyname and returns the first matching cert/private 541 * key found. 542 * 543 * Look for a friendlyname in a stack of certs. if 'certs' is NULL and 'pkeys' 544 * is not NULL, search the list of private keys. Move the matching cert to 545 * 'matching_cert' and its matching private key to 'matching_pkey'. If no 546 * cert or keys match, no match occurred. 547 * 548 * Arguments: 549 * fname - Friendlyname to find (NULL-terminated ASCII string). 550 * pkeys - Points to a stack of private keys which match the certs. 551 * This may be NULL, in which case no keys are returned. 552 * certs - Points to a stack of certs to search. If NULL, search the 553 * stack of keys instead. 554 * matching_pkey 555 * - Pointer to receive address of first matching pkey found. 556 * matching_cert 557 * - Pointer to receive address of first matching cert found. 558 * 559 * Returns: 560 * < 0 - An error returned. Call ERR_get_error() to get errors information. 561 * Where possible, memory has been freed. 562 * >= 0 - Objects were found and returned. Which objects are indicated by 563 * which bits are set (FOUND_PKEY and/or FOUND_CERT). 564 */ 565 int 566 sunw_find_fname(char *fname, STACK_OF(EVP_PKEY) *pkeys, STACK_OF(X509) *certs, 567 EVP_PKEY **matching_pkey, X509 ** matching_cert) 568 { 569 ASN1_STRING *cmpstr = NULL; 570 EVP_PKEY *tmp_pkey = NULL; 571 X509 *tmp_cert = NULL; 572 int retval = 0; 573 574 /* If NULL arguments, this is an error */ 575 if (fname == NULL || 576 (pkeys == NULL || certs == NULL) || 577 (pkeys != NULL && matching_pkey == NULL) || 578 (certs != NULL && matching_cert == NULL)) { 579 SUNWerr(SUNW_F_FIND_FNAME, SUNW_R_INVALID_ARG); 580 return (-1); 581 } 582 583 if (matching_pkey != NULL) 584 *matching_pkey = NULL; 585 if (matching_cert != NULL) 586 *matching_cert = NULL; 587 588 cmpstr = (ASN1_STRING *)asc2bmpstring(fname, strlen(fname)); 589 if (cmpstr == NULL) { 590 /* 591 * Error already on stack 592 */ 593 return (-1); 594 } 595 596 retval = find_attr(NID_friendlyName, cmpstr, pkeys, &tmp_pkey, certs, 597 &tmp_cert); 598 if (retval == 0) { 599 ASN1_STRING_free(cmpstr); 600 return (retval); 601 } 602 603 if (matching_pkey != NULL) 604 *matching_pkey = tmp_pkey; 605 if (matching_cert != NULL) 606 *matching_cert = tmp_cert; 607 608 return (retval); 609 } 610 611 /* 612 * sunw_print_times() formats and prints cert times to the given file. 613 * 614 * The label is printed on one line. One or both dates are printed on 615 * the following line or two, each with it's own indented label in the 616 * format: 617 * 618 * label 619 * 'not before' date: whatever 620 * 'not after' date: whatever 621 * 622 * Arguments: 623 * fp - file pointer for file to write to. 624 * dowhat - what field(s) to print. 625 * label - Label to use. If NULL, no line will be printed. 626 * cert - Points to a client or CA certs to check 627 * 628 * Returns: 629 * < 0 - An error occured. 630 * >= 0 - Number of lines written. 631 */ 632 int 633 sunw_print_times(FILE *fp, prnt_actions_t dowhat, char *label, X509 *cert) 634 { 635 int lines = 0; 636 637 if (label != NULL) { 638 (void) fprintf(fp, "%s\n", label); 639 lines++; 640 } 641 642 if (dowhat == PRNT_NOT_BEFORE || dowhat == PRNT_BOTH) { 643 (void) fprintf(fp, "'not before' date: "); 644 (void) print_time(fp, X509_get_notBefore(cert)); 645 (void) fprintf(fp, "\n"); 646 lines++; 647 } 648 649 if (dowhat == PRNT_NOT_AFTER || dowhat == PRNT_BOTH) { 650 (void) fprintf(fp, "'not after' date: "); 651 (void) print_time(fp, X509_get_notAfter(cert)); 652 (void) fprintf(fp, "\n"); 653 lines++; 654 } 655 return (lines); 656 } 657 658 /* 659 * sunw_check_keys() compares the public key in the certificate and a 660 * private key to ensure that they match. 661 * 662 * Arguments: 663 * cert - Points to a certificate. 664 * pkey - Points to a private key. 665 * 666 * Returns: 667 * == 0 - These do not match. 668 * != 0 - The cert's public key and the private key match. 669 */ 670 int 671 sunw_check_keys(X509 *cert, EVP_PKEY *pkey) 672 { 673 int retval = 0; 674 675 if (pkey != NULL && cert != NULL) 676 retval = X509_check_private_key(cert, pkey); 677 678 return (retval); 679 } 680 681 /* 682 * sunw_issuer_attrs - Given a cert, return the issuer-specific attributes 683 * as one ASCII string. 684 * 685 * Arguments: 686 * cert - Cert to process 687 * buf - If non-NULL, buffer to receive string. If NULL, one will 688 * be allocated and its value will be returned to the caller. 689 * len - If 'buff' is non-null, the buffer's length. 690 * 691 * This returns an ASCII string with all issuer-related attributes in one 692 * string separated by '/' characters. Each attribute begins with its name 693 * and an equal sign. Two attributes (ATTR1 and Attr2) would have the 694 * following form: 695 * 696 * ATTR1=attr_value/ATTR2=attr2_value 697 * 698 * Returns: 699 * != NULL - Pointer to the ASCII string containing the issuer-related 700 * attributes. If the 'buf' argument was NULL, this is a 701 * dynamically-allocated buffer and the caller will have the 702 * responsibility for freeing it. 703 * NULL - Memory needed to be allocated but could not be. Errors 704 * are set on the error stack. 705 */ 706 char * 707 sunw_issuer_attrs(X509 *cert, char *buf, int len) 708 { 709 return (X509_NAME_oneline(X509_get_issuer_name(cert), buf, len)); 710 } 711 712 /* 713 * sunw_subject_attrs - Given a cert, return the subject-specific attributes 714 * as one ASCII string. 715 * 716 * Arguments: 717 * cert - Cert to process 718 * buf - If non-NULL, buffer to receive string. If NULL, one will 719 * be allocated and its value will be returned to the caller. 720 * len - If 'buff' is non-null, the buffer's length. 721 * 722 * This returns an ASCII string with all subject-related attributes in one 723 * string separated by '/' characters. Each attribute begins with its name 724 * and an equal sign. Two attributes (ATTR1 and Attr2) would have the 725 * following form: 726 * 727 * ATTR1=attr_value/ATTR2=attr2_value 728 * 729 * Returns: 730 * != NULL - Pointer to the ASCII string containing the subject-related 731 * attributes. If the 'buf' argument was NULL, this is a 732 * dynamically-allocated buffer and the caller will have the 733 * responsibility for freeing it. 734 * NULL - Memory needed to be allocated but could not be. Errors 735 * are set on the error stack. 736 */ 737 char * 738 sunw_subject_attrs(X509 *cert, char *buf, int len) 739 { 740 return (X509_NAME_oneline(X509_get_subject_name(cert), buf, len)); 741 } 742 743 /* 744 * sunw_append_keys - Given two stacks of private keys, remove the keys from 745 * the second stack and append them to the first. Both stacks must exist 746 * at time of call. 747 * 748 * Arguments: 749 * dst - the stack to receive the keys from 'src' 750 * src - the stack whose keys are to be moved. 751 * 752 * Returns: 753 * -1 - An error occurred. The error status is set. 754 * >= 0 - The number of keys that were copied. 755 */ 756 int 757 sunw_append_keys(STACK_OF(EVP_PKEY) *dst, STACK_OF(EVP_PKEY) *src) 758 { 759 EVP_PKEY *tmpk; 760 int count = 0; 761 762 while (sk_EVP_PKEY_num(src) > 0) { 763 tmpk = sk_EVP_PKEY_delete(src, 0); 764 if (sk_EVP_PKEY_push(dst, tmpk) == 0) { 765 sunw_evp_pkey_free(tmpk); 766 SUNWerr(SUNW_F_APPEND_KEYS, SUNW_R_MEMORY_FAILURE); 767 return (-1); 768 } 769 count++; 770 } 771 772 return (count); 773 } 774