Merge pull request #3705 from BrzVlad/fix-sgen-internal-alloc
[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 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         SSL_set_options (ptr->ssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
40
41         return ptr;
42 }
43
44 void
45 mono_btls_ssl_destroy (MonoBtlsSsl *ptr)
46 {
47         mono_btls_ssl_close (ptr);
48         if (ptr->ssl) {
49                 SSL_free (ptr->ssl);
50                 ptr->ssl = NULL;
51         }
52         if (ptr->ctx) {
53                 mono_btls_ssl_ctx_free (ptr->ctx);
54                 ptr->ctx = NULL;
55         }
56         free (ptr);
57 }
58
59 void
60 mono_btls_ssl_close (MonoBtlsSsl *ptr)
61 {
62         ;
63 }
64
65 void
66 mono_btls_ssl_set_bio (MonoBtlsSsl *ptr, BIO *bio)
67 {
68         BIO_up_ref (bio);
69         SSL_set_bio (ptr->ssl, bio, bio);
70 }
71
72 void
73 mono_btls_ssl_print_errors_cb (ERR_print_errors_callback_t callback, void *ctx)
74 {
75         ERR_print_errors_cb (callback, ctx);
76 }
77
78 int
79 mono_btls_ssl_use_certificate (MonoBtlsSsl *ptr, X509 *x509)
80 {
81         return SSL_use_certificate (ptr->ssl, x509);
82 }
83
84 int
85 mono_btls_ssl_use_private_key (MonoBtlsSsl *ptr, EVP_PKEY *key)
86 {
87         return SSL_use_PrivateKey (ptr->ssl, key);
88 }
89
90 int
91 mono_btls_ssl_add_chain_certificate (MonoBtlsSsl *ptr, X509 *x509)
92 {
93         return SSL_add1_chain_cert (ptr->ssl, x509);
94 }
95
96 int
97 mono_btls_ssl_accept (MonoBtlsSsl *ptr)
98 {
99         return SSL_accept (ptr->ssl);
100 }
101
102 int
103 mono_btls_ssl_connect (MonoBtlsSsl *ptr)
104 {
105         return SSL_connect (ptr->ssl);
106 }
107
108 int
109 mono_btls_ssl_handshake (MonoBtlsSsl *ptr)
110 {
111         return SSL_do_handshake (ptr->ssl);
112 }
113
114 int
115 mono_btls_ssl_read (MonoBtlsSsl *ptr, void *buf, int count)
116 {
117         return SSL_read (ptr->ssl, buf, count);
118 }
119
120 int
121 mono_btls_ssl_write (MonoBtlsSsl *ptr, void *buf, int count)
122 {
123         return SSL_write (ptr->ssl, buf, count);
124 }
125
126 int
127 mono_btls_ssl_get_version (MonoBtlsSsl *ptr)
128 {
129         return SSL_version (ptr->ssl);
130 }
131
132 void
133 mono_btls_ssl_set_min_version (MonoBtlsSsl *ptr, int version)
134 {
135         SSL_set_min_version (ptr->ssl, version);
136 }
137
138 void
139 mono_btls_ssl_set_max_version (MonoBtlsSsl *ptr, int version)
140 {
141         SSL_set_max_version (ptr->ssl, version);
142 }
143
144 int
145 mono_btls_ssl_get_cipher (MonoBtlsSsl *ptr)
146 {
147         const SSL_CIPHER *cipher;
148
149         cipher = SSL_get_current_cipher (ptr->ssl);
150         if (!cipher)
151                 return 0;
152         return (uint16_t)SSL_CIPHER_get_id (cipher);
153 }
154
155 int
156 mono_btls_ssl_set_cipher_list (MonoBtlsSsl *ptr, const char *str)
157 {
158         return SSL_set_cipher_list(ptr->ssl, str);
159 }
160
161 int
162 mono_btls_ssl_get_ciphers (MonoBtlsSsl *ptr, uint16_t **data)
163 {
164         STACK_OF(SSL_CIPHER) *ciphers;
165         int count, i;
166
167         *data = NULL;
168
169         ciphers = SSL_get_ciphers (ptr->ssl);
170         if (!ciphers)
171                 return 0;
172
173         count = (int)sk_SSL_CIPHER_num (ciphers);
174
175         *data = OPENSSL_malloc (2 * count);
176         if (!*data)
177                 return 0;
178
179         for (i = 0; i < count; i++) {
180                 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value (ciphers, i);
181                 (*data) [i] = (uint16_t) SSL_CIPHER_get_id (cipher);
182         }
183
184         return count;
185 }
186
187 X509 *
188 mono_btls_ssl_get_peer_certificate (MonoBtlsSsl *ptr)
189 {
190         return SSL_get_peer_certificate (ptr->ssl);
191 }
192
193 int
194 mono_btls_ssl_get_error (MonoBtlsSsl *ptr, int ret_code)
195 {
196         return SSL_get_error (ptr->ssl, ret_code);
197 }
198
199 int
200 mono_btls_ssl_set_verify_param (MonoBtlsSsl *ptr, const MonoBtlsX509VerifyParam *param)
201 {
202         return SSL_set1_param (ptr->ssl, mono_btls_x509_verify_param_peek_param (param));
203 }
204
205 int
206 mono_btls_ssl_set_server_name (MonoBtlsSsl *ptr, const char *name)
207 {
208         return SSL_set_tlsext_host_name (ptr->ssl, name);
209 }