c6df5596e3545c56bd4605a93b0c334fcb7677ee
[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       errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
333       errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
334     }
335   else
336     {
337       GError *error = NULL;
338
339       errors |= g_tls_database_verify_chain (database, peer_certificate,
340                                              is_client ?
341                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
342                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
343                                              peer_identity,
344                                              g_tls_connection_get_interaction (conn),
345                                              G_TLS_DATABASE_VERIFY_NONE,
346                                              NULL, &error);
347       if (error)
348         {
349           g_warning ("failure verifying certificate chain: %s",
350                      error->message);
351           g_assert (errors != 0);
352           g_clear_error (&error);
353         }
354     }
355
356   if (is_client && (errors == 0))
357     errors = verify_ocsp_response (openssl, database, peer_certificate);
358
359   return errors;
360 }
361
362 static GTlsConnectionBaseStatus
363 g_tls_connection_openssl_handshake (GTlsConnectionBase  *tls,
364                                     GCancellable        *cancellable,
365                                     GError             **error)
366 {
367   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
368   GTlsConnectionOpensslPrivate *priv;
369   GTlsConnectionBaseStatus status;
370   SSL *ssl;
371   int ret;
372
373   priv = g_tls_connection_openssl_get_instance_private (openssl);
374
375   ssl = g_tls_connection_openssl_get_ssl (openssl);
376
377   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
378   ret = SSL_do_handshake (ssl);
379   END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
380                   _("Error performing TLS handshake: %s"), error);
381
382   if (ret > 0)
383     {
384       priv->peer_certificate_tmp = get_peer_certificate (openssl);
385       if (priv->peer_certificate_tmp)
386         priv->peer_certificate_errors_tmp = verify_peer_certificate (openssl, priv->peer_certificate_tmp);
387       else if (G_IS_TLS_CLIENT_CONNECTION (openssl))
388         {
389           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
390                                _("Server did not return a valid TLS certificate"));
391         }
392     }
393
394   return status;
395 }
396
397 static GTlsConnectionBaseStatus
398 g_tls_connection_openssl_complete_handshake (GTlsConnectionBase  *tls,
399                                              GError             **error)
400 {
401   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
402   GTlsConnectionOpensslPrivate *priv;
403   GTlsCertificate *peer_certificate;
404   GTlsCertificateFlags peer_certificate_errors = 0;
405   GTlsConnectionBaseStatus status = G_TLS_CONNECTION_BASE_OK;
406
407   priv = g_tls_connection_openssl_get_instance_private (openssl);
408
409   peer_certificate = priv->peer_certificate_tmp;
410   priv->peer_certificate_tmp = NULL;
411   peer_certificate_errors = priv->peer_certificate_errors_tmp;
412   priv->peer_certificate_errors_tmp = 0;
413
414   if (peer_certificate)
415     {
416       if (!g_tls_connection_base_accept_peer_certificate (tls, peer_certificate,
417                                                           peer_certificate_errors))
418         {
419           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
420                                _("Unacceptable TLS certificate"));
421           status = G_TLS_CONNECTION_BASE_ERROR;
422         }
423
424       g_tls_connection_base_set_peer_certificate (G_TLS_CONNECTION_BASE (openssl),
425                                                   peer_certificate,
426                                                   peer_certificate_errors);
427       g_clear_object (&peer_certificate);
428     }
429
430   return status;
431 }
432
433 static void
434 g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
435                                   GIOCondition        direction,
436                                   gboolean            blocking,
437                                   GCancellable       *cancellable)
438 {
439   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
440   GTlsConnectionOpensslPrivate *priv;
441
442   priv = g_tls_connection_openssl_get_instance_private (openssl);
443
444   G_TLS_CONNECTION_BASE_CLASS (g_tls_connection_openssl_parent_class)->push_io (tls, direction,
445                                                                                 blocking, cancellable);
446
447   if (direction & G_IO_IN)
448     {
449       g_tls_bio_set_read_cancellable (priv->bio, cancellable);
450       g_tls_bio_set_read_blocking (priv->bio, blocking);
451       g_clear_error (&tls->read_error);
452       g_tls_bio_set_read_error (priv->bio, &tls->read_error);
453     }
454
455   if (direction & G_IO_OUT)
456     {
457       g_tls_bio_set_write_cancellable (priv->bio, cancellable);
458       g_tls_bio_set_write_blocking (priv->bio, blocking);
459       g_clear_error (&tls->write_error);
460       g_tls_bio_set_write_error (priv->bio, &tls->write_error);
461     }
462 }
463
464 static GTlsConnectionBaseStatus
465 g_tls_connection_openssl_pop_io (GTlsConnectionBase  *tls,
466                                  GIOCondition         direction,
467                                  gboolean             success,
468                                  GError             **error)
469 {
470   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
471   GTlsConnectionOpensslPrivate *priv;
472
473   priv = g_tls_connection_openssl_get_instance_private (openssl);
474
475   if (direction & G_IO_IN)
476     g_tls_bio_set_read_cancellable (priv->bio, NULL);
477
478   if (direction & G_IO_OUT)
479     g_tls_bio_set_write_cancellable (priv->bio, NULL);
480
481   return G_TLS_CONNECTION_BASE_CLASS (g_tls_connection_openssl_parent_class)->pop_io (tls, direction,
482                                                                                       success, error);
483 }
484
485 static GTlsConnectionBaseStatus
486 g_tls_connection_openssl_read (GTlsConnectionBase    *tls,
487                                void                  *buffer,
488                                gsize                  count,
489                                gboolean               blocking,
490                                gssize                *nread,
491                                GCancellable          *cancellable,
492                                GError               **error)
493 {
494   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
495   GTlsConnectionBaseStatus status;
496   SSL *ssl;
497   gssize ret;
498
499   ssl = g_tls_connection_openssl_get_ssl (openssl);
500
501   BEGIN_OPENSSL_IO (openssl, G_IO_IN, blocking, cancellable);
502   ret = SSL_read (ssl, buffer, count);
503   END_OPENSSL_IO (openssl, G_IO_IN, ret, status,
504                   _("Error reading data from TLS socket: %s"), error);
505
506   if (ret >= 0)
507     *nread = ret;
508   return status;
509 }
510
511 static GTlsConnectionBaseStatus
512 g_tls_connection_openssl_write (GTlsConnectionBase    *tls,
513                                 const void            *buffer,
514                                 gsize                  count,
515                                 gboolean               blocking,
516                                 gssize                *nwrote,
517                                 GCancellable          *cancellable,
518                                 GError               **error)
519 {
520   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
521   GTlsConnectionBaseStatus status;
522   SSL *ssl;
523   gssize ret;
524
525   ssl = g_tls_connection_openssl_get_ssl (openssl);
526
527   BEGIN_OPENSSL_IO (openssl, G_IO_OUT, blocking, cancellable);
528   ret = SSL_write (ssl, buffer, count);
529   END_OPENSSL_IO (openssl, G_IO_OUT, ret, status,
530                   _("Error writing data to TLS socket: %s"), error);
531
532   if (ret >= 0)
533     *nwrote = ret;
534   return status;
535 }
536
537 static GTlsConnectionBaseStatus
538 g_tls_connection_openssl_close (GTlsConnectionBase  *tls,
539                                 GCancellable        *cancellable,
540                                 GError             **error)
541 {
542   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
543   GTlsConnectionOpensslPrivate *priv;
544   GTlsConnectionBaseStatus status;
545   SSL *ssl;
546   int ret;
547
548   ssl = g_tls_connection_openssl_get_ssl (openssl);
549   priv = g_tls_connection_openssl_get_instance_private (openssl);
550
551   priv->shutting_down = TRUE;
552
553   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, TRUE, cancellable);
554   ret = SSL_shutdown (ssl);
555   END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
556                   _("Error performing TLS close: %s"), error);
557
558   return status;
559 }
560
561 static void
562 g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
563 {
564   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
565   GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
566
567   gobject_class->finalize     = g_tls_connection_openssl_finalize;
568
569   base_class->request_rehandshake = g_tls_connection_openssl_request_rehandshake;
570   base_class->handshake           = g_tls_connection_openssl_handshake;
571   base_class->complete_handshake  = g_tls_connection_openssl_complete_handshake;
572   base_class->push_io             = g_tls_connection_openssl_push_io;
573   base_class->pop_io              = g_tls_connection_openssl_pop_io;
574   base_class->read_fn             = g_tls_connection_openssl_read;
575   base_class->write_fn            = g_tls_connection_openssl_write;
576   base_class->close_fn            = g_tls_connection_openssl_close;
577 }
578
579 static gboolean
580 g_tls_connection_openssl_initable_init (GInitable     *initable,
581                                         GCancellable  *cancellable,
582                                         GError       **error)
583 {
584   GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (initable);
585   GTlsConnectionOpensslPrivate *priv;
586   GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (initable);
587   SSL *ssl;
588
589   g_return_val_if_fail (tls->base_istream != NULL &&
590                         tls->base_ostream != NULL, FALSE);
591
592   priv = g_tls_connection_openssl_get_instance_private (openssl);
593
594   ssl = g_tls_connection_openssl_get_ssl (openssl);
595   g_assert (ssl != NULL);
596
597   priv->bio = g_tls_bio_new (tls->base_io_stream);
598
599   SSL_set_bio (ssl, priv->bio, priv->bio);
600
601   return TRUE;
602 }
603
604 static void
605 g_tls_connection_openssl_initable_iface_init (GInitableIface *iface)
606 {
607   iface->init = g_tls_connection_openssl_initable_init;
608 }
609
610 static void
611 g_tls_connection_openssl_init (GTlsConnectionOpenssl *openssl)
612 {
613 }
614
615 SSL *
616 g_tls_connection_openssl_get_ssl (GTlsConnectionOpenssl *openssl)
617 {
618   g_return_val_if_fail (G_IS_TLS_CONNECTION_OPENSSL (openssl), NULL);
619
620   return G_TLS_CONNECTION_OPENSSL_GET_CLASS (openssl)->get_ssl (openssl);
621 }
622
623 gboolean
624 g_tls_connection_openssl_request_certificate (GTlsConnectionOpenssl  *openssl,
625                                               GError                **error)
626 {
627   GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
628   GTlsInteraction *interaction;
629   GTlsConnection *conn;
630   GTlsConnectionBase *tls;
631
632   g_return_val_if_fail (G_IS_TLS_CONNECTION_OPENSSL (openssl), FALSE);
633
634   conn = G_TLS_CONNECTION (openssl);
635   tls = G_TLS_CONNECTION_BASE (openssl);
636
637   interaction = g_tls_connection_get_interaction (conn);
638   if (!interaction)
639     return FALSE;
640
641   res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
642                                                       tls->read_cancellable, error);
643   return res != G_TLS_INTERACTION_FAILED;
644 }