summaryrefslogtreecommitdiff
path: root/src/lib/libressl/ressl.c
diff options
context:
space:
mode:
authorjsing <>2014-10-31 13:46:17 +0000
committerjsing <>2014-10-31 13:46:17 +0000
commitcd85e00508e178758948e7a759609d0f1e7764df (patch)
tree44ea21a19ccf529a3e38fb107d3a2d1330f58d8e /src/lib/libressl/ressl.c
parente83bdb8edcd9388f13b71372b277fdcce386a9b0 (diff)
downloadopenbsd-cd85e00508e178758948e7a759609d0f1e7764df.tar.gz
openbsd-cd85e00508e178758948e7a759609d0f1e7764df.tar.bz2
openbsd-cd85e00508e178758948e7a759609d0f1e7764df.zip
Rename libressl to libtls to avoid confusion and to make it easier to
distinguish between LibreSSL (the project) and libressl (the library). Discussed with many.
Diffstat (limited to 'src/lib/libressl/ressl.c')
-rw-r--r--src/lib/libressl/ressl.c300
1 files changed, 0 insertions, 300 deletions
diff --git a/src/lib/libressl/ressl.c b/src/lib/libressl/ressl.c
deleted file mode 100644
index 06c7d54cc2..0000000000
--- a/src/lib/libressl/ressl.c
+++ /dev/null
@@ -1,300 +0,0 @@
1/* $OpenBSD: ressl.c,v 1.18 2014/10/15 21:02:39 tedu Exp $ */
2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/socket.h>
19
20#include <errno.h>
21#include <stdlib.h>
22#include <unistd.h>
23
24#include <openssl/bio.h>
25#include <openssl/evp.h>
26#include <openssl/pem.h>
27#include <openssl/x509.h>
28
29#include <ressl.h>
30#include "ressl_internal.h"
31
32static struct ressl_config *ressl_config_default;
33
34int
35ressl_init(void)
36{
37 static int ressl_initialised = 0;
38
39 if (ressl_initialised)
40 return (0);
41
42 SSL_load_error_strings();
43 SSL_library_init();
44
45 if ((ressl_config_default = ressl_config_new()) == NULL)
46 return (-1);
47
48 ressl_initialised = 1;
49
50 return (0);
51}
52
53const char *
54ressl_error(struct ressl *ctx)
55{
56 return ctx->errmsg;
57}
58
59int
60ressl_set_error(struct ressl *ctx, char *fmt, ...)
61{
62 va_list ap;
63 int rv;
64
65 ctx->err = errno;
66 free(ctx->errmsg);
67 ctx->errmsg = NULL;
68
69 va_start(ap, fmt);
70 rv = vasprintf(&ctx->errmsg, fmt, ap);
71 va_end(ap);
72
73 return (rv);
74}
75
76struct ressl *
77ressl_new(void)
78{
79 struct ressl *ctx;
80
81 if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
82 return (NULL);
83
84 ctx->config = ressl_config_default;
85
86 ressl_reset(ctx);
87
88 return (ctx);
89}
90
91int
92ressl_configure(struct ressl *ctx, struct ressl_config *config)
93{
94 if (config == NULL)
95 config = ressl_config_default;
96
97 ctx->config = config;
98
99 if ((ctx->flags & RESSL_SERVER) != 0)
100 return (ressl_configure_server(ctx));
101
102 return (0);
103}
104
105int
106ressl_configure_keypair(struct ressl *ctx)
107{
108 EVP_PKEY *pkey = NULL;
109 X509 *cert = NULL;
110 BIO *bio = NULL;
111
112 if (ctx->config->cert_mem != NULL) {
113 if (SSL_CTX_use_certificate_chain(ctx->ssl_ctx,
114 ctx->config->cert_mem, ctx->config->cert_len) != 1) {
115 ressl_set_error(ctx, "failed to load certificate");
116 goto err;
117 }
118 cert = NULL;
119 }
120 if (ctx->config->key_mem != NULL) {
121 if ((bio = BIO_new_mem_buf(ctx->config->key_mem,
122 ctx->config->key_len)) == NULL) {
123 ressl_set_error(ctx, "failed to create buffer");
124 goto err;
125 }
126 if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL,
127 NULL)) == NULL) {
128 ressl_set_error(ctx, "failed to read private key");
129 goto err;
130 }
131 if (SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey) != 1) {
132 ressl_set_error(ctx, "failed to load private key");
133 goto err;
134 }
135 BIO_free(bio);
136 bio = NULL;
137 EVP_PKEY_free(pkey);
138 pkey = NULL;
139 }
140
141 if (ctx->config->cert_file != NULL) {
142 if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx,
143 ctx->config->cert_file) != 1) {
144 ressl_set_error(ctx, "failed to load certificate file");
145 goto err;
146 }
147 }
148 if (ctx->config->key_file != NULL) {
149 if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx,
150 ctx->config->key_file, SSL_FILETYPE_PEM) != 1) {
151 ressl_set_error(ctx, "failed to load private key file");
152 goto err;
153 }
154 }
155
156 if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1) {
157 ressl_set_error(ctx, "private/public key mismatch");
158 goto err;
159 }
160
161 return (0);
162
163err:
164 EVP_PKEY_free(pkey);
165 X509_free(cert);
166 BIO_free(bio);
167
168 return (1);
169}
170
171int
172ressl_configure_ssl(struct ressl *ctx)
173{
174 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
175 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv3);
176
177 SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1);
178 SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_1);
179 SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2);
180
181 if ((ctx->config->protocols & RESSL_PROTOCOL_TLSv1_0) == 0)
182 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1);
183 if ((ctx->config->protocols & RESSL_PROTOCOL_TLSv1_1) == 0)
184 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_1);
185 if ((ctx->config->protocols & RESSL_PROTOCOL_TLSv1_2) == 0)
186 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2);
187
188 if (ctx->config->ciphers != NULL) {
189 if (SSL_CTX_set_cipher_list(ctx->ssl_ctx,
190 ctx->config->ciphers) != 1) {
191 ressl_set_error(ctx, "failed to set ciphers");
192 goto err;
193 }
194 }
195
196 return (0);
197
198err:
199 return (-1);
200}
201
202void
203ressl_free(struct ressl *ctx)
204{
205 if (ctx == NULL)
206 return;
207 ressl_reset(ctx);
208 free(ctx);
209}
210
211void
212ressl_reset(struct ressl *ctx)
213{
214 SSL_CTX_free(ctx->ssl_ctx);
215 SSL_free(ctx->ssl_conn);
216
217 ctx->ssl_conn = NULL;
218 ctx->ssl_ctx = NULL;
219
220 ctx->socket = -1;
221
222 ctx->err = 0;
223 free(ctx->errmsg);
224 ctx->errmsg = NULL;
225}
226
227int
228ressl_read(struct ressl *ctx, void *buf, size_t buflen, size_t *outlen)
229{
230 int ret, ssl_err;
231
232 ret = SSL_read(ctx->ssl_conn, buf, buflen);
233 if (ret > 0) {
234 *outlen = (size_t)ret;
235 return (0);
236 }
237
238 ssl_err = SSL_get_error(ctx->ssl_conn, ret);
239 switch (ssl_err) {
240 case SSL_ERROR_WANT_READ:
241 return (RESSL_READ_AGAIN);
242 case SSL_ERROR_WANT_WRITE:
243 return (RESSL_WRITE_AGAIN);
244 default:
245 ressl_set_error(ctx, "read failed (%i)", ssl_err);
246 return (-1);
247 }
248}
249
250int
251ressl_write(struct ressl *ctx, const void *buf, size_t buflen, size_t *outlen)
252{
253 int ret, ssl_err;
254
255 ret = SSL_write(ctx->ssl_conn, buf, buflen);
256 if (ret > 0) {
257 *outlen = (size_t)ret;
258 return (0);
259 }
260
261 ssl_err = SSL_get_error(ctx->ssl_conn, ret);
262 switch (ssl_err) {
263 case SSL_ERROR_WANT_READ:
264 return (RESSL_READ_AGAIN);
265 case SSL_ERROR_WANT_WRITE:
266 return (RESSL_WRITE_AGAIN);
267 default:
268 ressl_set_error(ctx, "write failed (%i)", ssl_err);
269 return (-1);
270 }
271}
272
273int
274ressl_close(struct ressl *ctx)
275{
276 /* XXX - handle case where multiple calls are required. */
277 if (ctx->ssl_conn != NULL) {
278 if (SSL_shutdown(ctx->ssl_conn) == -1) {
279 ressl_set_error(ctx, "SSL shutdown failed");
280 goto err;
281 }
282 }
283
284 if (ctx->socket != -1) {
285 if (shutdown(ctx->socket, SHUT_RDWR) != 0) {
286 ressl_set_error(ctx, "shutdown");
287 goto err;
288 }
289 if (close(ctx->socket) != 0) {
290 ressl_set_error(ctx, "close");
291 goto err;
292 }
293 ctx->socket = -1;
294 }
295
296 return (0);
297
298err:
299 return (-1);
300}