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 };