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