Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / boringssl / ssl / bio_ssl.cc
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/ssl.h>
11
12 #include <openssl/bio.h>
13
14
15 static SSL *get_ssl(BIO *bio) {
16   return reinterpret_cast<SSL *>(bio->ptr);
17 }
18
19 static int ssl_read(BIO *bio, char *out, int outl) {
20   SSL *ssl = get_ssl(bio);
21   if (ssl == NULL) {
22     return 0;
23   }
24
25   BIO_clear_retry_flags(bio);
26
27   const int ret = SSL_read(ssl, out, outl);
28
29   switch (SSL_get_error(ssl, ret)) {
30     case SSL_ERROR_WANT_READ:
31       BIO_set_retry_read(bio);
32       break;
33
34     case SSL_ERROR_WANT_WRITE:
35       BIO_set_retry_write(bio);
36       break;
37
38     case SSL_ERROR_WANT_ACCEPT:
39       BIO_set_retry_special(bio);
40       bio->retry_reason = BIO_RR_ACCEPT;
41       break;
42
43     case SSL_ERROR_WANT_CONNECT:
44       BIO_set_retry_special(bio);
45       bio->retry_reason = BIO_RR_CONNECT;
46       break;
47
48     case SSL_ERROR_NONE:
49     case SSL_ERROR_SYSCALL:
50     case SSL_ERROR_SSL:
51     case SSL_ERROR_ZERO_RETURN:
52     default:
53       break;
54   }
55
56   return ret;
57 }
58
59 static int ssl_write(BIO *bio, const char *out, int outl) {
60   SSL *ssl = get_ssl(bio);
61   if (ssl == NULL) {
62     return 0;
63   }
64
65   BIO_clear_retry_flags(bio);
66
67   const int ret = SSL_write(ssl, out, outl);
68
69   switch (SSL_get_error(ssl, ret)) {
70     case SSL_ERROR_WANT_WRITE:
71       BIO_set_retry_write(bio);
72       break;
73
74     case SSL_ERROR_WANT_READ:
75       BIO_set_retry_read(bio);
76       break;
77
78     case SSL_ERROR_WANT_CONNECT:
79       BIO_set_retry_special(bio);
80       bio->retry_reason = BIO_RR_CONNECT;
81       break;
82
83     case SSL_ERROR_NONE:
84     case SSL_ERROR_SYSCALL:
85     case SSL_ERROR_SSL:
86     default:
87       break;
88   }
89
90   return ret;
91 }
92
93 static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) {
94   SSL *ssl = get_ssl(bio);
95   if (ssl == NULL && cmd != BIO_C_SET_SSL) {
96     return 0;
97   }
98
99   switch (cmd) {
100     case BIO_C_SET_SSL:
101       bio->shutdown = num;
102       bio->ptr = ptr;
103       bio->init = 1;
104       return 1;
105
106     case BIO_CTRL_GET_CLOSE:
107       return bio->shutdown;
108
109     case BIO_CTRL_SET_CLOSE:
110       bio->shutdown = num;
111       return 1;
112
113     case BIO_CTRL_WPENDING:
114       return BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr);
115
116     case BIO_CTRL_PENDING:
117       return SSL_pending(ssl);
118
119     case BIO_CTRL_FLUSH: {
120       BIO_clear_retry_flags(bio);
121       long ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr);
122       BIO_copy_next_retry(bio);
123       return ret;
124     }
125
126     case BIO_CTRL_PUSH:
127     case BIO_CTRL_POP:
128     case BIO_CTRL_DUP:
129       return -1;
130
131     default:
132       return BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr);
133   }
134 }
135
136 static int ssl_new(BIO *bio) {
137   return 1;
138 }
139
140 static int ssl_free(BIO *bio) {
141   SSL *ssl = get_ssl(bio);
142
143   if (ssl == NULL) {
144     return 1;
145   }
146
147   SSL_shutdown(ssl);
148   if (bio->shutdown) {
149     SSL_free(ssl);
150   }
151
152   return 1;
153 }
154
155 static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
156   SSL *ssl = get_ssl(bio);
157   if (ssl == NULL) {
158     return 0;
159   }
160
161   switch (cmd) {
162     case BIO_CTRL_SET_CALLBACK:
163       return -1;
164
165     default:
166       return BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp);
167   }
168 }
169
170 static const BIO_METHOD ssl_method = {
171     BIO_TYPE_SSL, "SSL",    ssl_write, ssl_read, NULL,
172     NULL,         ssl_ctrl, ssl_new,   ssl_free, ssl_callback_ctrl,
173 };
174
175 const BIO_METHOD *BIO_f_ssl(void) { return &ssl_method; }
176
177 long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership) {
178   return BIO_ctrl(bio, BIO_C_SET_SSL, take_owership, ssl);
179 }