1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #include "streams/openssl.h"
9 #include "streams/openssl_legacy.h"
10 
11 #include "runtime.h"
12 #include "git2/sys/openssl.h"
13 
14 #if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC)
15 # include <openssl/ssl.h>
16 # include <openssl/err.h>
17 # include <openssl/x509v3.h>
18 # include <openssl/bio.h>
19 #endif
20 
21 #if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC)
22 
23 /*
24  * OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
25  * which do not exist in previous versions. We define these inline functions so
26  * we can program against the interface instead of littering the implementation
27  * with ifdefs. We do the same for OPENSSL_init_ssl.
28  */
29 
OPENSSL_init_ssl__legacy(uint64_t opts,const void * settings)30 int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings)
31 {
32 	GIT_UNUSED(opts);
33 	GIT_UNUSED(settings);
34 	SSL_load_error_strings();
35 	SSL_library_init();
36 	return 0;
37 }
38 
BIO_meth_new__legacy(int type,const char * name)39 BIO_METHOD *BIO_meth_new__legacy(int type, const char *name)
40 {
41 	BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
42 	if (!meth) {
43 		return NULL;
44 	}
45 
46 	meth->type = type;
47 	meth->name = name;
48 
49 	return meth;
50 }
51 
BIO_meth_free__legacy(BIO_METHOD * biom)52 void BIO_meth_free__legacy(BIO_METHOD *biom)
53 {
54 	git__free(biom);
55 }
56 
BIO_meth_set_write__legacy(BIO_METHOD * biom,int (* write)(BIO *,const char *,int))57 int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
58 {
59 	biom->bwrite = write;
60 	return 1;
61 }
62 
BIO_meth_set_read__legacy(BIO_METHOD * biom,int (* read)(BIO *,char *,int))63 int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
64 {
65 	biom->bread = read;
66 	return 1;
67 }
68 
BIO_meth_set_puts__legacy(BIO_METHOD * biom,int (* puts)(BIO *,const char *))69 int BIO_meth_set_puts__legacy(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
70 {
71 	biom->bputs = puts;
72 	return 1;
73 }
74 
BIO_meth_set_gets__legacy(BIO_METHOD * biom,int (* gets)(BIO *,char *,int))75 int BIO_meth_set_gets__legacy(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))
76 
77 {
78 	biom->bgets = gets;
79 	return 1;
80 }
81 
BIO_meth_set_ctrl__legacy(BIO_METHOD * biom,long (* ctrl)(BIO *,int,long,void *))82 int BIO_meth_set_ctrl__legacy(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
83 {
84 	biom->ctrl = ctrl;
85 	return 1;
86 }
87 
BIO_meth_set_create__legacy(BIO_METHOD * biom,int (* create)(BIO *))88 int BIO_meth_set_create__legacy(BIO_METHOD *biom, int (*create) (BIO *))
89 {
90 	biom->create = create;
91 	return 1;
92 }
93 
BIO_meth_set_destroy__legacy(BIO_METHOD * biom,int (* destroy)(BIO *))94 int BIO_meth_set_destroy__legacy(BIO_METHOD *biom, int (*destroy) (BIO *))
95 {
96 	biom->destroy = destroy;
97 	return 1;
98 }
99 
BIO_get_new_index__legacy(void)100 int BIO_get_new_index__legacy(void)
101 {
102 	/* This exists as of 1.1 so before we'd just have 0 */
103 	return 0;
104 }
105 
BIO_set_init__legacy(BIO * b,int init)106 void BIO_set_init__legacy(BIO *b, int init)
107 {
108 	b->init = init;
109 }
110 
BIO_set_data__legacy(BIO * a,void * ptr)111 void BIO_set_data__legacy(BIO *a, void *ptr)
112 {
113 	a->ptr = ptr;
114 }
115 
BIO_get_data__legacy(BIO * a)116 void *BIO_get_data__legacy(BIO *a)
117 {
118 	return a->ptr;
119 }
120 
ASN1_STRING_get0_data__legacy(const ASN1_STRING * x)121 const unsigned char *ASN1_STRING_get0_data__legacy(const ASN1_STRING *x)
122 {
123 	return ASN1_STRING_data((ASN1_STRING *)x);
124 }
125 
SSL_CTX_set_options__legacy(SSL_CTX * ctx,long op)126 long SSL_CTX_set_options__legacy(SSL_CTX *ctx, long op)
127 {
128 	return SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, op, NULL);
129 }
130 
131 # if defined(GIT_THREADS)
132 static git_mutex *openssl_locks;
133 
openssl_locking_function(int mode,int n,const char * file,int line)134 static void openssl_locking_function(int mode, int n, const char *file, int line)
135 {
136 	int lock;
137 
138 	GIT_UNUSED(file);
139 	GIT_UNUSED(line);
140 
141 	lock = mode & CRYPTO_LOCK;
142 
143 	if (lock)
144 		(void)git_mutex_lock(&openssl_locks[n]);
145 	else
146 		git_mutex_unlock(&openssl_locks[n]);
147 }
148 
shutdown_ssl_locking(void)149 static void shutdown_ssl_locking(void)
150 {
151 	int num_locks, i;
152 
153 	num_locks = CRYPTO_num_locks();
154 	CRYPTO_set_locking_callback(NULL);
155 
156 	for (i = 0; i < num_locks; ++i)
157 		git_mutex_free(&openssl_locks[i]);
158 	git__free(openssl_locks);
159 }
160 
threadid_cb(CRYPTO_THREADID * threadid)161 static void threadid_cb(CRYPTO_THREADID *threadid)
162 {
163 	GIT_UNUSED(threadid);
164 	CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid());
165 }
166 
git_openssl_set_locking(void)167 int git_openssl_set_locking(void)
168 {
169 	int num_locks, i;
170 
171 #ifndef GIT_THREADS
172 	git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads");
173 	return -1;
174 #endif
175 
176 #ifdef GIT_OPENSSL_DYNAMIC
177 	/*
178 	 * This function is required on legacy versions of OpenSSL; when building
179 	 * with dynamically-loaded OpenSSL, we detect whether we loaded it or not.
180 	 */
181 	if (!CRYPTO_set_locking_callback)
182 		return 0;
183 #endif
184 
185 	CRYPTO_THREADID_set_callback(threadid_cb);
186 
187 	num_locks = CRYPTO_num_locks();
188 	openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
189 	GIT_ERROR_CHECK_ALLOC(openssl_locks);
190 
191 	for (i = 0; i < num_locks; i++) {
192 		if (git_mutex_init(&openssl_locks[i]) != 0) {
193 			git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks");
194 			return -1;
195 		}
196 	}
197 
198 	CRYPTO_set_locking_callback(openssl_locking_function);
199 	return git_runtime_shutdown_register(shutdown_ssl_locking);
200 }
201 #endif /* GIT_THREADS */
202 
203 #endif /* GIT_OPENSSL_LEGACY || GIT_OPENSSL_DYNAMIC */
204