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