plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

openssl.c (1479B)


      1 #include <u.h>
      2 #include <openssl/bio.h>
      3 #include <openssl/ssl.h>
      4 #include <openssl/err.h>
      5 #include "a.h"
      6 
      7 AUTOLIB(ssl)
      8 
      9 static void
     10 httpsinit(void)
     11 {
     12 	ERR_load_crypto_strings();
     13 	ERR_load_SSL_strings();
     14 	SSL_load_error_strings();
     15 	SSL_library_init();
     16 }
     17 
     18 struct Pfd
     19 {
     20 	BIO *sbio;
     21 };
     22 
     23 static Pfd*
     24 opensslconnect(char *host)
     25 {
     26 	Pfd *pfd;
     27 	BIO *sbio;
     28 	SSL_CTX *ctx;
     29 	SSL *ssl;
     30 	static int didinit;
     31 	char buf[1024];
     32 
     33 	if(!didinit){
     34 		httpsinit();
     35 		didinit = 1;
     36 	}
     37 
     38 	ctx = SSL_CTX_new(SSLv23_client_method());
     39 	sbio = BIO_new_ssl_connect(ctx);
     40 	BIO_get_ssl(sbio, &ssl);
     41 	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
     42 
     43 	snprint(buf, sizeof buf, "%s:https", host);
     44 	BIO_set_conn_hostname(sbio, buf);
     45 
     46 	if(BIO_do_connect(sbio) <= 0 || BIO_do_handshake(sbio) <= 0){
     47 		ERR_error_string_n(ERR_get_error(), buf, sizeof buf);
     48 		BIO_free_all(sbio);
     49 		werrstr("openssl: %s", buf);
     50 		return nil;
     51 	}
     52 
     53 	pfd = emalloc(sizeof *pfd);
     54 	pfd->sbio = sbio;
     55 	return pfd;
     56 }
     57 
     58 static void
     59 opensslclose(Pfd *pfd)
     60 {
     61 	if(pfd == nil)
     62 		return;
     63 	BIO_free_all(pfd->sbio);
     64 	free(pfd);
     65 }
     66 
     67 static int
     68 opensslwrite(Pfd *pfd, void *v, int n)
     69 {
     70 	int m, total;
     71 	char *p;
     72 
     73 	p = v;
     74 	total = 0;
     75 	while(total < n){
     76 		if((m = BIO_write(pfd->sbio, p+total, n-total)) <= 0){
     77 			if(total == 0)
     78 				return m;
     79 			return total;
     80 		}
     81 		total += m;
     82 	}
     83 	return total;
     84 }
     85 
     86 static int
     87 opensslread(Pfd *pfd, void *v, int n)
     88 {
     89 	return BIO_read(pfd->sbio, v, n);
     90 }
     91 
     92 Protocol https =
     93 {
     94 	opensslconnect,
     95 	opensslread,
     96 	opensslwrite,
     97 	opensslclose
     98 };