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