File Coverage

deps/libgit2/src/libgit2/streams/openssl_legacy.c
Criterion Covered Total %
statement 0 83 0.0
branch 0 14 0.0
condition n/a
subroutine n/a
pod n/a
total 0 97 0.0


line stmt bran cond sub pod time code
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
16             # include
17             # include
18             # include
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              
30 0           int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings)
31             {
32 0           GIT_UNUSED(opts);
33 0           GIT_UNUSED(settings);
34 0           SSL_load_error_strings();
35 0           SSL_library_init();
36 0           return 0;
37             }
38              
39 0           BIO_METHOD *BIO_meth_new__legacy(int type, const char *name)
40             {
41 0           BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
42 0 0         if (!meth) {
43 0           return NULL;
44             }
45              
46 0           meth->type = type;
47 0           meth->name = name;
48              
49 0           return meth;
50             }
51              
52 0           void BIO_meth_free__legacy(BIO_METHOD *biom)
53             {
54 0           git__free(biom);
55 0           }
56              
57 0           int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
58             {
59 0           biom->bwrite = write;
60 0           return 1;
61             }
62              
63 0           int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
64             {
65 0           biom->bread = read;
66 0           return 1;
67             }
68              
69 0           int BIO_meth_set_puts__legacy(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
70             {
71 0           biom->bputs = puts;
72 0           return 1;
73             }
74              
75 0           int BIO_meth_set_gets__legacy(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))
76              
77             {
78 0           biom->bgets = gets;
79 0           return 1;
80             }
81              
82 0           int BIO_meth_set_ctrl__legacy(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
83             {
84 0           biom->ctrl = ctrl;
85 0           return 1;
86             }
87              
88 0           int BIO_meth_set_create__legacy(BIO_METHOD *biom, int (*create) (BIO *))
89             {
90 0           biom->create = create;
91 0           return 1;
92             }
93              
94 0           int BIO_meth_set_destroy__legacy(BIO_METHOD *biom, int (*destroy) (BIO *))
95             {
96 0           biom->destroy = destroy;
97 0           return 1;
98             }
99              
100 0           int BIO_get_new_index__legacy(void)
101             {
102             /* This exists as of 1.1 so before we'd just have 0 */
103 0           return 0;
104             }
105              
106 0           void BIO_set_init__legacy(BIO *b, int init)
107             {
108 0           b->init = init;
109 0           }
110              
111 0           void BIO_set_data__legacy(BIO *a, void *ptr)
112             {
113 0           a->ptr = ptr;
114 0           }
115              
116 0           void *BIO_get_data__legacy(BIO *a)
117             {
118 0           return a->ptr;
119             }
120              
121 0           const unsigned char *ASN1_STRING_get0_data__legacy(const ASN1_STRING *x)
122             {
123 0           return ASN1_STRING_data((ASN1_STRING *)x);
124             }
125              
126 0           long SSL_CTX_set_options__legacy(SSL_CTX *ctx, long op)
127             {
128 0           return SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, op, NULL);
129             }
130              
131             # if defined(GIT_THREADS)
132             static git_mutex *openssl_locks;
133              
134 0           static void openssl_locking_function(int mode, int n, const char *file, int line)
135             {
136             int lock;
137              
138 0           GIT_UNUSED(file);
139 0           GIT_UNUSED(line);
140              
141 0           lock = mode & CRYPTO_LOCK;
142              
143 0 0         if (lock)
144 0           (void)git_mutex_lock(&openssl_locks[n]);
145             else
146 0           git_mutex_unlock(&openssl_locks[n]);
147 0           }
148              
149 0           static void shutdown_ssl_locking(void)
150             {
151             int num_locks, i;
152              
153 0           num_locks = CRYPTO_num_locks();
154 0           CRYPTO_set_locking_callback(NULL);
155              
156 0 0         for (i = 0; i < num_locks; ++i)
157 0           git_mutex_free(&openssl_locks[i]);
158 0           git__free(openssl_locks);
159 0           }
160              
161 0           static void threadid_cb(CRYPTO_THREADID *threadid)
162             {
163 0           GIT_UNUSED(threadid);
164 0           CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid());
165 0           }
166              
167 0           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 0 0         if (!CRYPTO_set_locking_callback)
182 0           return 0;
183             #endif
184              
185 0           CRYPTO_THREADID_set_callback(threadid_cb);
186              
187 0           num_locks = CRYPTO_num_locks();
188 0           openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
189 0 0         GIT_ERROR_CHECK_ALLOC(openssl_locks);
190              
191 0 0         for (i = 0; i < num_locks; i++) {
192 0 0         if (git_mutex_init(&openssl_locks[i]) != 0) {
193 0           git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks");
194 0           return -1;
195             }
196             }
197              
198 0           CRYPTO_set_locking_callback(openssl_locking_function);
199 0           return git_runtime_shutdown_register(shutdown_ssl_locking);
200             }
201             #endif /* GIT_THREADS */
202              
203             #endif /* GIT_OPENSSL_LEGACY || GIT_OPENSSL_DYNAMIC */