plong

Unnamed repository; edit this file 'description' to name the repository.
git clone https://git.inz.fi/plong
Log | Files | Refs

minitls.h (2972B)


      1 /*
      2  * MIT License
      3  *
      4  * Copyright (c) 2023 Santtu Lakkala
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  */
     24 #ifndef MINITLS_H
     25 #define MINITLS_H
     26 #include <openssl/ssl.h>
     27 #include <stdbool.h>
     28 
     29 #define TLS_WANT_POLLIN -2
     30 #define TLS_WANT_POLLOUT -3
     31 
     32 struct tls {
     33 	SSL_CTX *ctx;
     34 	SSL *ssl;
     35 	int err;
     36 };
     37 
     38 static inline struct tls *tls_client(void)
     39 {
     40 	static bool ready = false;
     41 	const SSL_METHOD *method;
     42 	struct tls *rv = malloc(sizeof(*rv));
     43 
     44 	if (!rv)
     45 		return NULL;
     46 
     47 	if (!ready) {
     48 		SSL_library_init();
     49 		OpenSSL_add_all_algorithms();
     50 		ready = true;
     51 	}
     52 
     53 	method = TLS_client_method();
     54 	rv->ctx = SSL_CTX_new(method);
     55 	rv->ssl = NULL;
     56 	SSL_CTX_set_default_verify_paths(rv->ctx);
     57 
     58 	return rv;
     59 }
     60 
     61 static inline ssize_t tls_read(struct tls *ctx, void *buf, size_t buflen)
     62 {
     63 	ssize_t r = SSL_read(ctx->ssl, buf, buflen);
     64 	if (r >= 0)
     65 		return r;
     66 	ctx->err = r;
     67 	r = SSL_get_error(ctx->ssl, r);
     68 	if (r == SSL_ERROR_WANT_READ)
     69 		return TLS_WANT_POLLIN;
     70 	if (r == SSL_ERROR_WANT_WRITE)
     71 		return TLS_WANT_POLLOUT;
     72 	return -1;
     73 }
     74 
     75 static inline ssize_t tls_write(struct tls *ctx, const void *buf, size_t buflen)
     76 {
     77 	ssize_t r = SSL_write(ctx->ssl, buf, buflen);
     78 	if (r >= 0)
     79 		return r;
     80 	ctx->err = r;
     81 	r = SSL_get_error(ctx->ssl, r);
     82 	if (r == SSL_ERROR_WANT_READ)
     83 		return TLS_WANT_POLLIN;
     84 	if (r == SSL_ERROR_WANT_WRITE)
     85 		return TLS_WANT_POLLOUT;
     86 	return -1;
     87 }
     88 
     89 static inline void tls_reset(struct tls *ctx)
     90 {
     91 	SSL_free(ctx->ssl);
     92 	ctx->ssl = NULL;
     93 }
     94 
     95 static inline int tls_connect_socket(struct tls *ctx, int fd, const char *servername)
     96 {
     97 	if (!(ctx->ssl = SSL_new(ctx->ctx)))
     98 		return -1;
     99 
    100 	SSL_set_fd(ctx->ssl, fd);
    101 	SSL_set_tlsext_host_name(ctx->ssl, servername);
    102 	if ((ctx->err = SSL_connect(ctx->ssl)) != 1)
    103 		return -1;
    104 	return 0;
    105 }
    106 
    107 static inline int tls_close(struct tls *ctx)
    108 {
    109 	SSL_shutdown(ctx->ssl);
    110 	return 0;
    111 }
    112 
    113 static inline void tls_free(struct tls *ctx)
    114 {
    115 	SSL_CTX_free(ctx->ctx);
    116 	free(ctx);
    117 }
    118 
    119 #define tls_configure(x, y)
    120 
    121 #endif