Blob


1 #include <u.h>
2 #include <openssl/bio.h>
3 #include <openssl/ssl.h>
4 #include <openssl/err.h>
5 #include "a.h"
7 AUTOLIB(ssl)
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 }
18 struct Pfd
19 {
20 BIO *sbio;
21 };
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];
33 if(!didinit){
34 httpsinit();
35 didinit = 1;
36 }
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);
43 snprint(buf, sizeof buf, "%s:https", host);
44 BIO_set_conn_hostname(sbio, buf);
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 }
53 pfd = emalloc(sizeof *pfd);
54 pfd->sbio = sbio;
55 return pfd;
56 }
58 static void
59 opensslclose(Pfd *pfd)
60 {
61 if(pfd == nil)
62 return;
63 BIO_free_all(pfd->sbio);
64 free(pfd);
65 }
67 static int
68 opensslwrite(Pfd *pfd, void *v, int n)
69 {
70 int m, total;
71 char *p;
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 }
86 static int
87 opensslread(Pfd *pfd, void *v, int n)
88 {
89 return BIO_read(pfd->sbio, v, n);
90 }
92 Protocol https =
93 {
94 opensslconnect,
95 opensslread,
96 opensslwrite,
97 opensslclose
98 };