summaryrefslogtreecommitdiff
path: root/src/lib/libressl/ressl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libressl/ressl.c')
-rw-r--r--src/lib/libressl/ressl.c160
1 files changed, 0 insertions, 160 deletions
diff --git a/src/lib/libressl/ressl.c b/src/lib/libressl/ressl.c
index 7295c520d2..dc82f321b1 100644
--- a/src/lib/libressl/ressl.c
+++ b/src/lib/libressl/ressl.c
@@ -14,18 +14,12 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <sys/types.h>
18#include <sys/socket.h> 17#include <sys/socket.h>
19 18
20#include <arpa/inet.h>
21
22#include <errno.h> 19#include <errno.h>
23#include <netdb.h>
24#include <stdlib.h> 20#include <stdlib.h>
25#include <unistd.h> 21#include <unistd.h>
26 22
27#include <openssl/x509.h>
28
29#include <ressl.h> 23#include <ressl.h>
30#include "ressl_internal.h" 24#include "ressl_internal.h"
31 25
@@ -117,160 +111,6 @@ ressl_reset(struct ressl *ctx)
117} 111}
118 112
119int 113int
120ressl_connect(struct ressl *ctx, const char *host, const char *port)
121{
122 struct addrinfo hints, *res, *res0;
123 const char *h = NULL, *p = NULL;
124 char *hs = NULL, *ps = NULL;
125 int rv = -1, s = -1, ret;
126
127 if (host == NULL) {
128 ressl_set_error(ctx, "host not specified");
129 goto err;
130 }
131
132 /*
133 * If port is NULL try to extract a port from the specified host,
134 * otherwise use the default.
135 */
136 if ((p = (char *)port) == NULL) {
137 ret = ressl_host_port(host, &hs, &ps);
138 if (ret == -1) {
139 ressl_set_error(ctx, "memory allocation failure");
140 goto err;
141 }
142 if (ret != 0)
143 port = HTTPS_PORT;
144 }
145
146 h = (hs != NULL) ? hs : host;
147 p = (ps != NULL) ? ps : port;
148
149 memset(&hints, 0, sizeof(hints));
150 hints.ai_family = AF_UNSPEC;
151 hints.ai_socktype = SOCK_STREAM;
152
153 if ((ret = getaddrinfo(h, p, &hints, &res0)) != 0) {
154 ressl_set_error(ctx, "%s", gai_strerror(ret));
155 goto err;
156 }
157 for (res = res0; res; res = res->ai_next) {
158 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
159 if (s == -1) {
160 ressl_set_error(ctx, "socket");
161 continue;
162 }
163 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
164 ressl_set_error(ctx, "connect");
165 close(s);
166 s = -1;
167 continue;
168 }
169
170 break; /* Connected. */
171 }
172 freeaddrinfo(res0);
173
174 if (s == -1)
175 goto err;
176
177 if (ressl_connect_socket(ctx, s, h) != 0) {
178 close(s);
179 goto err;
180 }
181
182 rv = 0;
183
184err:
185
186 free(hs);
187 free(ps);
188
189 return (rv);
190}
191
192int
193ressl_connect_socket(struct ressl *ctx, int socket, const char *hostname)
194{
195 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
196 X509 *cert = NULL;
197 int ret;
198
199 ctx->socket = socket;
200
201 /* XXX - add a configuration option to control versions. */
202 if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
203 ressl_set_error(ctx, "ssl context failure");
204 goto err;
205 }
206 if (ctx->config->verify) {
207 if (hostname == NULL) {
208 ressl_set_error(ctx, "server name not specified");
209 goto err;
210 }
211
212 SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL);
213
214 if (SSL_CTX_load_verify_locations(ctx->ssl_ctx,
215 ctx->config->ca_file, ctx->config->ca_path) != 1) {
216 ressl_set_error(ctx, "ssl verify setup failure");
217 goto err;
218 }
219 if (ctx->config->verify_depth >= 0)
220 SSL_CTX_set_verify_depth(ctx->ssl_ctx,
221 ctx->config->verify_depth);
222 }
223
224 if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
225 ressl_set_error(ctx, "ssl connection failure");
226 goto err;
227 }
228 if (SSL_set_fd(ctx->ssl_conn, ctx->socket) != 1) {
229 ressl_set_error(ctx, "ssl file descriptor failure");
230 goto err;
231 }
232
233 /*
234 * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not
235 * permitted in "HostName".
236 */
237 if (hostname != NULL &&
238 inet_pton(AF_INET, hostname, &addrbuf) != 1 &&
239 inet_pton(AF_INET6, hostname, &addrbuf) != 1) {
240 if (SSL_set_tlsext_host_name(ctx->ssl_conn, hostname) == 0) {
241 ressl_set_error(ctx, "SNI host name failed");
242 goto err;
243 }
244 }
245
246 if ((ret = SSL_connect(ctx->ssl_conn)) != 1) {
247 ressl_set_error(ctx, "SSL connect failed: %i",
248 SSL_get_error(ctx->ssl_conn, ret));
249 goto err;
250 }
251
252 if (ctx->config->verify) {
253 cert = SSL_get_peer_certificate(ctx->ssl_conn);
254 if (cert == NULL) {
255 ressl_set_error(ctx, "no server certificate");
256 goto err;
257 }
258 if (ressl_check_hostname(cert, hostname) != 0) {
259 ressl_set_error(ctx, "host `%s' not present in"
260 " server certificate", hostname);
261 goto err;
262 }
263 }
264
265 return (0);
266
267err:
268 X509_free(cert);
269
270 return (-1);
271}
272
273int
274ressl_read(struct ressl *ctx, char *buf, size_t buflen, size_t *outlen) 114ressl_read(struct ressl *ctx, char *buf, size_t buflen, size_t *outlen)
275{ 115{
276 int ret; 116 int ret;