1 /* Copyright 2015 Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  *
17  * --
18  *
19  * This file transparently wraps lazy-loading hooks in the schannel
20  * implementation on top of the PolarSSL/mbedTLS open source library.
21  */
22 
23 static void *libmbedtls_handle;
24 
25 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
26 
27 MAKE_FUNCPTR(mbedtls_ctr_drbg_free)
MAKE_FUNCPTR(mbedtls_ctr_drbg_init)28 MAKE_FUNCPTR(mbedtls_ctr_drbg_init)
29 MAKE_FUNCPTR(mbedtls_ctr_drbg_random)
30 MAKE_FUNCPTR(mbedtls_entropy_free)
31 MAKE_FUNCPTR(mbedtls_entropy_func)
32 MAKE_FUNCPTR(mbedtls_entropy_init)
33 MAKE_FUNCPTR(mbedtls_ssl_ciphersuite_from_id)
34 MAKE_FUNCPTR(mbedtls_ssl_free)
35 MAKE_FUNCPTR(mbedtls_ssl_get_ciphersuite)
36 MAKE_FUNCPTR(mbedtls_ssl_get_ciphersuite_id)
37 MAKE_FUNCPTR(mbedtls_ssl_get_max_frag_len)
38 MAKE_FUNCPTR(mbedtls_ssl_get_version)
39 MAKE_FUNCPTR(mbedtls_ssl_handshake)
40 MAKE_FUNCPTR(mbedtls_ssl_init)
41 MAKE_FUNCPTR(mbedtls_ssl_read)
42 MAKE_FUNCPTR(mbedtls_ssl_conf_authmode)
43 MAKE_FUNCPTR(mbedtls_ssl_set_bio)
44 MAKE_FUNCPTR(mbedtls_ssl_conf_endpoint)
45 MAKE_FUNCPTR(mbedtls_ssl_set_hostname)
46 MAKE_FUNCPTR(mbedtls_ssl_conf_max_version)
47 MAKE_FUNCPTR(mbedtls_ssl_conf_min_version)
48 MAKE_FUNCPTR(mbedtls_ssl_conf_rng)
49 MAKE_FUNCPTR(mbedtls_ssl_write)
50 MAKE_FUNCPTR(mbedtls_ssl_get_peer_cert)
51 MAKE_FUNCPTR(mbedtls_ssl_config_init)
52 MAKE_FUNCPTR(mbedtls_ssl_config_free)
53 MAKE_FUNCPTR(mbedtls_ssl_config_defaults)
54 MAKE_FUNCPTR(mbedtls_ssl_conf_dbg)
55 MAKE_FUNCPTR(mbedtls_ssl_setup)
56 MAKE_FUNCPTR(mbedtls_cipher_info_from_type)
57 MAKE_FUNCPTR(mbedtls_md_info_from_type)
58 MAKE_FUNCPTR(mbedtls_pk_get_bitlen)
59 MAKE_FUNCPTR(mbedtls_ctr_drbg_seed)
60 
61 #undef MAKE_FUNCPTR
62 
63 /* replace the initialization functions by our own, specially tailored, ones */
64 
65 BOOL schan_imp_init(void)
66 {
67     libmbedtls_handle = wine_dlopen(SONAME_LIBMBEDTLS, RTLD_NOW, NULL, 0);
68 
69     if (!libmbedtls_handle)
70     {
71         WARN("Failed to load the mbedTLS dynamic library (" SONAME_LIBMBEDTLS ").\n");
72         return FALSE;
73     }
74 
75 #define LOAD_FUNCPTR(f) \
76     if (!(p##f = wine_dlsym(libmbedtls_handle, #f, NULL, 0))) \
77     { \
78         ERR("Failed to retrieve function %s from the mbedTLS dynamic library (" SONAME_LIBMBEDTLS ")\n", #f); \
79         goto fail; \
80     }
81 
82     LOAD_FUNCPTR(mbedtls_ctr_drbg_free)
83     LOAD_FUNCPTR(mbedtls_ctr_drbg_init)
84     LOAD_FUNCPTR(mbedtls_ctr_drbg_random)
85     LOAD_FUNCPTR(mbedtls_entropy_free)
86     LOAD_FUNCPTR(mbedtls_entropy_func)
87     LOAD_FUNCPTR(mbedtls_entropy_init)
88     LOAD_FUNCPTR(mbedtls_ssl_ciphersuite_from_id)
89     LOAD_FUNCPTR(mbedtls_ssl_free)
90     LOAD_FUNCPTR(mbedtls_ssl_get_ciphersuite)
91     LOAD_FUNCPTR(mbedtls_ssl_get_ciphersuite_id)
92     LOAD_FUNCPTR(mbedtls_ssl_get_max_frag_len)
93     LOAD_FUNCPTR(mbedtls_ssl_get_version)
94     LOAD_FUNCPTR(mbedtls_ssl_handshake)
95     LOAD_FUNCPTR(mbedtls_ssl_init)
96     LOAD_FUNCPTR(mbedtls_ssl_read)
97     LOAD_FUNCPTR(mbedtls_ssl_conf_authmode)
98     LOAD_FUNCPTR(mbedtls_ssl_set_bio)
99     LOAD_FUNCPTR(mbedtls_ssl_conf_endpoint)
100     LOAD_FUNCPTR(mbedtls_ssl_set_hostname)
101     LOAD_FUNCPTR(mbedtls_ssl_conf_max_version)
102     LOAD_FUNCPTR(mbedtls_ssl_conf_min_version)
103     LOAD_FUNCPTR(mbedtls_ssl_conf_rng)
104     LOAD_FUNCPTR(mbedtls_ssl_write)
105     LOAD_FUNCPTR(mbedtls_ssl_get_peer_cert)
106     LOAD_FUNCPTR(mbedtls_ssl_config_init)
107     LOAD_FUNCPTR(mbedtls_ssl_config_free)
108     LOAD_FUNCPTR(mbedtls_ssl_config_defaults)
109     LOAD_FUNCPTR(mbedtls_ssl_conf_dbg)
110     LOAD_FUNCPTR(mbedtls_ssl_setup)
111     LOAD_FUNCPTR(mbedtls_cipher_info_from_type)
112     LOAD_FUNCPTR(mbedtls_md_info_from_type)
113     LOAD_FUNCPTR(mbedtls_pk_get_bitlen)
114     LOAD_FUNCPTR(mbedtls_ctr_drbg_seed)
115 
116 #undef LOAD_FUNCPTR
117 
118     return TRUE;
119 
120 fail:
121 
122     wine_dlclose(libmbedtls_handle, NULL, 0);
123     libmbedtls_handle = NULL;
124 
125     return FALSE;
126 }
127 
schan_imp_deinit(void)128 void schan_imp_deinit(void)
129 {
130     wine_dlclose(libmbedtls_handle, NULL, 0);
131     libmbedtls_handle = NULL;
132 }
133 
134 /* now that we have overridden the initialization functions
135    cancel out the original stubs used when dynamically linking */
136 
137 #define schan_imp_init                  schan_imp_init_unused
138 #define schan_imp_deinit                schan_imp_deinit_unused
139 
140 /* seamlessly redirect the function pointers with some preprocessor magic */
141 
142 #define mbedtls_ctr_drbg_free           pmbedtls_ctr_drbg_free
143 #define mbedtls_ctr_drbg_init           pmbedtls_ctr_drbg_init
144 #define mbedtls_ctr_drbg_random         pmbedtls_ctr_drbg_random
145 #define mbedtls_entropy_free            pmbedtls_entropy_free
146 #define mbedtls_entropy_func            pmbedtls_entropy_func
147 #define mbedtls_entropy_init            pmbedtls_entropy_init
148 #define mbedtls_ssl_ciphersuite_from_id pmbedtls_ssl_ciphersuite_from_id
149 #define mbedtls_ssl_free                pmbedtls_ssl_free
150 #define mbedtls_ssl_get_ciphersuite     pmbedtls_ssl_get_ciphersuite
151 #define mbedtls_ssl_get_ciphersuite_id  pmbedtls_ssl_get_ciphersuite_id
152 #define mbedtls_ssl_get_max_frag_len    pmbedtls_ssl_get_max_frag_len
153 #define mbedtls_ssl_get_version         pmbedtls_ssl_get_version
154 #define mbedtls_ssl_handshake           pmbedtls_ssl_handshake
155 #define mbedtls_ssl_init                pmbedtls_ssl_init
156 #define mbedtls_ssl_read                pmbedtls_ssl_read
157 #define mbedtls_ssl_conf_authmode       pmbedtls_ssl_conf_authmode
158 #define mbedtls_ssl_set_bio             pmbedtls_ssl_set_bio
159 #define mbedtls_ssl_conf_endpoint       pmbedtls_ssl_conf_endpoint
160 #define mbedtls_ssl_set_hostname        pmbedtls_ssl_set_hostname
161 #define mbedtls_ssl_conf_max_version    pmbedtls_ssl_conf_max_version
162 #define mbedtls_ssl_conf_min_version    pmbedtls_ssl_conf_min_version
163 #define mbedtls_ssl_conf_rng            pmbedtls_ssl_conf_rng
164 #define mbedtls_ssl_write               pmbedtls_ssl_write
165 #define mbedtls_ssl_get_peer_cert       pmbedtls_ssl_get_peer_cert
166 #define mbedtls_ssl_config_init         pmbedtls_ssl_config_init
167 #define mbedtls_ssl_config_free         pmbedtls_ssl_config_free
168 #define mbedtls_ssl_config_defaults     pmbedtls_ssl_config_defaults
169 #define mbedtls_ssl_conf_dbg            pmbedtls_ssl_conf_dbg
170 #define mbedtls_ssl_setup               pmbedtls_ssl_setup
171 #define mbedtls_cipher_info_from_type   pmbedtls_cipher_info_from_type
172 #define mbedtls_md_info_from_type       pmbedtls_md_info_from_type
173 #define mbedtls_pk_get_bitlen           pmbedtls_pk_get_bitlen
174 #define mbedtls_ctr_drbg_seed           pmbedtls_ctr_drbg_seed
175