17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * ==================================================================== 37c478bd9Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 67c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 77c478bd9Sstevel@tonic-gate * are met: 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 107c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 117c478bd9Sstevel@tonic-gate * 127c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 137c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 147c478bd9Sstevel@tonic-gate * the documentation and/or other materials provided with the 157c478bd9Sstevel@tonic-gate * distribution. 167c478bd9Sstevel@tonic-gate * 177c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 187c478bd9Sstevel@tonic-gate * software must display the following acknowledgment: 197c478bd9Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 207c478bd9Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 217c478bd9Sstevel@tonic-gate * 227c478bd9Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 237c478bd9Sstevel@tonic-gate * endorse or promote products derived from this software without 247c478bd9Sstevel@tonic-gate * prior written permission. For written permission, please contact 257c478bd9Sstevel@tonic-gate * licensing@OpenSSL.org. 267c478bd9Sstevel@tonic-gate * 277c478bd9Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 287c478bd9Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 297c478bd9Sstevel@tonic-gate * permission of the OpenSSL Project. 307c478bd9Sstevel@tonic-gate * 317c478bd9Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 327c478bd9Sstevel@tonic-gate * acknowledgment: 337c478bd9Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 347c478bd9Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 357c478bd9Sstevel@tonic-gate * 367c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 377c478bd9Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 387c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 397c478bd9Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 407c478bd9Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 417c478bd9Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 427c478bd9Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 437c478bd9Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 447c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 457c478bd9Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 467c478bd9Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 477c478bd9Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 487c478bd9Sstevel@tonic-gate * ==================================================================== 497c478bd9Sstevel@tonic-gate * 507c478bd9Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 517c478bd9Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 527c478bd9Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate /* 579dc0df1bSjp161948 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 587c478bd9Sstevel@tonic-gate * Use is subject to license terms. 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate 61*70f9559bSTheo Schlossnagle /* 62*70f9559bSTheo Schlossnagle * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. 63*70f9559bSTheo Schlossnagle */ 64*70f9559bSTheo Schlossnagle 657c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #include <stdio.h> 687c478bd9Sstevel@tonic-gate #include <strings.h> 697c478bd9Sstevel@tonic-gate #include <stdlib.h> 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate #include <openssl/crypto.h> 727c478bd9Sstevel@tonic-gate #include <openssl/err.h> 737c478bd9Sstevel@tonic-gate #include <openssl/x509.h> 749dc0df1bSjp161948 #include <openssl/ssl.h> 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #include <openssl/pkcs12.h> 777c478bd9Sstevel@tonic-gate #include <p12aux.h> 787c478bd9Sstevel@tonic-gate #include <auxutil.h> 797c478bd9Sstevel@tonic-gate #include <p12err.h> 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * sunw_cryto_init() does crypto-specific initialization. 837c478bd9Sstevel@tonic-gate * 847c478bd9Sstevel@tonic-gate * Arguments: 857c478bd9Sstevel@tonic-gate * None. 867c478bd9Sstevel@tonic-gate * 877c478bd9Sstevel@tonic-gate * Returns: 887c478bd9Sstevel@tonic-gate * None. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate void 917c478bd9Sstevel@tonic-gate sunw_crypto_init(void) 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate OpenSSL_add_all_algorithms(); 949dc0df1bSjp161948 SSL_load_error_strings(); 957c478bd9Sstevel@tonic-gate ERR_load_SUNW_strings(); 969dc0df1bSjp161948 (void) SSL_library_init(); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * sunw_split_certs() - Given a list of certs and a list of private keys, 1017c478bd9Sstevel@tonic-gate * moves certs which match one of the keys to a different stack. 1027c478bd9Sstevel@tonic-gate * 1037c478bd9Sstevel@tonic-gate * Arguments: 1047c478bd9Sstevel@tonic-gate * allkeys - Points to a stack of private keys to search. 1057c478bd9Sstevel@tonic-gate * allcerts - Points to a stack of certs to be searched. 1067c478bd9Sstevel@tonic-gate * keycerts - Points to address of a stack of certs with matching private 1077c478bd9Sstevel@tonic-gate * keys. They are moved from 'allcerts'. This may not be NULL 1087c478bd9Sstevel@tonic-gate * when called. If *keycerts is NULL upon entry, a new stack will 1097c478bd9Sstevel@tonic-gate * be allocated. Otherwise, it must be a valid STACK_OF(509). 1107c478bd9Sstevel@tonic-gate * nocerts - Points to address of a stack for keys which have no matching 1117c478bd9Sstevel@tonic-gate * certs. Keys are moved from 'allkeys' here when they have no 1127c478bd9Sstevel@tonic-gate * matching certs. If this is NULL, matchless keys will be 1137c478bd9Sstevel@tonic-gate * discarded. 1147c478bd9Sstevel@tonic-gate * 1157c478bd9Sstevel@tonic-gate * Notes: If an error occurs while moving certs, the cert being move may be 1167c478bd9Sstevel@tonic-gate * lost. 'keycerts' may only contain part of the matching certs. The number 1177c478bd9Sstevel@tonic-gate * of certs successfully moved can be found by checking sk_X509_num(keycerts). 1187c478bd9Sstevel@tonic-gate * 1197c478bd9Sstevel@tonic-gate * If there is a key which does not have a matching cert, it is moved to 1207c478bd9Sstevel@tonic-gate * the list nocerts. 1217c478bd9Sstevel@tonic-gate * 1227c478bd9Sstevel@tonic-gate * If all certs are removed from 'certs' and/or 'pkeys', it will be the 1237c478bd9Sstevel@tonic-gate * caller's responsibility to free the empty stacks. 1247c478bd9Sstevel@tonic-gate * 1257c478bd9Sstevel@tonic-gate * Returns: 1267c478bd9Sstevel@tonic-gate * < 0 - An error returned. Call ERR_get_error() to get errors information. 1277c478bd9Sstevel@tonic-gate * Where possible, memory has been freed. 1287c478bd9Sstevel@tonic-gate * >= 0 - The number of certs moved from 'cert' to 'pkcerts'. 1297c478bd9Sstevel@tonic-gate */ 1307c478bd9Sstevel@tonic-gate int 1317c478bd9Sstevel@tonic-gate sunw_split_certs(STACK_OF(EVP_PKEY) *allkeys, STACK_OF(X509) *allcerts, 1327c478bd9Sstevel@tonic-gate STACK_OF(X509) **keycerts, STACK_OF(EVP_PKEY) **nocerts) 1337c478bd9Sstevel@tonic-gate { 1347c478bd9Sstevel@tonic-gate STACK_OF(X509) *matching; 1357c478bd9Sstevel@tonic-gate STACK_OF(EVP_PKEY) *nomatch; 1367c478bd9Sstevel@tonic-gate EVP_PKEY *tmpkey; 1377c478bd9Sstevel@tonic-gate X509 *tmpcert; 1387c478bd9Sstevel@tonic-gate int count = 0; 1397c478bd9Sstevel@tonic-gate int found; 1407c478bd9Sstevel@tonic-gate int res; 1417c478bd9Sstevel@tonic-gate int i; 1427c478bd9Sstevel@tonic-gate int k; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate *keycerts = NULL; 1457c478bd9Sstevel@tonic-gate if (nocerts != NULL) 1467c478bd9Sstevel@tonic-gate *nocerts = NULL; 1477c478bd9Sstevel@tonic-gate nomatch = NULL; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate if ((matching = sk_X509_new_null()) == NULL) { 1507c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SPLIT_CERTS, SUNW_R_MEMORY_FAILURE); 1517c478bd9Sstevel@tonic-gate return (-1); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate *keycerts = matching; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate k = 0; 1567c478bd9Sstevel@tonic-gate while (k < sk_EVP_PKEY_num(allkeys)) { 1577c478bd9Sstevel@tonic-gate found = 0; 1587c478bd9Sstevel@tonic-gate tmpkey = sk_EVP_PKEY_value(allkeys, k); 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate for (i = 0; i < sk_X509_num(allcerts); i++) { 1617c478bd9Sstevel@tonic-gate tmpcert = sk_X509_value(allcerts, i); 1627c478bd9Sstevel@tonic-gate res = X509_check_private_key(tmpcert, tmpkey); 1637c478bd9Sstevel@tonic-gate if (res != 0) { 1647c478bd9Sstevel@tonic-gate count++; 1657c478bd9Sstevel@tonic-gate found = 1; 1667c478bd9Sstevel@tonic-gate tmpcert = sk_X509_delete(allcerts, i); 1677c478bd9Sstevel@tonic-gate if (sk_X509_push(matching, tmpcert) == 0) { 1687c478bd9Sstevel@tonic-gate X509_free(tmpcert); 1697c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SPLIT_CERTS, 1707c478bd9Sstevel@tonic-gate SUNW_R_MEMORY_FAILURE); 1717c478bd9Sstevel@tonic-gate return (-1); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate if (found != 0) { 1777c478bd9Sstevel@tonic-gate /* 1787c478bd9Sstevel@tonic-gate * Found a match - keep the key & check out the next 1797c478bd9Sstevel@tonic-gate * one. 1807c478bd9Sstevel@tonic-gate */ 1817c478bd9Sstevel@tonic-gate k++; 1827c478bd9Sstevel@tonic-gate } else { 1837c478bd9Sstevel@tonic-gate /* 1847c478bd9Sstevel@tonic-gate * No cert matching this key. Move the key if 1857c478bd9Sstevel@tonic-gate * possible or discard it. Don't increment the 1867c478bd9Sstevel@tonic-gate * index. 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate if (nocerts == NULL) { 1897c478bd9Sstevel@tonic-gate tmpkey = sk_EVP_PKEY_delete(allkeys, k); 1907c478bd9Sstevel@tonic-gate sunw_evp_pkey_free(tmpkey); 1917c478bd9Sstevel@tonic-gate } else { 1927c478bd9Sstevel@tonic-gate if (*nocerts == NULL) { 1937c478bd9Sstevel@tonic-gate nomatch = sk_EVP_PKEY_new_null(); 1947c478bd9Sstevel@tonic-gate if (nomatch == NULL) { 1957c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SPLIT_CERTS, 1967c478bd9Sstevel@tonic-gate SUNW_R_MEMORY_FAILURE); 1977c478bd9Sstevel@tonic-gate return (-1); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate *nocerts = nomatch; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate tmpkey = sk_EVP_PKEY_delete(allkeys, k); 2027c478bd9Sstevel@tonic-gate if (sk_EVP_PKEY_push(nomatch, tmpkey) == 0) { 2037c478bd9Sstevel@tonic-gate sunw_evp_pkey_free(tmpkey); 2047c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SPLIT_CERTS, 2057c478bd9Sstevel@tonic-gate SUNW_R_MEMORY_FAILURE); 2067c478bd9Sstevel@tonic-gate return (-1); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate return (count); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate /* 2167c478bd9Sstevel@tonic-gate * sunw_evp_pkey_free() Given an EVP_PKEY structure, free any attributes 2177c478bd9Sstevel@tonic-gate * that are attached. Then free the EVP_PKEY itself. 2187c478bd9Sstevel@tonic-gate * 2197c478bd9Sstevel@tonic-gate * This is a replacement for EVP_PKEY_free() for the sunw stuff. 2207c478bd9Sstevel@tonic-gate * It should be used in places where EVP_PKEY_free would be used, 2217c478bd9Sstevel@tonic-gate * including calls to sk_EVP_PKEY_pop_free(). 2227c478bd9Sstevel@tonic-gate * 2237c478bd9Sstevel@tonic-gate * Arguments: 2247c478bd9Sstevel@tonic-gate * pkey - Entry which potentially has attributes to be freed. 2257c478bd9Sstevel@tonic-gate * 2267c478bd9Sstevel@tonic-gate * Returns: 2277c478bd9Sstevel@tonic-gate * None. 2287c478bd9Sstevel@tonic-gate */ 2297c478bd9Sstevel@tonic-gate void 2307c478bd9Sstevel@tonic-gate sunw_evp_pkey_free(EVP_PKEY *pkey) 2317c478bd9Sstevel@tonic-gate { 2327c478bd9Sstevel@tonic-gate if (pkey != NULL) { 2337c478bd9Sstevel@tonic-gate if (pkey->attributes != NULL) { 2347c478bd9Sstevel@tonic-gate sk_X509_ATTRIBUTE_pop_free(pkey->attributes, 2357c478bd9Sstevel@tonic-gate X509_ATTRIBUTE_free); 2367c478bd9Sstevel@tonic-gate pkey->attributes = NULL; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate EVP_PKEY_free(pkey); 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /* 2437c478bd9Sstevel@tonic-gate * sunw_set_localkeyid() sets the localkeyid in a cert, a private key or 2447c478bd9Sstevel@tonic-gate * both. Any existing localkeyid will be discarded. 2457c478bd9Sstevel@tonic-gate * 2467c478bd9Sstevel@tonic-gate * Arguments: 2477c478bd9Sstevel@tonic-gate * keyid_str- A byte string with the localkeyid to set 2487c478bd9Sstevel@tonic-gate * keyid_len- Length of the keyid byte string. 2497c478bd9Sstevel@tonic-gate * pkey - Points to a private key to set the keyidstr in. 2507c478bd9Sstevel@tonic-gate * cert - Points to a cert to set the keyidstr in. 2517c478bd9Sstevel@tonic-gate * 2527c478bd9Sstevel@tonic-gate * Note that setting a keyid into a cert which will not be written out as 2537c478bd9Sstevel@tonic-gate * a PKCS12 cert is pointless since it will be lost. 2547c478bd9Sstevel@tonic-gate * 2557c478bd9Sstevel@tonic-gate * Returns: 2567c478bd9Sstevel@tonic-gate * 0 - Success. 2577c478bd9Sstevel@tonic-gate * < 0 - An error occurred. It was probably an error in allocating 2587c478bd9Sstevel@tonic-gate * memory. The error will be set in the error stack. Call 2597c478bd9Sstevel@tonic-gate * ERR_get_error() to get specific information. 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate int 2627c478bd9Sstevel@tonic-gate sunw_set_localkeyid(const char *keyid_str, int keyid_len, EVP_PKEY *pkey, 2637c478bd9Sstevel@tonic-gate X509 *cert) 2647c478bd9Sstevel@tonic-gate { 2657c478bd9Sstevel@tonic-gate X509_ATTRIBUTE *attr = NULL; 2667c478bd9Sstevel@tonic-gate ASN1_STRING *str = NULL; 2677c478bd9Sstevel@tonic-gate ASN1_TYPE *keyid = NULL; 2687c478bd9Sstevel@tonic-gate int retval = -1; 2697c478bd9Sstevel@tonic-gate int i; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate if (cert != NULL) { 2727c478bd9Sstevel@tonic-gate if (X509_keyid_set1(cert, (uchar_t *)keyid_str, keyid_len) 2737c478bd9Sstevel@tonic-gate == 0) { 2747c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_SET_LKID_ERR); 2757c478bd9Sstevel@tonic-gate goto cleanup; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate if (pkey != NULL) { 2797c478bd9Sstevel@tonic-gate str = (ASN1_STRING *)M_ASN1_OCTET_STRING_new(); 2807c478bd9Sstevel@tonic-gate if (str == NULL || 2817c478bd9Sstevel@tonic-gate M_ASN1_OCTET_STRING_set(str, keyid_str, keyid_len) == 0 || 2827c478bd9Sstevel@tonic-gate (keyid = ASN1_TYPE_new()) == NULL) { 2837c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 2847c478bd9Sstevel@tonic-gate goto cleanup; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate ASN1_TYPE_set(keyid, V_ASN1_OCTET_STRING, str); 2887c478bd9Sstevel@tonic-gate str = NULL; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate attr = type2attrib(keyid, NID_localKeyID); 2917c478bd9Sstevel@tonic-gate if (attr == NULL) { 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * Error already on stack 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate goto cleanup; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate keyid = NULL; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate if (pkey->attributes == NULL) { 3007c478bd9Sstevel@tonic-gate pkey->attributes = sk_X509_ATTRIBUTE_new_null(); 3017c478bd9Sstevel@tonic-gate if (pkey->attributes == NULL) { 3027c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SET_LOCALKEYID, 3037c478bd9Sstevel@tonic-gate SUNW_R_MEMORY_FAILURE); 3047c478bd9Sstevel@tonic-gate goto cleanup; 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate } else { 3077c478bd9Sstevel@tonic-gate i = find_attr_by_nid(pkey->attributes, NID_localKeyID); 3087c478bd9Sstevel@tonic-gate if (i >= 0) 3097c478bd9Sstevel@tonic-gate sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) { 3127c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 3137c478bd9Sstevel@tonic-gate goto cleanup; 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate attr = NULL; 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate retval = 0; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate cleanup: 3207c478bd9Sstevel@tonic-gate if (str != NULL) 3217c478bd9Sstevel@tonic-gate ASN1_STRING_free(str); 3227c478bd9Sstevel@tonic-gate if (keyid != NULL) 3237c478bd9Sstevel@tonic-gate ASN1_TYPE_free(keyid); 3247c478bd9Sstevel@tonic-gate if (attr != NULL) 3257c478bd9Sstevel@tonic-gate X509_ATTRIBUTE_free(attr); 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate return (retval); 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate /* 3317c478bd9Sstevel@tonic-gate * sunw_get_pkey_localkeyid() gets the localkeyid from a private key. It can 3327c478bd9Sstevel@tonic-gate * optionally remove the value found. 3337c478bd9Sstevel@tonic-gate * 3347c478bd9Sstevel@tonic-gate * Arguments: 3357c478bd9Sstevel@tonic-gate * dowhat - What to do with the attributes (remove them or copy them). 3367c478bd9Sstevel@tonic-gate * pkey - Points to a private key to set the keyidstr in. 3377c478bd9Sstevel@tonic-gate * keyid_str- Points to a location which will receive the pointer to 3387c478bd9Sstevel@tonic-gate * a byte string containing the binary localkeyid. Note that 3397c478bd9Sstevel@tonic-gate * this is a copy, and the caller must free it. 3407c478bd9Sstevel@tonic-gate * keyid_len- Length of keyid_str. 3417c478bd9Sstevel@tonic-gate * 3427c478bd9Sstevel@tonic-gate * Returns: 3437c478bd9Sstevel@tonic-gate * >= 0 - The number of characters in the keyid returned. 3447c478bd9Sstevel@tonic-gate * < 0 - An error occurred. It was probably an error in allocating 3457c478bd9Sstevel@tonic-gate * memory. The error will be set in the error stack. Call 3467c478bd9Sstevel@tonic-gate * ERR_get_error() to get specific information. 3477c478bd9Sstevel@tonic-gate */ 3487c478bd9Sstevel@tonic-gate int 3497c478bd9Sstevel@tonic-gate sunw_get_pkey_localkeyid(getdo_actions_t dowhat, EVP_PKEY *pkey, 3507c478bd9Sstevel@tonic-gate char **keyid_str, int *keyid_len) 3517c478bd9Sstevel@tonic-gate { 3527c478bd9Sstevel@tonic-gate X509_ATTRIBUTE *attr = NULL; 3537c478bd9Sstevel@tonic-gate ASN1_OCTET_STRING *str = NULL; 3547c478bd9Sstevel@tonic-gate ASN1_TYPE *ty = NULL; 3557c478bd9Sstevel@tonic-gate int len = 0; 3567c478bd9Sstevel@tonic-gate int i; 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate if (keyid_str != NULL) 3597c478bd9Sstevel@tonic-gate *keyid_str = NULL; 3607c478bd9Sstevel@tonic-gate if (keyid_len != NULL) 3617c478bd9Sstevel@tonic-gate *keyid_len = 0; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate if (pkey == NULL || pkey->attributes == NULL) { 3647c478bd9Sstevel@tonic-gate return (0); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate if ((i = find_attr_by_nid(pkey->attributes, NID_localKeyID)) < 0) { 3687c478bd9Sstevel@tonic-gate return (0); 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate if ((ty = attrib2type(attr)) == NULL || 3737c478bd9Sstevel@tonic-gate ty->type != V_ASN1_OCTET_STRING) { 3747c478bd9Sstevel@tonic-gate return (0); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate if (dowhat == GETDO_DEL) { 3787c478bd9Sstevel@tonic-gate attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 3797c478bd9Sstevel@tonic-gate if (attr != NULL) 3807c478bd9Sstevel@tonic-gate X509_ATTRIBUTE_free(attr); 3817c478bd9Sstevel@tonic-gate return (0); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate str = ty->value.octet_string; 3857c478bd9Sstevel@tonic-gate len = str->length; 3867c478bd9Sstevel@tonic-gate if ((*keyid_str = malloc(len)) == NULL) { 3877c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_GET_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 3887c478bd9Sstevel@tonic-gate return (-1); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate (void) memcpy(*keyid_str, str->data, len); 3927c478bd9Sstevel@tonic-gate *keyid_len = len; 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate return (len); 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * sunw_get_pkey_fname() gets the friendlyName from a private key. It can 3997c478bd9Sstevel@tonic-gate * optionally remove the value found. 4007c478bd9Sstevel@tonic-gate * 4017c478bd9Sstevel@tonic-gate * Arguments: 4027c478bd9Sstevel@tonic-gate * dowhat - What to do with the attributes (remove them or copy them). 4037c478bd9Sstevel@tonic-gate * pkey - Points to a private key to get the frientlyname from 4047c478bd9Sstevel@tonic-gate * fname - Points to a location which will receive the pointer to a 4057c478bd9Sstevel@tonic-gate * byte string with the ASCII friendlyname 4067c478bd9Sstevel@tonic-gate * 4077c478bd9Sstevel@tonic-gate * Returns: 4087c478bd9Sstevel@tonic-gate * >= 0 - The number of characters in the frienlyname returned. 4097c478bd9Sstevel@tonic-gate * < 0 - An error occurred. It was probably an error in allocating 4107c478bd9Sstevel@tonic-gate * memory. The error will be set in the error stack. Call 4117c478bd9Sstevel@tonic-gate * ERR_get_error() to get specific information. 4127c478bd9Sstevel@tonic-gate */ 4137c478bd9Sstevel@tonic-gate int 4147c478bd9Sstevel@tonic-gate sunw_get_pkey_fname(getdo_actions_t dowhat, EVP_PKEY *pkey, char **fname) 4157c478bd9Sstevel@tonic-gate { 4167c478bd9Sstevel@tonic-gate X509_ATTRIBUTE *attr = NULL; 4177c478bd9Sstevel@tonic-gate ASN1_BMPSTRING *str = NULL; 4187c478bd9Sstevel@tonic-gate ASN1_TYPE *ty = NULL; 4197c478bd9Sstevel@tonic-gate int len = 0; 4207c478bd9Sstevel@tonic-gate int i; 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate if (fname != NULL) 4237c478bd9Sstevel@tonic-gate *fname = NULL; 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate if (pkey == NULL || pkey->attributes == NULL) { 4267c478bd9Sstevel@tonic-gate return (0); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate if ((i = find_attr_by_nid(pkey->attributes, NID_friendlyName)) < 0) { 4307c478bd9Sstevel@tonic-gate return (0); 4317c478bd9Sstevel@tonic-gate } 4327c478bd9Sstevel@tonic-gate attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if ((ty = attrib2type(attr)) == NULL || 4357c478bd9Sstevel@tonic-gate ty->type != V_ASN1_BMPSTRING) { 4367c478bd9Sstevel@tonic-gate return (0); 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate if (dowhat == GETDO_DEL) { 4407c478bd9Sstevel@tonic-gate attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i); 4417c478bd9Sstevel@tonic-gate if (attr != NULL) 4427c478bd9Sstevel@tonic-gate X509_ATTRIBUTE_free(attr); 4437c478bd9Sstevel@tonic-gate return (0); 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate str = ty->value.bmpstring; 447*70f9559bSTheo Schlossnagle #if OPENSSL_VERSION_NUMBER < 0x10000000L 4487c478bd9Sstevel@tonic-gate *fname = uni2asc(str->data, str->length); 449*70f9559bSTheo Schlossnagle #else 450*70f9559bSTheo Schlossnagle *fname = OPENSSL_uni2asc(str->data, str->length); 451*70f9559bSTheo Schlossnagle #endif 4527c478bd9Sstevel@tonic-gate if (*fname == NULL) { 4537c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_GET_PKEY_FNAME, SUNW_R_MEMORY_FAILURE); 4547c478bd9Sstevel@tonic-gate return (-1); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate len = strlen(*fname); 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate return (len); 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate /* 4637c478bd9Sstevel@tonic-gate * sunw_find_localkeyid() searches stacks of certs and private keys, 4647c478bd9Sstevel@tonic-gate * and returns the first matching cert/private key found. 4657c478bd9Sstevel@tonic-gate * 4667c478bd9Sstevel@tonic-gate * Look for a keyid in a stack of certs. if 'certs' is NULL and 'pkeys' is 4677c478bd9Sstevel@tonic-gate * not NULL, search the list of private keys. Move the matching cert to 4687c478bd9Sstevel@tonic-gate * 'matching_cert' and its matching private key to 'matching_pkey'. If no 4697c478bd9Sstevel@tonic-gate * cert or keys match, no match occurred. 4707c478bd9Sstevel@tonic-gate * 4717c478bd9Sstevel@tonic-gate * Arguments: 4727c478bd9Sstevel@tonic-gate * keyid_str- A byte string with the localkeyid to match 4737c478bd9Sstevel@tonic-gate * keyid_len- Length of the keyid byte string. 4747c478bd9Sstevel@tonic-gate * pkeys - Points to a stack of private keys which match the certs. 4757c478bd9Sstevel@tonic-gate * This may be NULL, in which case no keys are returned. 4767c478bd9Sstevel@tonic-gate * certs - Points to a stack of certs to search. If NULL, search the 4777c478bd9Sstevel@tonic-gate * stack of keys instead. 4787c478bd9Sstevel@tonic-gate * matching_pkey 4797c478bd9Sstevel@tonic-gate * - Pointer to receive address of first matching pkey found. 4807c478bd9Sstevel@tonic-gate * 'matching_pkey' must not be NULL; '*matching_pkey' will be 4817c478bd9Sstevel@tonic-gate * reset. 4827c478bd9Sstevel@tonic-gate * matching_cert 4837c478bd9Sstevel@tonic-gate * - Pointer to receive address of first matching cert found. 4847c478bd9Sstevel@tonic-gate * 'matching_cert' must not be NULL; '*matching_cert' will be 4857c478bd9Sstevel@tonic-gate * reset. 4867c478bd9Sstevel@tonic-gate * 4877c478bd9Sstevel@tonic-gate * Returns: 4887c478bd9Sstevel@tonic-gate * < 0 - An error returned. Call ERR_get_error() to get errors information. 4897c478bd9Sstevel@tonic-gate * Where possible, memory has been freed. 4907c478bd9Sstevel@tonic-gate * >= 0 - Objects were found and returned. Which objects are indicated by 4917c478bd9Sstevel@tonic-gate * which bits are set (FOUND_PKEY and/or FOUND_CERT). 4927c478bd9Sstevel@tonic-gate */ 4937c478bd9Sstevel@tonic-gate int 4947c478bd9Sstevel@tonic-gate sunw_find_localkeyid(char *keyid_str, int len, STACK_OF(EVP_PKEY) *pkeys, 4957c478bd9Sstevel@tonic-gate STACK_OF(X509) *certs, EVP_PKEY **matching_pkey, X509 **matching_cert) 4967c478bd9Sstevel@tonic-gate { 4977c478bd9Sstevel@tonic-gate ASN1_STRING *cmpstr = NULL; 4987c478bd9Sstevel@tonic-gate EVP_PKEY *tmp_pkey = NULL; 4997c478bd9Sstevel@tonic-gate X509 *tmp_cert = NULL; 5007c478bd9Sstevel@tonic-gate int retval = 0; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* If NULL arguments, this is an error */ 5037c478bd9Sstevel@tonic-gate if (keyid_str == NULL || 5047c478bd9Sstevel@tonic-gate (pkeys == NULL || certs == NULL) || 5057c478bd9Sstevel@tonic-gate (pkeys != NULL && matching_pkey == NULL) || 5067c478bd9Sstevel@tonic-gate (certs != NULL && matching_cert == NULL)) { 5077c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_INVALID_ARG); 5087c478bd9Sstevel@tonic-gate return (-1); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate if (matching_pkey != NULL) 5127c478bd9Sstevel@tonic-gate *matching_pkey = NULL; 5137c478bd9Sstevel@tonic-gate if (matching_cert != NULL) 5147c478bd9Sstevel@tonic-gate *matching_cert = NULL; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate cmpstr = (ASN1_STRING *)M_ASN1_OCTET_STRING_new(); 5177c478bd9Sstevel@tonic-gate if (cmpstr == NULL || 5187c478bd9Sstevel@tonic-gate M_ASN1_OCTET_STRING_set(cmpstr, keyid_str, len) == 0) { 5197c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_MEMORY_FAILURE); 5207c478bd9Sstevel@tonic-gate return (-1); 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate retval = find_attr(NID_localKeyID, cmpstr, pkeys, &tmp_pkey, certs, 5247c478bd9Sstevel@tonic-gate &tmp_cert); 5257c478bd9Sstevel@tonic-gate if (retval == 0) { 5267c478bd9Sstevel@tonic-gate ASN1_STRING_free(cmpstr); 5277c478bd9Sstevel@tonic-gate return (retval); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate if (matching_pkey != NULL) 5317c478bd9Sstevel@tonic-gate *matching_pkey = tmp_pkey; 5327c478bd9Sstevel@tonic-gate if (matching_cert != NULL) 5337c478bd9Sstevel@tonic-gate *matching_cert = tmp_cert; 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate return (retval); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate /* 5397c478bd9Sstevel@tonic-gate * sunw_find_fname() searches stacks of certs and private keys for one with 5407c478bd9Sstevel@tonic-gate * a matching friendlyname and returns the first matching cert/private 5417c478bd9Sstevel@tonic-gate * key found. 5427c478bd9Sstevel@tonic-gate * 5437c478bd9Sstevel@tonic-gate * Look for a friendlyname in a stack of certs. if 'certs' is NULL and 'pkeys' 5447c478bd9Sstevel@tonic-gate * is not NULL, search the list of private keys. Move the matching cert to 5457c478bd9Sstevel@tonic-gate * 'matching_cert' and its matching private key to 'matching_pkey'. If no 5467c478bd9Sstevel@tonic-gate * cert or keys match, no match occurred. 5477c478bd9Sstevel@tonic-gate * 5487c478bd9Sstevel@tonic-gate * Arguments: 5497c478bd9Sstevel@tonic-gate * fname - Friendlyname to find (NULL-terminated ASCII string). 5507c478bd9Sstevel@tonic-gate * pkeys - Points to a stack of private keys which match the certs. 5517c478bd9Sstevel@tonic-gate * This may be NULL, in which case no keys are returned. 5527c478bd9Sstevel@tonic-gate * certs - Points to a stack of certs to search. If NULL, search the 5537c478bd9Sstevel@tonic-gate * stack of keys instead. 5547c478bd9Sstevel@tonic-gate * matching_pkey 5557c478bd9Sstevel@tonic-gate * - Pointer to receive address of first matching pkey found. 5567c478bd9Sstevel@tonic-gate * matching_cert 5577c478bd9Sstevel@tonic-gate * - Pointer to receive address of first matching cert found. 5587c478bd9Sstevel@tonic-gate * 5597c478bd9Sstevel@tonic-gate * Returns: 5607c478bd9Sstevel@tonic-gate * < 0 - An error returned. Call ERR_get_error() to get errors information. 5617c478bd9Sstevel@tonic-gate * Where possible, memory has been freed. 5627c478bd9Sstevel@tonic-gate * >= 0 - Objects were found and returned. Which objects are indicated by 5637c478bd9Sstevel@tonic-gate * which bits are set (FOUND_PKEY and/or FOUND_CERT). 5647c478bd9Sstevel@tonic-gate */ 5657c478bd9Sstevel@tonic-gate int 5667c478bd9Sstevel@tonic-gate sunw_find_fname(char *fname, STACK_OF(EVP_PKEY) *pkeys, STACK_OF(X509) *certs, 5677c478bd9Sstevel@tonic-gate EVP_PKEY **matching_pkey, X509 ** matching_cert) 5687c478bd9Sstevel@tonic-gate { 5697c478bd9Sstevel@tonic-gate ASN1_STRING *cmpstr = NULL; 5707c478bd9Sstevel@tonic-gate EVP_PKEY *tmp_pkey = NULL; 5717c478bd9Sstevel@tonic-gate X509 *tmp_cert = NULL; 5727c478bd9Sstevel@tonic-gate int retval = 0; 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate /* If NULL arguments, this is an error */ 5757c478bd9Sstevel@tonic-gate if (fname == NULL || 5767c478bd9Sstevel@tonic-gate (pkeys == NULL || certs == NULL) || 5777c478bd9Sstevel@tonic-gate (pkeys != NULL && matching_pkey == NULL) || 5787c478bd9Sstevel@tonic-gate (certs != NULL && matching_cert == NULL)) { 5797c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_FIND_FNAME, SUNW_R_INVALID_ARG); 5807c478bd9Sstevel@tonic-gate return (-1); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate if (matching_pkey != NULL) 5847c478bd9Sstevel@tonic-gate *matching_pkey = NULL; 5857c478bd9Sstevel@tonic-gate if (matching_cert != NULL) 5867c478bd9Sstevel@tonic-gate *matching_cert = NULL; 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate cmpstr = (ASN1_STRING *)asc2bmpstring(fname, strlen(fname)); 5897c478bd9Sstevel@tonic-gate if (cmpstr == NULL) { 5907c478bd9Sstevel@tonic-gate /* 5917c478bd9Sstevel@tonic-gate * Error already on stack 5927c478bd9Sstevel@tonic-gate */ 5937c478bd9Sstevel@tonic-gate return (-1); 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate retval = find_attr(NID_friendlyName, cmpstr, pkeys, &tmp_pkey, certs, 5977c478bd9Sstevel@tonic-gate &tmp_cert); 5987c478bd9Sstevel@tonic-gate if (retval == 0) { 5997c478bd9Sstevel@tonic-gate ASN1_STRING_free(cmpstr); 6007c478bd9Sstevel@tonic-gate return (retval); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate if (matching_pkey != NULL) 6047c478bd9Sstevel@tonic-gate *matching_pkey = tmp_pkey; 6057c478bd9Sstevel@tonic-gate if (matching_cert != NULL) 6067c478bd9Sstevel@tonic-gate *matching_cert = tmp_cert; 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate return (retval); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate /* 6127c478bd9Sstevel@tonic-gate * sunw_print_times() formats and prints cert times to the given file. 6137c478bd9Sstevel@tonic-gate * 6147c478bd9Sstevel@tonic-gate * The label is printed on one line. One or both dates are printed on 6157c478bd9Sstevel@tonic-gate * the following line or two, each with it's own indented label in the 6167c478bd9Sstevel@tonic-gate * format: 6177c478bd9Sstevel@tonic-gate * 6187c478bd9Sstevel@tonic-gate * label 6197c478bd9Sstevel@tonic-gate * 'not before' date: whatever 6207c478bd9Sstevel@tonic-gate * 'not after' date: whatever 6217c478bd9Sstevel@tonic-gate * 6227c478bd9Sstevel@tonic-gate * Arguments: 6237c478bd9Sstevel@tonic-gate * fp - file pointer for file to write to. 6247c478bd9Sstevel@tonic-gate * dowhat - what field(s) to print. 6257c478bd9Sstevel@tonic-gate * label - Label to use. If NULL, no line will be printed. 6267c478bd9Sstevel@tonic-gate * cert - Points to a client or CA certs to check 6277c478bd9Sstevel@tonic-gate * 6287c478bd9Sstevel@tonic-gate * Returns: 6297c478bd9Sstevel@tonic-gate * < 0 - An error occured. 6307c478bd9Sstevel@tonic-gate * >= 0 - Number of lines written. 6317c478bd9Sstevel@tonic-gate */ 6327c478bd9Sstevel@tonic-gate int 6337c478bd9Sstevel@tonic-gate sunw_print_times(FILE *fp, prnt_actions_t dowhat, char *label, X509 *cert) 6347c478bd9Sstevel@tonic-gate { 6357c478bd9Sstevel@tonic-gate int lines = 0; 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate if (label != NULL) { 6387c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s\n", label); 6397c478bd9Sstevel@tonic-gate lines++; 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate if (dowhat == PRNT_NOT_BEFORE || dowhat == PRNT_BOTH) { 6437c478bd9Sstevel@tonic-gate (void) fprintf(fp, "'not before' date: "); 6447c478bd9Sstevel@tonic-gate (void) print_time(fp, X509_get_notBefore(cert)); 6457c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 6467c478bd9Sstevel@tonic-gate lines++; 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate if (dowhat == PRNT_NOT_AFTER || dowhat == PRNT_BOTH) { 6507c478bd9Sstevel@tonic-gate (void) fprintf(fp, "'not after' date: "); 6517c478bd9Sstevel@tonic-gate (void) print_time(fp, X509_get_notAfter(cert)); 6527c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 6537c478bd9Sstevel@tonic-gate lines++; 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate return (lines); 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate /* 6597c478bd9Sstevel@tonic-gate * sunw_check_keys() compares the public key in the certificate and a 6607c478bd9Sstevel@tonic-gate * private key to ensure that they match. 6617c478bd9Sstevel@tonic-gate * 6627c478bd9Sstevel@tonic-gate * Arguments: 6637c478bd9Sstevel@tonic-gate * cert - Points to a certificate. 6647c478bd9Sstevel@tonic-gate * pkey - Points to a private key. 6657c478bd9Sstevel@tonic-gate * 6667c478bd9Sstevel@tonic-gate * Returns: 6677c478bd9Sstevel@tonic-gate * == 0 - These do not match. 6687c478bd9Sstevel@tonic-gate * != 0 - The cert's public key and the private key match. 6697c478bd9Sstevel@tonic-gate */ 6707c478bd9Sstevel@tonic-gate int 6717c478bd9Sstevel@tonic-gate sunw_check_keys(X509 *cert, EVP_PKEY *pkey) 6727c478bd9Sstevel@tonic-gate { 6737c478bd9Sstevel@tonic-gate int retval = 0; 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate if (pkey != NULL && cert != NULL) 6767c478bd9Sstevel@tonic-gate retval = X509_check_private_key(cert, pkey); 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate return (retval); 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate /* 6827c478bd9Sstevel@tonic-gate * sunw_issuer_attrs - Given a cert, return the issuer-specific attributes 6837c478bd9Sstevel@tonic-gate * as one ASCII string. 6847c478bd9Sstevel@tonic-gate * 6857c478bd9Sstevel@tonic-gate * Arguments: 6867c478bd9Sstevel@tonic-gate * cert - Cert to process 6877c478bd9Sstevel@tonic-gate * buf - If non-NULL, buffer to receive string. If NULL, one will 6887c478bd9Sstevel@tonic-gate * be allocated and its value will be returned to the caller. 6897c478bd9Sstevel@tonic-gate * len - If 'buff' is non-null, the buffer's length. 6907c478bd9Sstevel@tonic-gate * 6917c478bd9Sstevel@tonic-gate * This returns an ASCII string with all issuer-related attributes in one 6927c478bd9Sstevel@tonic-gate * string separated by '/' characters. Each attribute begins with its name 6937c478bd9Sstevel@tonic-gate * and an equal sign. Two attributes (ATTR1 and Attr2) would have the 6947c478bd9Sstevel@tonic-gate * following form: 6957c478bd9Sstevel@tonic-gate * 6967c478bd9Sstevel@tonic-gate * ATTR1=attr_value/ATTR2=attr2_value 6977c478bd9Sstevel@tonic-gate * 6987c478bd9Sstevel@tonic-gate * Returns: 6997c478bd9Sstevel@tonic-gate * != NULL - Pointer to the ASCII string containing the issuer-related 7007c478bd9Sstevel@tonic-gate * attributes. If the 'buf' argument was NULL, this is a 7017c478bd9Sstevel@tonic-gate * dynamically-allocated buffer and the caller will have the 7027c478bd9Sstevel@tonic-gate * responsibility for freeing it. 7037c478bd9Sstevel@tonic-gate * NULL - Memory needed to be allocated but could not be. Errors 7047c478bd9Sstevel@tonic-gate * are set on the error stack. 7057c478bd9Sstevel@tonic-gate */ 7067c478bd9Sstevel@tonic-gate char * 7077c478bd9Sstevel@tonic-gate sunw_issuer_attrs(X509 *cert, char *buf, int len) 7087c478bd9Sstevel@tonic-gate { 7097c478bd9Sstevel@tonic-gate return (X509_NAME_oneline(X509_get_issuer_name(cert), buf, len)); 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate /* 7137c478bd9Sstevel@tonic-gate * sunw_subject_attrs - Given a cert, return the subject-specific attributes 7147c478bd9Sstevel@tonic-gate * as one ASCII string. 7157c478bd9Sstevel@tonic-gate * 7167c478bd9Sstevel@tonic-gate * Arguments: 7177c478bd9Sstevel@tonic-gate * cert - Cert to process 7187c478bd9Sstevel@tonic-gate * buf - If non-NULL, buffer to receive string. If NULL, one will 7197c478bd9Sstevel@tonic-gate * be allocated and its value will be returned to the caller. 7207c478bd9Sstevel@tonic-gate * len - If 'buff' is non-null, the buffer's length. 7217c478bd9Sstevel@tonic-gate * 7227c478bd9Sstevel@tonic-gate * This returns an ASCII string with all subject-related attributes in one 7237c478bd9Sstevel@tonic-gate * string separated by '/' characters. Each attribute begins with its name 7247c478bd9Sstevel@tonic-gate * and an equal sign. Two attributes (ATTR1 and Attr2) would have the 7257c478bd9Sstevel@tonic-gate * following form: 7267c478bd9Sstevel@tonic-gate * 7277c478bd9Sstevel@tonic-gate * ATTR1=attr_value/ATTR2=attr2_value 7287c478bd9Sstevel@tonic-gate * 7297c478bd9Sstevel@tonic-gate * Returns: 7307c478bd9Sstevel@tonic-gate * != NULL - Pointer to the ASCII string containing the subject-related 7317c478bd9Sstevel@tonic-gate * attributes. If the 'buf' argument was NULL, this is a 7327c478bd9Sstevel@tonic-gate * dynamically-allocated buffer and the caller will have the 7337c478bd9Sstevel@tonic-gate * responsibility for freeing it. 7347c478bd9Sstevel@tonic-gate * NULL - Memory needed to be allocated but could not be. Errors 7357c478bd9Sstevel@tonic-gate * are set on the error stack. 7367c478bd9Sstevel@tonic-gate */ 7377c478bd9Sstevel@tonic-gate char * 7387c478bd9Sstevel@tonic-gate sunw_subject_attrs(X509 *cert, char *buf, int len) 7397c478bd9Sstevel@tonic-gate { 7407c478bd9Sstevel@tonic-gate return (X509_NAME_oneline(X509_get_subject_name(cert), buf, len)); 7417c478bd9Sstevel@tonic-gate } 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate /* 7447c478bd9Sstevel@tonic-gate * sunw_append_keys - Given two stacks of private keys, remove the keys from 7457c478bd9Sstevel@tonic-gate * the second stack and append them to the first. Both stacks must exist 7467c478bd9Sstevel@tonic-gate * at time of call. 7477c478bd9Sstevel@tonic-gate * 7487c478bd9Sstevel@tonic-gate * Arguments: 7497c478bd9Sstevel@tonic-gate * dst - the stack to receive the keys from 'src' 7507c478bd9Sstevel@tonic-gate * src - the stack whose keys are to be moved. 7517c478bd9Sstevel@tonic-gate * 7527c478bd9Sstevel@tonic-gate * Returns: 7537c478bd9Sstevel@tonic-gate * -1 - An error occurred. The error status is set. 7547c478bd9Sstevel@tonic-gate * >= 0 - The number of keys that were copied. 7557c478bd9Sstevel@tonic-gate */ 7567c478bd9Sstevel@tonic-gate int 7577c478bd9Sstevel@tonic-gate sunw_append_keys(STACK_OF(EVP_PKEY) *dst, STACK_OF(EVP_PKEY) *src) 7587c478bd9Sstevel@tonic-gate { 7597c478bd9Sstevel@tonic-gate EVP_PKEY *tmpk; 7607c478bd9Sstevel@tonic-gate int count = 0; 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate while (sk_EVP_PKEY_num(src) > 0) { 7637c478bd9Sstevel@tonic-gate tmpk = sk_EVP_PKEY_delete(src, 0); 7647c478bd9Sstevel@tonic-gate if (sk_EVP_PKEY_push(dst, tmpk) == 0) { 7657c478bd9Sstevel@tonic-gate sunw_evp_pkey_free(tmpk); 7667c478bd9Sstevel@tonic-gate SUNWerr(SUNW_F_APPEND_KEYS, SUNW_R_MEMORY_FAILURE); 7677c478bd9Sstevel@tonic-gate return (-1); 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate count++; 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate return (count); 7737c478bd9Sstevel@tonic-gate } 774