Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / btls / btls-ssl.c
1 //
2 //  btls-ssl.c
3 //  MonoBtls
4 //
5 //  Created by Martin Baulig on 14/11/15.
6 //  Copyright (c) 2015 Xamarin. All rights reserved.
7 //
8
9 #include <btls-ssl.h>
10 #include <btls-x509-verify-param.h>
11
12 struct MonoBtlsSsl {
13         MonoBtlsSslCtx *ctx;
14         SSL *ssl;
15 };
16
17 #define debug_print(ptr,message) \
18 do { if (mono_btls_ssl_ctx_is_debug_enabled(ptr->ctx)) \
19 mono_btls_ssl_ctx_debug_printf (ptr->ctx, "%s:%d:%s(): " message, __FILE__, __LINE__, \
20 __func__); } while (0)
21
22 #define debug_printf(ptr,fmt, ...) \
23 do { if (mono_btls_ssl_ctx_is_debug_enabled(ptr->ctx)) \
24 mono_btls_ssl_ctx_debug_printf (ptr->ctx, "%s:%d:%s(): " fmt, __FILE__, __LINE__, \
25 __func__, __VA_ARGS__); } while (0)
26
27 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list (SSL *s, const CBS *cbs);
28
29 MONO_API MonoBtlsSsl *
30 mono_btls_ssl_new (MonoBtlsSslCtx *ctx)
31 {
32         MonoBtlsSsl *ptr;
33
34         ptr = calloc (1, sizeof (MonoBtlsSsl));
35
36         ptr->ctx = mono_btls_ssl_ctx_up_ref (ctx);
37         ptr->ssl = SSL_new (mono_btls_ssl_ctx_get_ctx (ptr->ctx));
38
39         return ptr;
40 }
41
42 MONO_API void
43 mono_btls_ssl_destroy (MonoBtlsSsl *ptr)
44 {
45         mono_btls_ssl_close (ptr);
46         if (ptr->ssl) {
47                 SSL_free (ptr->ssl);
48                 ptr->ssl = NULL;
49         }
50         if (ptr->ctx) {
51                 mono_btls_ssl_ctx_free (ptr->ctx);
52                 ptr->ctx = NULL;
53         }
54         free (ptr);
55 }
56
57 MONO_API void
58 mono_btls_ssl_close (MonoBtlsSsl *ptr)
59 {
60         ;
61 }
62
63 MONO_API int
64 mono_btls_ssl_shutdown (MonoBtlsSsl *ptr)
65 {
66     return SSL_shutdown (ptr->ssl);
67 }
68
69 MONO_API void
70 mono_btls_ssl_set_quiet_shutdown (MonoBtlsSsl *ptr, int mode)
71 {
72     SSL_set_quiet_shutdown (ptr->ssl, mode);
73 }
74
75 MONO_API void
76 mono_btls_ssl_set_bio (MonoBtlsSsl *ptr, BIO *bio)
77 {
78         BIO_up_ref (bio);
79         SSL_set_bio (ptr->ssl, bio, bio);
80 }
81
82 MONO_API void
83 mono_btls_ssl_print_errors_cb (ERR_print_errors_callback_t callback, void *ctx)
84 {
85         ERR_print_errors_cb (callback, ctx);
86 }
87
88 MONO_API int
89 mono_btls_ssl_use_certificate (MonoBtlsSsl *ptr, X509 *x509)
90 {
91         return SSL_use_certificate (ptr->ssl, x509);
92 }
93
94 MONO_API int
95 mono_btls_ssl_use_private_key (MonoBtlsSsl *ptr, EVP_PKEY *key)
96 {
97         return SSL_use_PrivateKey (ptr->ssl, key);
98 }
99
100 MONO_API int
101 mono_btls_ssl_add_chain_certificate (MonoBtlsSsl *ptr, X509 *x509)
102 {
103         return SSL_add1_chain_cert (ptr->ssl, x509);
104 }
105
106 MONO_API int
107 mono_btls_ssl_accept (MonoBtlsSsl *ptr)
108 {
109         return SSL_accept (ptr->ssl);
110 }
111
112 MONO_API int
113 mono_btls_ssl_connect (MonoBtlsSsl *ptr)
114 {
115         return SSL_connect (ptr->ssl);
116 }
117
118 MONO_API int
119 mono_btls_ssl_handshake (MonoBtlsSsl *ptr)
120 {
121         return SSL_do_handshake (ptr->ssl);
122 }
123
124 MONO_API int
125 mono_btls_ssl_read (MonoBtlsSsl *ptr, void *buf, int count)
126 {
127         return SSL_read (ptr->ssl, buf, count);
128 }
129
130 MONO_API int
131 mono_btls_ssl_write (MonoBtlsSsl *ptr, void *buf, int count)
132 {
133         return SSL_write (ptr->ssl, buf, count);
134 }
135
136 MONO_API int
137 mono_btls_ssl_get_version (MonoBtlsSsl *ptr)
138 {
139         return SSL_version (ptr->ssl);
140 }
141
142 MONO_API void
143 mono_btls_ssl_set_min_version (MonoBtlsSsl *ptr, int version)
144 {
145         SSL_set_min_version (ptr->ssl, version);
146 }
147
148 MONO_API void
149 mono_btls_ssl_set_max_version (MonoBtlsSsl *ptr, int version)
150 {
151         SSL_set_max_version (ptr->ssl, version);
152 }
153
154 MONO_API int
155 mono_btls_ssl_get_cipher (MonoBtlsSsl *ptr)
156 {
157         const SSL_CIPHER *cipher;
158
159         cipher = SSL_get_current_cipher (ptr->ssl);
160         if (!cipher)
161                 return 0;
162         return (uint16_t)SSL_CIPHER_get_id (cipher);
163 }
164
165 MONO_API int
166 mono_btls_ssl_set_cipher_list (MonoBtlsSsl *ptr, const char *str)
167 {
168         return SSL_set_cipher_list(ptr->ssl, str);
169 }
170
171 MONO_API int
172 mono_btls_ssl_get_ciphers (MonoBtlsSsl *ptr, uint16_t **data)
173 {
174         STACK_OF(SSL_CIPHER) *ciphers;
175         int count, i;
176
177         *data = NULL;
178
179         ciphers = SSL_get_ciphers (ptr->ssl);
180         if (!ciphers)
181                 return 0;
182
183         count = (int)sk_SSL_CIPHER_num (ciphers);
184
185         *data = OPENSSL_malloc (2 * count);
186         if (!*data)
187                 return 0;
188
189         for (i = 0; i < count; i++) {
190                 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value (ciphers, i);
191                 (*data) [i] = (uint16_t) SSL_CIPHER_get_id (cipher);
192         }
193
194         return count;
195 }
196
197 MONO_API X509 *
198 mono_btls_ssl_get_peer_certificate (MonoBtlsSsl *ptr)
199 {
200         return SSL_get_peer_certificate (ptr->ssl);
201 }
202
203 MONO_API int
204 mono_btls_ssl_get_error (MonoBtlsSsl *ptr, int ret_code)
205 {
206         return SSL_get_error (ptr->ssl, ret_code);
207 }
208
209 MONO_API int
210 mono_btls_ssl_set_verify_param (MonoBtlsSsl *ptr, const MonoBtlsX509VerifyParam *param)
211 {
212         return SSL_set1_param (ptr->ssl, mono_btls_x509_verify_param_peek_param (param));
213 }
214
215 MONO_API int
216 mono_btls_ssl_set_server_name (MonoBtlsSsl *ptr, const char *name)
217 {
218         return SSL_set_tlsext_host_name (ptr->ssl, name);
219 }
220
221 MONO_API const char *
222 mono_btls_ssl_get_server_name (MonoBtlsSsl *ptr)
223 {
224         return SSL_get_servername (ptr->ssl, TLSEXT_NAMETYPE_host_name);
225 }
226
227 MONO_API void
228 mono_btls_ssl_set_renegotiate_mode (MonoBtlsSsl *ptr, MonoBtlsSslRenegotiateMode mode)
229 {
230     SSL_set_renegotiate_mode (ptr->ssl, (enum ssl_renegotiate_mode_t)mode);
231 }
232
233 MONO_API int
234 mono_btls_ssl_renegotiate_pending (MonoBtlsSsl *ptr)
235 {
236     return SSL_renegotiate_pending (ptr->ssl);
237 }
238