99 lines
1.4 KiB
C
99 lines
1.4 KiB
C
|
|
#include <u.h>
|
||
|
|
#include <openssl/bio.h>
|
||
|
|
#include <openssl/ssl.h>
|
||
|
|
#include <openssl/err.h>
|
||
|
|
#include "a.h"
|
||
|
|
|
||
|
|
AUTOLIB(ssl)
|
||
|
|
|
||
|
|
static void
|
||
|
|
httpsinit(void)
|
||
|
|
{
|
||
|
|
ERR_load_crypto_strings();
|
||
|
|
ERR_load_SSL_strings();
|
||
|
|
SSL_load_error_strings();
|
||
|
|
SSL_library_init();
|
||
|
|
}
|
||
|
|
|
||
|
|
struct Pfd
|
||
|
|
{
|
||
|
|
BIO *sbio;
|
||
|
|
};
|
||
|
|
|
||
|
|
static Pfd*
|
||
|
|
opensslconnect(char *host)
|
||
|
|
{
|
||
|
|
Pfd *pfd;
|
||
|
|
BIO *sbio;
|
||
|
|
SSL_CTX *ctx;
|
||
|
|
SSL *ssl;
|
||
|
|
static int didinit;
|
||
|
|
char buf[1024];
|
||
|
|
|
||
|
|
if(!didinit){
|
||
|
|
httpsinit();
|
||
|
|
didinit = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
ctx = SSL_CTX_new(SSLv23_client_method());
|
||
|
|
sbio = BIO_new_ssl_connect(ctx);
|
||
|
|
BIO_get_ssl(sbio, &ssl);
|
||
|
|
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||
|
|
|
||
|
|
snprint(buf, sizeof buf, "%s:https", host);
|
||
|
|
BIO_set_conn_hostname(sbio, buf);
|
||
|
|
|
||
|
|
if(BIO_do_connect(sbio) <= 0 || BIO_do_handshake(sbio) <= 0){
|
||
|
|
ERR_error_string_n(ERR_get_error(), buf, sizeof buf);
|
||
|
|
BIO_free_all(sbio);
|
||
|
|
werrstr("openssl: %s", buf);
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
|
||
|
|
pfd = emalloc(sizeof *pfd);
|
||
|
|
pfd->sbio = sbio;
|
||
|
|
return pfd;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
opensslclose(Pfd *pfd)
|
||
|
|
{
|
||
|
|
if(pfd == nil)
|
||
|
|
return;
|
||
|
|
BIO_free_all(pfd->sbio);
|
||
|
|
free(pfd);
|
||
|
|
}
|
||
|
|
|
||
|
|
static int
|
||
|
|
opensslwrite(Pfd *pfd, void *v, int n)
|
||
|
|
{
|
||
|
|
int m, total;
|
||
|
|
char *p;
|
||
|
|
|
||
|
|
p = v;
|
||
|
|
total = 0;
|
||
|
|
while(total < n){
|
||
|
|
if((m = BIO_write(pfd->sbio, p+total, n-total)) <= 0){
|
||
|
|
if(total == 0)
|
||
|
|
return m;
|
||
|
|
return total;
|
||
|
|
}
|
||
|
|
total += m;
|
||
|
|
}
|
||
|
|
return total;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int
|
||
|
|
opensslread(Pfd *pfd, void *v, int n)
|
||
|
|
{
|
||
|
|
return BIO_read(pfd->sbio, v, n);
|
||
|
|
}
|
||
|
|
|
||
|
|
Protocol https =
|
||
|
|
{
|
||
|
|
opensslconnect,
|
||
|
|
opensslread,
|
||
|
|
opensslwrite,
|
||
|
|
opensslclose
|
||
|
|
};
|