1a12f8217Spwernau /* 2a12f8217Spwernau * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3a12f8217Spwernau * All rights reserved. 4a12f8217Spwernau * 5a12f8217Spwernau * This package is an SSL implementation written 6a12f8217Spwernau * by Eric Young (eay@cryptsoft.com). 7a12f8217Spwernau * The implementation was written so as to conform with Netscapes SSL. 8a12f8217Spwernau * 9a12f8217Spwernau * This library is free for commercial and non-commercial use as long as 10a12f8217Spwernau * the following conditions are aheared to. The following conditions 11a12f8217Spwernau * apply to all code found in this distribution, be it the RC4, RSA, 12a12f8217Spwernau * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13a12f8217Spwernau * included with this distribution is covered by the same copyright terms 14a12f8217Spwernau * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15a12f8217Spwernau * 16a12f8217Spwernau * Copyright remains Eric Young's, and as such any Copyright notices in 17a12f8217Spwernau * the code are not to be removed. 18a12f8217Spwernau * If this package is used in a product, Eric Young should be given attribution 19a12f8217Spwernau * as the author of the parts of the library used. 20a12f8217Spwernau * This can be in the form of a textual message at program startup or 21a12f8217Spwernau * in documentation (online or textual) provided with the package. 22a12f8217Spwernau * 23a12f8217Spwernau * Redistribution and use in source and binary forms, with or without 24a12f8217Spwernau * modification, are permitted provided that the following conditions 25a12f8217Spwernau * are met: 26a12f8217Spwernau * 1. Redistributions of source code must retain the copyright 27a12f8217Spwernau * notice, this list of conditions and the following disclaimer. 28a12f8217Spwernau * 2. Redistributions in binary form must reproduce the above copyright 29a12f8217Spwernau * notice, this list of conditions and the following disclaimer in the 30a12f8217Spwernau * documentation and/or other materials provided with the distribution. 31a12f8217Spwernau * 3. All advertising materials mentioning features or use of this software 32a12f8217Spwernau * must display the following acknowledgement: 33a12f8217Spwernau * "This product includes cryptographic software written by 34a12f8217Spwernau * Eric Young (eay@cryptsoft.com)" 35a12f8217Spwernau * The word 'cryptographic' can be left out if the rouines from the library 36a12f8217Spwernau * being used are not cryptographic related :-). 37a12f8217Spwernau * 4. If you include any Windows specific code (or a derivative thereof) from 38a12f8217Spwernau * the apps directory (application code) you must include an acknowledgement: 39a12f8217Spwernau * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40a12f8217Spwernau * 41a12f8217Spwernau * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42a12f8217Spwernau * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43a12f8217Spwernau * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44a12f8217Spwernau * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45a12f8217Spwernau * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46a12f8217Spwernau * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47a12f8217Spwernau * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48a12f8217Spwernau * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49a12f8217Spwernau * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50a12f8217Spwernau * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51a12f8217Spwernau * SUCH DAMAGE. 52a12f8217Spwernau * 53a12f8217Spwernau * The licence and distribution terms for any publically available version or 54a12f8217Spwernau * derivative of this code cannot be changed. i.e. this code cannot simply be 55a12f8217Spwernau * copied and put under another distribution licence 56a12f8217Spwernau * [including the GNU Public Licence.] 57a12f8217Spwernau */ 58a12f8217Spwernau 59a12f8217Spwernau /* 60*6221cd42SPaul Wernau * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 61a12f8217Spwernau * Use is subject to license terms. 62a12f8217Spwernau */ 63a12f8217Spwernau 64a12f8217Spwernau /* 65a12f8217Spwernau * Thread setup portions of this code derived from 66*6221cd42SPaul Wernau * OpenSSL 0.9.x file mt/mttest.c examples 67a12f8217Spwernau */ 68a12f8217Spwernau 69a12f8217Spwernau #include <stdio.h> 70a12f8217Spwernau #include <stdlib.h> 71a12f8217Spwernau #include <string.h> 72a12f8217Spwernau #include <errno.h> 73a12f8217Spwernau #include <libintl.h> 74a12f8217Spwernau #include <synch.h> 75a12f8217Spwernau #include <thread.h> 76a12f8217Spwernau #include <dlfcn.h> 77a12f8217Spwernau #include <openssl/lhash.h> 78a12f8217Spwernau #include <openssl/crypto.h> 79a12f8217Spwernau #include <openssl/ssl.h> 80a12f8217Spwernau #include <openssl/err.h> 81a12f8217Spwernau #include "ipsec_util.h" 82a12f8217Spwernau 83a12f8217Spwernau /* OpenSSL function pointers */ 84a12f8217Spwernau static X509_NAME *(*d2i_X509_NAME_fn)() = NULL; 85a12f8217Spwernau static int (*X509_NAME_print_ex_fp_fn)() = NULL; 86a12f8217Spwernau static char *(*ERR_get_error_fn)() = NULL; 87a12f8217Spwernau static char *(*ERR_error_string_fn)() = NULL; 88a12f8217Spwernau static void (*SSL_load_error_strings_fn)() = NULL; 89a12f8217Spwernau static void (*ERR_free_strings_fn)() = NULL; 90a12f8217Spwernau static void (*CRYPTO_set_locking_callback_fn)() = NULL; 91a12f8217Spwernau static void (*CRYPTO_set_id_callback_fn)() = NULL; 92dfd65381Svk199839 static void (*X509_NAME_free_fn)() = NULL; 93*6221cd42SPaul Wernau static int (*CRYPTO_num_locks_fn)() = NULL; 94*6221cd42SPaul Wernau static void *(*OPENSSL_malloc_fn)() = NULL; 95*6221cd42SPaul Wernau static void (*OPENSSL_free_fn)() = NULL; 96a12f8217Spwernau 97a12f8217Spwernau static void solaris_locking_callback(int, int, char *, int); 98a12f8217Spwernau static unsigned long solaris_thread_id(void); 99*6221cd42SPaul Wernau static boolean_t thread_setup(void); 100a12f8217Spwernau /* LINTED E_STATIC_UNUSED */ 101a12f8217Spwernau static void thread_cleanup(void); 102a12f8217Spwernau 103a12f8217Spwernau mutex_t init_lock = DEFAULTMUTEX; 104*6221cd42SPaul Wernau static mutex_t *lock_cs; 105*6221cd42SPaul Wernau static long *lock_count; 106*6221cd42SPaul Wernau 107*6221cd42SPaul Wernau static boolean_t libssl_loaded = B_FALSE; 108*6221cd42SPaul Wernau static boolean_t libcrypto_loaded = B_FALSE; 109a12f8217Spwernau 110a12f8217Spwernau void 111a12f8217Spwernau libssl_load() 112a12f8217Spwernau { 113a12f8217Spwernau void *dldesc; 114a12f8217Spwernau 115a12f8217Spwernau (void) mutex_lock(&init_lock); 116a12f8217Spwernau if (libssl_loaded) { 117a12f8217Spwernau (void) mutex_unlock(&init_lock); 118a12f8217Spwernau return; 119a12f8217Spwernau } 120a12f8217Spwernau 121a12f8217Spwernau dldesc = dlopen(LIBSSL, RTLD_LAZY); 122a12f8217Spwernau if (dldesc != NULL) { 123a12f8217Spwernau d2i_X509_NAME_fn = (X509_NAME*(*)())dlsym(dldesc, 124a12f8217Spwernau "d2i_X509_NAME"); 125a12f8217Spwernau if (d2i_X509_NAME_fn == NULL) 126a12f8217Spwernau goto libssl_err; 127a12f8217Spwernau 128a12f8217Spwernau X509_NAME_print_ex_fp_fn = (int(*)())dlsym(dldesc, 129a12f8217Spwernau "X509_NAME_print_ex_fp"); 130a12f8217Spwernau if (X509_NAME_print_ex_fp_fn == NULL) 131a12f8217Spwernau goto libssl_err; 132a12f8217Spwernau 133a12f8217Spwernau ERR_get_error_fn = (char *(*)())dlsym(dldesc, 134a12f8217Spwernau "ERR_get_error"); 135a12f8217Spwernau if (ERR_get_error_fn == NULL) 136a12f8217Spwernau goto libssl_err; 137a12f8217Spwernau 138a12f8217Spwernau ERR_error_string_fn = (char *(*)())dlsym(dldesc, 139a12f8217Spwernau "ERR_error_string"); 140a12f8217Spwernau if (ERR_error_string_fn == NULL) 141a12f8217Spwernau goto libssl_err; 142a12f8217Spwernau 143a12f8217Spwernau SSL_load_error_strings_fn = (void(*)())dlsym(dldesc, 144a12f8217Spwernau "SSL_load_error_strings"); 145a12f8217Spwernau if (SSL_load_error_strings_fn == NULL) 146a12f8217Spwernau goto libssl_err; 147a12f8217Spwernau 148a12f8217Spwernau ERR_free_strings_fn = (void(*)())dlsym(dldesc, 149a12f8217Spwernau "ERR_free_strings"); 150a12f8217Spwernau if (ERR_free_strings_fn == NULL) 151a12f8217Spwernau goto libssl_err; 152a12f8217Spwernau 153a12f8217Spwernau CRYPTO_set_locking_callback_fn = (void(*)())dlsym(dldesc, 154a12f8217Spwernau "CRYPTO_set_locking_callback"); 155a12f8217Spwernau if (CRYPTO_set_locking_callback_fn == NULL) 156a12f8217Spwernau goto libssl_err; 157a12f8217Spwernau 158a12f8217Spwernau CRYPTO_set_id_callback_fn = (void(*)())dlsym(dldesc, 159a12f8217Spwernau "CRYPTO_set_id_callback"); 160a12f8217Spwernau if (CRYPTO_set_id_callback_fn == NULL) 161a12f8217Spwernau goto libssl_err; 162a12f8217Spwernau 163dfd65381Svk199839 X509_NAME_free_fn = (void(*)())dlsym(dldesc, 164dfd65381Svk199839 "X509_NAME_free"); 165dfd65381Svk199839 if (X509_NAME_free_fn == NULL) 166e314c1b2Svk199839 goto libssl_err; 167e314c1b2Svk199839 168*6221cd42SPaul Wernau if (thread_setup() == B_FALSE) 169*6221cd42SPaul Wernau goto libssl_err; 170a12f8217Spwernau 171a12f8217Spwernau libssl_loaded = B_TRUE; 172a12f8217Spwernau } 173a12f8217Spwernau (void) mutex_unlock(&init_lock); 174a12f8217Spwernau return; 175a12f8217Spwernau libssl_err: 176a12f8217Spwernau (void) dlclose(dldesc); 177a12f8217Spwernau (void) mutex_unlock(&init_lock); 178a12f8217Spwernau } 179a12f8217Spwernau 180*6221cd42SPaul Wernau void 181*6221cd42SPaul Wernau libcrypto_load() 182*6221cd42SPaul Wernau { 183*6221cd42SPaul Wernau void *dldesc; 184*6221cd42SPaul Wernau 185*6221cd42SPaul Wernau (void) mutex_lock(&init_lock); 186*6221cd42SPaul Wernau if (libcrypto_loaded) { 187*6221cd42SPaul Wernau (void) mutex_unlock(&init_lock); 188*6221cd42SPaul Wernau return; 189*6221cd42SPaul Wernau } 190*6221cd42SPaul Wernau 191*6221cd42SPaul Wernau dldesc = dlopen(LIBCRYPTO, RTLD_LAZY); 192*6221cd42SPaul Wernau if (dldesc != NULL) { 193*6221cd42SPaul Wernau CRYPTO_num_locks_fn = (int(*)())dlsym(dldesc, 194*6221cd42SPaul Wernau "CRYPTO_num_locks"); 195*6221cd42SPaul Wernau if (CRYPTO_num_locks_fn == NULL) 196*6221cd42SPaul Wernau goto libcrypto_err; 197*6221cd42SPaul Wernau 198*6221cd42SPaul Wernau /* 199*6221cd42SPaul Wernau * OPENSSL_free is really a macro, so we 200*6221cd42SPaul Wernau * need to reference the actual symbol, 201*6221cd42SPaul Wernau * which is CRYPTO_free. 202*6221cd42SPaul Wernau */ 203*6221cd42SPaul Wernau OPENSSL_free_fn = (void(*)())dlsym(dldesc, 204*6221cd42SPaul Wernau "CRYPTO_free"); 205*6221cd42SPaul Wernau if (OPENSSL_free_fn == NULL) 206*6221cd42SPaul Wernau goto libcrypto_err; 207*6221cd42SPaul Wernau 208*6221cd42SPaul Wernau /* 209*6221cd42SPaul Wernau * OPENSSL_malloc is really a macro, so we 210*6221cd42SPaul Wernau * need to reference the actual symbol, 211*6221cd42SPaul Wernau * which is CRYPTO_malloc. 212*6221cd42SPaul Wernau */ 213*6221cd42SPaul Wernau OPENSSL_malloc_fn = (void *(*)())dlsym(dldesc, 214*6221cd42SPaul Wernau "CRYPTO_malloc"); 215*6221cd42SPaul Wernau if (OPENSSL_malloc_fn == NULL) 216*6221cd42SPaul Wernau goto libcrypto_err; 217*6221cd42SPaul Wernau 218*6221cd42SPaul Wernau libcrypto_loaded = B_TRUE; 219*6221cd42SPaul Wernau } 220*6221cd42SPaul Wernau (void) mutex_unlock(&init_lock); 221*6221cd42SPaul Wernau return; 222*6221cd42SPaul Wernau libcrypto_err: 223*6221cd42SPaul Wernau (void) dlclose(dldesc); 224*6221cd42SPaul Wernau (void) mutex_unlock(&init_lock); 225*6221cd42SPaul Wernau } 226*6221cd42SPaul Wernau 227*6221cd42SPaul Wernau static boolean_t 228a12f8217Spwernau thread_setup(void) 229a12f8217Spwernau { 230a12f8217Spwernau int i; 231a12f8217Spwernau 232*6221cd42SPaul Wernau if ((lock_cs = OPENSSL_malloc_fn(CRYPTO_num_locks_fn() * 233*6221cd42SPaul Wernau sizeof (mutex_t))) == NULL) 234*6221cd42SPaul Wernau return (B_FALSE); 235*6221cd42SPaul Wernau if ((lock_count = OPENSSL_malloc_fn(CRYPTO_num_locks_fn() * 236*6221cd42SPaul Wernau sizeof (long))) == NULL) { 237*6221cd42SPaul Wernau OPENSSL_free_fn(lock_cs); 238*6221cd42SPaul Wernau return (B_FALSE); 239*6221cd42SPaul Wernau } 240*6221cd42SPaul Wernau 241*6221cd42SPaul Wernau for (i = 0; i < CRYPTO_num_locks_fn(); i++) { 242a12f8217Spwernau lock_count[i] = 0; 243a12f8217Spwernau (void) mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); 244a12f8217Spwernau } 245a12f8217Spwernau 246a12f8217Spwernau CRYPTO_set_id_callback_fn((unsigned long (*)())solaris_thread_id); 247a12f8217Spwernau CRYPTO_set_locking_callback_fn((void (*)())solaris_locking_callback); 248*6221cd42SPaul Wernau return (B_TRUE); 249a12f8217Spwernau } 250a12f8217Spwernau 251a12f8217Spwernau static void 252a12f8217Spwernau thread_cleanup(void) 253a12f8217Spwernau { 254a12f8217Spwernau int i; 255a12f8217Spwernau 256a12f8217Spwernau (void) mutex_lock(&init_lock); 257a12f8217Spwernau CRYPTO_set_locking_callback_fn(NULL); 258a12f8217Spwernau CRYPTO_set_id_callback_fn(NULL); 259*6221cd42SPaul Wernau for (i = 0; i < CRYPTO_num_locks_fn(); i++) 260a12f8217Spwernau (void) mutex_destroy(&(lock_cs[i])); 261*6221cd42SPaul Wernau OPENSSL_free_fn(lock_cs); 262*6221cd42SPaul Wernau OPENSSL_free_fn(lock_count); 263a12f8217Spwernau (void) mutex_unlock(&init_lock); 264a12f8217Spwernau } 265a12f8217Spwernau 266a12f8217Spwernau /* ARGSUSED */ 267a12f8217Spwernau static void 268a12f8217Spwernau solaris_locking_callback(int mode, int type, char *file, int line) 269a12f8217Spwernau { 270a12f8217Spwernau if (mode & CRYPTO_LOCK) { 271a12f8217Spwernau (void) mutex_lock(&(lock_cs[type])); 272a12f8217Spwernau lock_count[type]++; 273a12f8217Spwernau } else { 274a12f8217Spwernau (void) mutex_unlock(&(lock_cs[type])); 275a12f8217Spwernau } 276a12f8217Spwernau } 277a12f8217Spwernau 278a12f8217Spwernau static unsigned long 279a12f8217Spwernau solaris_thread_id(void) 280a12f8217Spwernau { 281a12f8217Spwernau unsigned long ret; 282a12f8217Spwernau 283a12f8217Spwernau ret = (unsigned long)thr_self(); 284a12f8217Spwernau return (ret); 285a12f8217Spwernau } 286a12f8217Spwernau 287a12f8217Spwernau void 288a12f8217Spwernau print_asn1_name(FILE *file, const unsigned char *buf, long buflen) 289a12f8217Spwernau { 290*6221cd42SPaul Wernau libcrypto_load(); 291*6221cd42SPaul Wernau if (libcrypto_loaded) 292a12f8217Spwernau libssl_load(); 293a12f8217Spwernau 294*6221cd42SPaul Wernau if (libssl_loaded && libcrypto_loaded) { 295dfd65381Svk199839 X509_NAME *x509name = NULL; 296a12f8217Spwernau const unsigned char *p; 297a12f8217Spwernau 298a12f8217Spwernau /* Make an effort to decode the ASN1 encoded name */ 299a12f8217Spwernau SSL_load_error_strings_fn(); 300a12f8217Spwernau 301dfd65381Svk199839 /* 302dfd65381Svk199839 * Temporary variable is mandatory per d2i_X509(3). Upcoming 303dfd65381Svk199839 * call to d2i_X509_NAME_fn() will change the 'p' pointer. 304dfd65381Svk199839 */ 305a12f8217Spwernau p = buf; 306a12f8217Spwernau 307dfd65381Svk199839 x509name = d2i_X509_NAME_fn(NULL, &p, buflen); 308dfd65381Svk199839 if (x509name != NULL) { 309dfd65381Svk199839 (void) X509_NAME_print_ex_fp_fn(file, x509name, 0, 310a12f8217Spwernau (ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | 311a12f8217Spwernau XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN)); 312dfd65381Svk199839 X509_NAME_free_fn(x509name); 313a12f8217Spwernau (void) fprintf(file, "\n"); 314a12f8217Spwernau } else { 315a12f8217Spwernau char errbuf[80]; 316a12f8217Spwernau 317a12f8217Spwernau (void) fprintf(file, "\n# %s\n", 318a12f8217Spwernau ERR_error_string_fn(ERR_get_error_fn(), errbuf)); 319a12f8217Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, 320a12f8217Spwernau "<cannot interpret>\n")); 321a12f8217Spwernau } 322a12f8217Spwernau ERR_free_strings_fn(); 323a12f8217Spwernau } else { 324a12f8217Spwernau (void) fprintf(file, dgettext(TEXT_DOMAIN, "<cannot print>\n")); 325a12f8217Spwernau } 326a12f8217Spwernau } 327