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