From d1e9aa49ea13bf3dce11552ecb05baf2ce5f4bac Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 9 Sep 2021 19:55:49 +0300 Subject: [PATCH] net.http: in memory cert verification --- vlib/net/http/backend_nix.c.v | 26 +++++++++++++++++++++++--- vlib/net/http/http.v | 10 ++++++---- vlib/net/http/request.v | 9 +++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/vlib/net/http/backend_nix.c.v b/vlib/net/http/backend_nix.c.v index 06112b408f..b8d07eebbd 100644 --- a/vlib/net/http/backend_nix.c.v +++ b/vlib/net/http/backend_nix.c.v @@ -5,6 +5,8 @@ module http import strings import net.openssl +import os +import time const ( is_used = openssl.is_used @@ -22,21 +24,39 @@ fn (req &Request) ssl_do(port int, method Method, host_name string, path string) flags := C.SSL_OP_NO_SSLv2 | C.SSL_OP_NO_SSLv3 | C.SSL_OP_NO_COMPRESSION C.SSL_CTX_set_options(ctx, flags) // Support client certificates: + mut verify := req.verify + mut cert := req.cert + mut cert_key := req.cert_key + if req.in_memory_verification { + now := time.now().unix.str() + verify = os.temp_dir() + '/v_verify' + now + cert = os.temp_dir() + '/v_cert' + now + cert_key = os.temp_dir() + '/v_cert_key' + now + if req.verify != '' { + os.write_file(verify, req.verify) ? + } + if req.cert != '' { + os.write_file(cert, req.cert) ? + } + if req.cert_key != '' { + os.write_file(cert_key, req.cert_key) ? + } + } mut res := 0 if req.verify != '' { - res = C.SSL_CTX_load_verify_locations(ctx, &char(req.verify.str), 0) + res = C.SSL_CTX_load_verify_locations(ctx, &char(verify.str), 0) if req.validate && res != 1 { return error('http: openssl: SSL_CTX_load_verify_locations failed') } } if req.cert != '' { - res = C.SSL_CTX_use_certificate_file(ctx, &char(req.cert.str), C.SSL_FILETYPE_PEM) + res = C.SSL_CTX_use_certificate_file(ctx, &char(cert.str), C.SSL_FILETYPE_PEM) if req.validate && res != 1 { return error('http: openssl: SSL_CTX_use_certificate_file failed, res: $res') } } if req.cert_key != '' { - res = C.SSL_CTX_use_PrivateKey_file(ctx, &char(req.cert_key.str), C.SSL_FILETYPE_PEM) + res = C.SSL_CTX_use_PrivateKey_file(ctx, &char(cert_key.str), C.SSL_FILETYPE_PEM) if req.validate && res != 1 { return error('http: openssl: SSL_CTX_use_PrivateKey_file failed, res: $res') } diff --git a/vlib/net/http/http.v b/vlib/net/http/http.v index a6a850f5a6..3ad3e514ad 100644 --- a/vlib/net/http/http.v +++ b/vlib/net/http/http.v @@ -23,10 +23,11 @@ pub mut: user_agent string = 'v.http' verbose bool // - validate bool // set this to true, if you want to stop requests, when their certificates are found to be invalid - verify string // the path to a rootca.pem file, containing trusted CA certificate(s) - cert string // the path to a cert.pem file, containing client certificate(s) for the request - cert_key string // the path to a key.pem file, containing private keys for the client certificate(s) + validate bool // set this to true, if you want to stop requests, when their certificates are found to be invalid + verify string // the path to a rootca.pem file, containing trusted CA certificate(s) + cert string // the path to a cert.pem file, containing client certificate(s) for the request + cert_key string // the path to a key.pem file, containing private keys for the client certificate(s) + in_memory_verification bool // if true, verify, cert, and cert_key are read from memory, not from a file } pub fn new_request(method Method, url_ string, data string) ?Request { @@ -128,6 +129,7 @@ pub fn fetch(config FetchConfig) ?Response { verify: config.verify cert: config.cert cert_key: config.cert_key + in_memory_verification: config.in_memory_verification } res := req.do() ? return res diff --git a/vlib/net/http/request.v b/vlib/net/http/request.v index d6c53c38f0..41e22d917a 100644 --- a/vlib/net/http/request.v +++ b/vlib/net/http/request.v @@ -27,10 +27,11 @@ pub mut: read_timeout i64 = 30 * time.second write_timeout i64 = 30 * time.second // - validate bool // when true, certificate failures will stop further processing - verify string - cert string - cert_key string + validate bool // when true, certificate failures will stop further processing + verify string + cert string + cert_key string + in_memory_verification bool // if true, verify, cert, and cert_key are read from memory, not from a file } fn (mut req Request) free() {