Add tizen dlog for debugging
[platform/upstream/glib-networking.git] / tls / openssl / gtlsconnection-openssl.c
1 /*
2  * gtlsconnection-openssl.c
3  *
4  * Copyright (C) 2015 NICE s.r.l.
5  *
6  * This file is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This file is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * In addition, when the library is used with OpenSSL, a special
20  * exception applies. Refer to the LICENSE_EXCEPTION file for details.
21  *
22  * Authors: Ignacio Casal Quinteiro
23  */
24
25 #include "config.h"
26 #include "glib.h"
27
28 #include <errno.h>
29 #include <stdarg.h>
30 #include "openssl-include.h"
31
32 #include "gtlsconnection-openssl.h"
33 #include "gtlsbackend-openssl.h"
34 #include "gtlscertificate-openssl.h"
35 #include "gtlsfiledatabase-openssl.h"
36 #include "gtlsbio.h"
37
38 #include <glib/gi18n-lib.h>
39
40 typedef struct _GTlsConnectionOpensslPrivate
41 {
42   BIO *bio;
43
44   GTlsCertificate *peer_certificate_tmp;
45   GTlsCertificateFlags peer_certificate_errors_tmp;
46
47   gboolean shutting_down;
48 } GTlsConnectionOpensslPrivate;
49
50 static void g_tls_connection_openssl_initable_iface_init (GInitableIface *iface);
51
52 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionOpenssl, g_tls_connection_openssl, G_TYPE_TLS_CONNECTION_BASE,
53                                   G_ADD_PRIVATE (GTlsConnectionOpenssl)
54                                   G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
55                                                          g_tls_connection_openssl_initable_iface_init))
56
57 static void
58 g_tls_connection_openssl_finalize (GObject *object)
59 {
60   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (object);
61   GTlsConnectionOpensslPrivate *priv;
62
63   priv = g_tls_connection_openssl_get_instance_private (openssl);
64
65   g_clear_object (&priv->peer_certificate_tmp);
66
67   G_OBJECT_CLASS (g_tls_connection_openssl_parent_class)->finalize (object);
68 }
69
70 static GTlsConnectionBaseStatus
71 end_openssl_io (GTlsConnectionOpenssl  *openssl,
72                 GIOCondition           direction,
73                 int                    ret,
74                 GError               **error,
75                 const char            *err_fmt,
76                 ...) G_GNUC_PRINTF(5, 6);
77
78 static GTlsConnectionBaseStatus
79 end_openssl_io (GTlsConnectionOpenssl  *openssl,
80                 GIOCondition            direction,
81                 int                     ret,
82                 GError                **error,
83                 const char             *err_fmt,
84                 ...)
85 {
86   GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (openssl);
87   GTlsConnectionOpensslPrivate *priv;
88   int err_code, err, err_lib, reason;
89   GError *my_error = NULL;
90   GTlsConnectionBaseStatus status;
91   SSL *ssl;
92
93   priv = g_tls_connection_openssl_get_instance_private (openssl);
94
95   ssl = g_tls_connection_openssl_get_ssl (openssl);
96
97   err_code = SSL_get_error (ssl, ret);
98
99   status = g_tls_connection_base_pop_io (tls, direction, ret > 0, &my_error);
100
101   /* NOTE: this is tricky! The tls bio will set to retry if the operation
102    * would block, and we would get an error code with WANT_READ or WANT_WRITE,
103    * though if in that case we try again we would end up in an infinite loop
104    * since we will not let the glib main loop to do its stuff and we would
105    * be getting a would block forever. Instead we need to also check the error
106    * we get from the socket operation to understand whether to try again. See
107    * that we propagate the WOULD_BLOCK error a bit more down.
108    */
109   if ((err_code == SSL_ERROR_WANT_READ ||
110        err_code == SSL_ERROR_WANT_WRITE) &&
111       status != G_TLS_CONNECTION_BASE_WOULD_BLOCK)
112     {
113       if (my_error)
114         g_error_free (my_error);
115       return G_TLS_CONNECTION_BASE_TRY_AGAIN;
116     }
117
118   if (err_code == SSL_ERROR_ZERO_RETURN)
119     return G_TLS_CONNECTION_BASE_OK;
120
121   if (status == G_TLS_CONNECTION_BASE_OK ||
122       status == G_TLS_CONNECTION_BASE_WOULD_BLOCK ||
123       status == G_TLS_CONNECTION_BASE_TIMED_OUT)
124     {
125       if (my_error)
126         g_propagate_error (error, my_error);
127       return status;
128     }
129
130   /* This case is documented that it may happen and that is perfectly fine */
131   if (err_code == SSL_ERROR_SYSCALL && priv->shutting_down && !my_error)
132     return G_TLS_CONNECTION_BASE_OK;
133
134   err = ERR_get_error ();
135   err_lib = ERR_GET_LIB (err);
136   reason = ERR_GET_REASON (err);
137
138   if (tls->handshaking && !tls->ever_handshaked)
139     {
140       if (reason == SSL_R_BAD_PACKET_LENGTH ||
141           reason == SSL_R_UNKNOWN_ALERT_TYPE ||
142           reason == SSL_R_DECRYPTION_FAILED ||
143           reason == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC ||
144           reason == SSL_R_BAD_PROTOCOL_VERSION_NUMBER ||
145           reason == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE ||
146           reason == SSL_R_UNKNOWN_PROTOCOL)
147         {
148           g_clear_error (&my_error);
149           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
150                                _("Peer failed to perform TLS handshake"));
151           return G_TLS_CONNECTION_BASE_ERROR;
152         }
153     }
154
155 #ifdef SSL_R_SHUTDOWN_WHILE_IN_INIT
156   /* XXX: this error happens on ubuntu when shutting down the connection, it
157    * seems to be a bug in a specific version of openssl, so let's handle it
158    * gracefully
159    */
160   if (reason == SSL_R_SHUTDOWN_WHILE_IN_INIT)
161     {
162       g_clear_error (&my_error);
163       return G_TLS_CONNECTION_BASE_OK;
164     }
165 #endif
166
167   if (reason == SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
168 #ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED
169       || reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED
170 #endif
171      )
172     {
173       g_clear_error (&my_error);
174       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
175                            _("TLS connection peer did not send a certificate"));
176       return status;
177     }
178
179   if (err_lib == ERR_LIB_RSA && reason == RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY)
180     {
181       g_clear_error (&my_error);
182       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
183                            _("Digest too big for RSA key"));
184       return G_TLS_CONNECTION_BASE_ERROR;
185     }
186
187   if (my_error != NULL)
188     g_propagate_error (error, my_error);
189   else
190     /* FIXME: this is just for debug */
191     g_message ("end_openssl_io %s: %d, %d, %d", G_IS_TLS_CLIENT_CONNECTION (openssl) ? "client" : "server", err_code, err_lib, reason);
192
193   if (error && !*error)
194     {
195       va_list ap;
196
197       va_start (ap, err_fmt);
198       *error = g_error_new_valist (G_TLS_ERROR, G_TLS_ERROR_MISC, err_fmt, ap);
199       va_end (ap);
200     }
201
202   return G_TLS_CONNECTION_BASE_ERROR;
203 }
204
205 #define BEGIN_OPENSSL_IO(openssl, direction, blocking, cancellable)        \
206   g_tls_connection_base_push_io (G_TLS_CONNECTION_BASE (openssl),        \
207                                  direction, blocking, cancellable);        \
208   do {                                                                      \
209     char error_str[256];
210
211 #define END_OPENSSL_IO(openssl, direction, ret, status, errmsg, err)        \
212     ERR_error_string_n (SSL_get_error (ssl, ret), error_str, sizeof(error_str)); \
213     status = end_openssl_io (openssl, direction, ret, err, errmsg, error_str); \
214   } while (status == G_TLS_CONNECTION_BASE_TRY_AGAIN);
215
216 static GTlsConnectionBaseStatus
217 g_tls_connection_openssl_request_rehandshake (GTlsConnectionBase  *tls,
218                                               GCancellable        *cancellable,
219                                               GError             **error)
220 {
221   GTlsConnectionOpenssl *openssl;
222   GTlsConnectionBaseStatus status;
223   SSL *ssl;
224   int ret;
225
226   /* On a client-side connection, SSL_renegotiate() itself will start
227    * a rehandshake, so we only need to do something special here for
228    * server-side connections.
229    */
230   if (!G_IS_TLS_SERVER_CONNECTION (tls))
231     return G_TLS_CONNECTION_BASE_OK;
232
233   openssl = G_TLS_CONNECTION_OPENSSL (tls);
234
235   if (tls->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
236     {
237       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
238                            _("Peer requested illegal TLS rehandshake"));
239       return G_TLS_CONNECTION_BASE_ERROR;
240     }
241
242   ssl = g_tls_connection_openssl_get_ssl (openssl);
243
244   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
245   ret = SSL_renegotiate (ssl);
246   END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
247                   _("Error performing TLS handshake: %s"), error);
248
249   return status;
250 }
251
252 static GTlsCertificate *
253 get_peer_certificate (GTlsConnectionOpenssl *openssl)
254 {
255   X509 *peer;
256   STACK_OF (X509) *certs;
257   GTlsCertificateOpenssl *chain;
258   SSL *ssl;
259
260   ssl = g_tls_connection_openssl_get_ssl (openssl);
261
262   peer = SSL_get_peer_certificate (ssl);
263   if (peer == NULL)
264     return NULL;
265
266   certs = SSL_get_peer_cert_chain (ssl);
267   if (certs == NULL)
268     {
269       X509_free (peer);
270       return NULL;
271     }
272
273   chain = g_tls_certificate_openssl_build_chain (peer, certs);
274   X509_free (peer);
275   if (!chain)
276     return NULL;
277
278   return G_TLS_CERTIFICATE (chain);
279 }
280
281 static GTlsCertificateFlags
282 verify_ocsp_response (GTlsConnectionOpenssl *openssl,
283                       GTlsDatabase          *database,
284                       GTlsCertificate       *peer_certificate)
285 {
286 #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
287   !defined(OPENSSL_NO_OCSP)
288   SSL *ssl = NULL;
289   OCSP_RESPONSE *resp = NULL;
290   long len = 0;
291   unsigned char *p = NULL;
292
293   ssl = g_tls_connection_openssl_get_ssl (openssl);
294   len = SSL_get_tlsext_status_ocsp_resp (ssl, &p);
295   /* Soft fail in case of no response is the best we can do */
296   if (p == NULL)
297     return 0;
298
299   resp = d2i_OCSP_RESPONSE (NULL, (const unsigned char **) &p, len);
300   if (resp == NULL)
301     return G_TLS_CERTIFICATE_GENERIC_ERROR;
302
303   return g_tls_file_database_openssl_verify_ocsp_response (database,
304                                                            peer_certificate,
305                                                            resp);
306 #else
307   return 0;
308 #endif
309 }
310
311 static GTlsCertificateFlags
312 verify_peer_certificate (GTlsConnectionOpenssl *openssl,
313                          GTlsCertificate       *peer_certificate)
314 {
315   GTlsConnection *conn = G_TLS_CONNECTION (openssl);
316   GSocketConnectable *peer_identity;
317   GTlsDatabase *database;
318   GTlsCertificateFlags errors;
319   gboolean is_client;
320
321   is_client = G_IS_TLS_CLIENT_CONNECTION (openssl);
322   if (is_client)
323     peer_identity = g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION (openssl));
324   else
325     peer_identity = NULL;
326
327   errors = 0;
328
329   database = g_tls_connection_get_database (conn);
330   if (database == NULL)
331     {
332       TIZEN_LOGE("SSL HandShake - Unknown CA");
333       errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
334       errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
335     }
336   else
337     {
338       GError *error = NULL;
339
340       errors |= g_tls_database_verify_chain (database, peer_certificate,
341                                              is_client ?
342                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
343                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
344                                              peer_identity,
345                                              g_tls_connection_get_interaction (conn),
346                                              G_TLS_DATABASE_VERIFY_NONE,
347                                              NULL, &error);
348       if (error)
349         {
350           g_warning ("failure verifying certificate chain: %s",
351                      error->message);
352           g_assert (errors != 0);
353           g_clear_error (&error);
354         }
355     }
356
357   if (is_client && (errors == 0))
358     errors = verify_ocsp_response (openssl, database, peer_certificate);
359
360   return errors;
361 }
362
363 static GTlsConnectionBaseStatus
364 g_tls_connection_openssl_handshake (GTlsConnectionBase  *tls,
365                                     GCancellable        *cancellable,
366                                     GError             **error)
367 {
368   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
369   GTlsConnectionOpensslPrivate *priv;
370   GTlsConnectionBaseStatus status;
371   SSL *ssl;
372   int ret;
373
374   priv = g_tls_connection_openssl_get_instance_private (openssl);
375
376   ssl = g_tls_connection_openssl_get_ssl (openssl);
377
378   TIZEN_LOGI("tls[%p] openssl[%p] priv[%p] ssl[%p]", tls, openssl, priv, ssl);
379
380   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
381   ret = SSL_do_handshake (ssl);
382   END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
383                   _("Error performing TLS handshake: %s"), error);
384
385   if (ret > 0)
386     {
387       priv->peer_certificate_tmp = get_peer_certificate (openssl);
388       if (priv->peer_certificate_tmp)
389         priv->peer_certificate_errors_tmp = verify_peer_certificate (openssl, priv->peer_certificate_tmp);
390       else if (G_IS_TLS_CLIENT_CONNECTION (openssl))
391         {
392           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
393                                _("Server did not return a valid TLS certificate"));
394         }
395     }
396
397   return status;
398 }
399
400 static GTlsConnectionBaseStatus
401 g_tls_connection_openssl_complete_handshake (GTlsConnectionBase  *tls,
402                                              GError             **error)
403 {
404   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
405   GTlsConnectionOpensslPrivate *priv;
406   GTlsCertificate *peer_certificate;
407   GTlsCertificateFlags peer_certificate_errors = 0;
408   GTlsConnectionBaseStatus status = G_TLS_CONNECTION_BASE_OK;
409
410   priv = g_tls_connection_openssl_get_instance_private (openssl);
411
412   TIZEN_LOGI("tls[%p] openssl[%p] priv[%p]", tls, openssl, priv);
413
414   peer_certificate = priv->peer_certificate_tmp;
415   priv->peer_certificate_tmp = NULL;
416   peer_certificate_errors = priv->peer_certificate_errors_tmp;
417   priv->peer_certificate_errors_tmp = 0;
418
419   if (peer_certificate)
420     {
421       if (!g_tls_connection_base_accept_peer_certificate (tls, peer_certificate,
422                                                           peer_certificate_errors))
423         {
424           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
425                                _("Unacceptable TLS certificate"));
426           status = G_TLS_CONNECTION_BASE_ERROR;
427         }
428
429       g_tls_connection_base_set_peer_certificate (G_TLS_CONNECTION_BASE (openssl),
430                                                   peer_certificate,
431                                                   peer_certificate_errors);
432       g_clear_object (&peer_certificate);
433     }
434
435   return status;
436 }
437
438 static void
439 g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
440                                   GIOCondition        direction,
441                                   gboolean            blocking,
442                                   GCancellable       *cancellable)
443 {
444   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
445   GTlsConnectionOpensslPrivate *priv;
446
447   priv = g_tls_connection_openssl_get_instance_private (openssl);
448
449   G_TLS_CONNECTION_BASE_CLASS (g_tls_connection_openssl_parent_class)->push_io (tls, direction,
450                                                                                 blocking, cancellable);
451
452   if (direction & G_IO_IN)
453     {
454       g_tls_bio_set_read_cancellable (priv->bio, cancellable);
455       g_tls_bio_set_read_blocking (priv->bio, blocking);
456       g_clear_error (&tls->read_error);
457       g_tls_bio_set_read_error (priv->bio, &tls->read_error);
458     }
459
460   if (direction & G_IO_OUT)
461     {
462       g_tls_bio_set_write_cancellable (priv->bio, cancellable);
463       g_tls_bio_set_write_blocking (priv->bio, blocking);
464       g_clear_error (&tls->write_error);
465       g_tls_bio_set_write_error (priv->bio, &tls->write_error);
466     }
467 }
468
469 static GTlsConnectionBaseStatus
470 g_tls_connection_openssl_pop_io (GTlsConnectionBase  *tls,
471                                  GIOCondition         direction,
472                                  gboolean             success,
473                                  GError             **error)
474 {
475   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
476   GTlsConnectionOpensslPrivate *priv;
477
478   priv = g_tls_connection_openssl_get_instance_private (openssl);
479
480   if (direction & G_IO_IN)
481     g_tls_bio_set_read_cancellable (priv->bio, NULL);
482
483   if (direction & G_IO_OUT)
484     g_tls_bio_set_write_cancellable (priv->bio, NULL);
485
486   return G_TLS_CONNECTION_BASE_CLASS (g_tls_connection_openssl_parent_class)->pop_io (tls, direction,
487                                                                                       success, error);
488 }
489
490 static GTlsConnectionBaseStatus
491 g_tls_connection_openssl_read (GTlsConnectionBase    *tls,
492                                void                  *buffer,
493                                gsize                  count,
494                                gboolean               blocking,
495                                gssize                *nread,
496                                GCancellable          *cancellable,
497                                GError               **error)
498 {
499   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
500   GTlsConnectionBaseStatus status;
501   SSL *ssl;
502   gssize ret;
503
504   ssl = g_tls_connection_openssl_get_ssl (openssl);
505
506   BEGIN_OPENSSL_IO (openssl, G_IO_IN, blocking, cancellable);
507   ret = SSL_read (ssl, buffer, count);
508   END_OPENSSL_IO (openssl, G_IO_IN, ret, status,
509                   _("Error reading data from TLS socket: %s"), error);
510
511   if (ret >= 0)
512     *nread = ret;
513   return status;
514 }
515
516 static GTlsConnectionBaseStatus
517 g_tls_connection_openssl_write (GTlsConnectionBase    *tls,
518                                 const void            *buffer,
519                                 gsize                  count,
520                                 gboolean               blocking,
521                                 gssize                *nwrote,
522                                 GCancellable          *cancellable,
523                                 GError               **error)
524 {
525   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
526   GTlsConnectionBaseStatus status;
527   SSL *ssl;
528   gssize ret;
529
530   ssl = g_tls_connection_openssl_get_ssl (openssl);
531
532   BEGIN_OPENSSL_IO (openssl, G_IO_OUT, blocking, cancellable);
533   ret = SSL_write (ssl, buffer, count);
534   END_OPENSSL_IO (openssl, G_IO_OUT, ret, status,
535                   _("Error writing data to TLS socket: %s"), error);
536
537   if (ret >= 0)
538     *nwrote = ret;
539   return status;
540 }
541
542 static GTlsConnectionBaseStatus
543 g_tls_connection_openssl_close (GTlsConnectionBase  *tls,
544                                 GCancellable        *cancellable,
545                                 GError             **error)
546 {
547   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
548   GTlsConnectionOpensslPrivate *priv;
549   GTlsConnectionBaseStatus status;
550   SSL *ssl;
551   int ret;
552
553   ssl = g_tls_connection_openssl_get_ssl (openssl);
554   priv = g_tls_connection_openssl_get_instance_private (openssl);
555
556   TIZEN_LOGI("tls[%p] openssl[%p] priv[%p] ssl[%p]", tls, openssl, priv, ssl);
557
558   priv->shutting_down = TRUE;
559
560   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
561   ret = SSL_shutdown (ssl);
562   END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
563                   _("Error performing TLS close: %s"), error);
564
565   return status;
566 }
567
568 static void
569 g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
570 {
571   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
572   GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
573
574   gobject_class->finalize     = g_tls_connection_openssl_finalize;
575
576   base_class->request_rehandshake = g_tls_connection_openssl_request_rehandshake;
577   base_class->handshake           = g_tls_connection_openssl_handshake;
578   base_class->complete_handshake  = g_tls_connection_openssl_complete_handshake;
579   base_class->push_io             = g_tls_connection_openssl_push_io;
580   base_class->pop_io              = g_tls_connection_openssl_pop_io;
581   base_class->read_fn             = g_tls_connection_openssl_read;
582   base_class->write_fn            = g_tls_connection_openssl_write;
583   base_class->close_fn            = g_tls_connection_openssl_close;
584 }
585
586 static gboolean
587 g_tls_connection_openssl_initable_init (GInitable     *initable,
588                                         GCancellable  *cancellable,
589                                         GError       **error)
590 {
591   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (initable);
592   GTlsConnectionOpensslPrivate *priv;
593   GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (initable);
594   SSL *ssl;
595
596   g_return_val_if_fail (tls->base_istream != NULL &&
597                         tls->base_ostream != NULL, FALSE);
598
599   priv = g_tls_connection_openssl_get_instance_private (openssl);
600
601   ssl = g_tls_connection_openssl_get_ssl (openssl);
602   g_assert (ssl != NULL);
603
604   priv->bio = g_tls_bio_new (tls->base_io_stream);
605
606   SSL_set_bio (ssl, priv->bio, priv->bio);
607
608   return TRUE;
609 }
610
611 static void
612 g_tls_connection_openssl_initable_iface_init (GInitableIface *iface)
613 {
614   iface->init = g_tls_connection_openssl_initable_init;
615 }
616
617 static void
618 g_tls_connection_openssl_init (GTlsConnectionOpenssl *openssl)
619 {
620 }
621
622 SSL *
623 g_tls_connection_openssl_get_ssl (GTlsConnectionOpenssl *openssl)
624 {
625   g_return_val_if_fail (G_IS_TLS_CONNECTION_OPENSSL (openssl), NULL);
626
627   return G_TLS_CONNECTION_OPENSSL_GET_CLASS (openssl)->get_ssl (openssl);
628 }
629
630 gboolean
631 g_tls_connection_openssl_request_certificate (GTlsConnectionOpenssl  *openssl,
632                                               GError                **error)
633 {
634   GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
635   GTlsInteraction *interaction;
636   GTlsConnection *conn;
637   GTlsConnectionBase *tls;
638
639   g_return_val_if_fail (G_IS_TLS_CONNECTION_OPENSSL (openssl), FALSE);
640
641   conn = G_TLS_CONNECTION (openssl);
642   tls = G_TLS_CONNECTION_BASE (openssl);
643
644   interaction = g_tls_connection_get_interaction (conn);
645   if (!interaction)
646     return FALSE;
647
648   res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
649                                                       tls->read_cancellable, error);
650   return res != G_TLS_INTERACTION_FAILED;
651 }