Latest update (add quic)

This commit is contained in:
2020-07-12 19:52:18 +09:00
parent 3a6d64bb68
commit e85ee33eee
501 changed files with 19166 additions and 10232 deletions
+25 -198
View File
@@ -438,10 +438,6 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin,
if (desc == NULL)
desc = "certificate";
if (uri == NULL) {
unbuffer(stdin);
uri = "";
}
(void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL);
if (cert == NULL) {
BIO_printf(bio_err, "Unable to load %s\n", desc);
@@ -453,7 +449,7 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin,
/* the format parameter is meanwhile not needed anymore and thus ignored */
X509 *load_cert(const char *uri, int format, const char *desc)
{
return load_cert_pass(uri, 0, NULL, desc);
return load_cert_pass(uri, 1, NULL, desc);
}
/* the format parameter is meanwhile not needed anymore and thus ignored */
@@ -671,16 +667,24 @@ static int load_certs_crls(const char *file, int format,
return rv;
}
void app_bail_out(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
BIO_vprintf(bio_err, fmt, args);
va_end(args);
ERR_print_errors(bio_err);
exit(1);
}
void* app_malloc(int sz, const char *what)
{
void *vp = OPENSSL_malloc(sz);
if (vp == NULL) {
BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n",
opt_getprog(), sz, what);
ERR_print_errors(bio_err);
exit(1);
}
if (vp == NULL)
app_bail_out("%s: Could not allocate %d bytes for %s\n",
opt_getprog(), sz, what);
return vp;
}
@@ -1627,7 +1631,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
goto err;
}
while (*cp) {
while (*cp != '\0') {
char *bp = work;
char *typestr = bp;
unsigned char *valstr;
@@ -1636,12 +1640,12 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
nextismulti = 0;
/* Collect the type */
while (*cp && *cp != '=')
while (*cp != '\0' && *cp != '=')
*bp++ = *cp++;
if (*cp == '\0') {
BIO_printf(bio_err,
"%s: Hit end of string before finding the '='\n",
opt_getprog());
"%s: Hit end of string before finding the '='\n",
opt_getprog());
goto err;
}
*bp++ = '\0';
@@ -1649,7 +1653,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
/* Collect the value. */
valstr = (unsigned char *)bp;
for (; *cp && *cp != '/'; *bp++ = *cp++) {
for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) {
if (canmulti && *cp == '+') {
nextismulti = 1;
break;
@@ -1664,7 +1668,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
*bp++ = '\0';
/* If not at EOS (must be + or /), move forward. */
if (*cp)
if (*cp != '\0')
++cp;
/* Parse */
@@ -1683,6 +1687,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
valstr, strlen((char *)valstr),
-1, ismulti ? -1 : 0)) {
ERR_print_errors(bio_err);
BIO_printf(bio_err, "%s: Error adding name attribute \"/%s=%s\"\n",
opt_getprog(), typestr ,valstr);
goto err;
@@ -1949,137 +1954,6 @@ void store_setup_crl_download(X509_STORE *st)
X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
}
#ifndef OPENSSL_NO_SOCK
static const char *tls_error_hint(void)
{
unsigned long err = ERR_peek_error();
if (ERR_GET_LIB(err) != ERR_LIB_SSL)
err = ERR_peek_last_error();
if (ERR_GET_LIB(err) != ERR_LIB_SSL)
return NULL;
switch (ERR_GET_REASON(err)) {
case SSL_R_WRONG_VERSION_NUMBER:
return "The server does not support (a suitable version of) TLS";
case SSL_R_UNKNOWN_PROTOCOL:
return "The server does not support HTTPS";
case SSL_R_CERTIFICATE_VERIFY_FAILED:
return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status";
case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA:
return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status";
case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE:
return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it";
default: /* no error or no hint available for error */
return NULL;
}
}
/* HTTP callback function that supports TLS connection also via HTTPS proxy */
BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
{
APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
SSL_CTX *ssl_ctx = info->ssl_ctx;
SSL *ssl;
BIO *sbio = NULL;
if (connect && detail) { /* connecting with TLS */
if ((info->use_proxy
&& !OSSL_HTTP_proxy_connect(hbio, info->server, info->port,
NULL, NULL, /* no proxy credentials */
info->timeout, bio_err, opt_getprog()))
|| (sbio = BIO_new(BIO_f_ssl())) == NULL) {
return NULL;
}
if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) {
BIO_free(sbio);
return NULL;
}
SSL_set_tlsext_host_name(ssl, info->server);
SSL_set_connect_state(ssl);
BIO_set_ssl(sbio, ssl, BIO_CLOSE);
hbio = BIO_push(sbio, hbio);
} else if (!connect && !detail) { /* disconnecting after error */
const char *hint = tls_error_hint();
if (hint != NULL)
ERR_add_error_data(2, " : ", hint);
/*
* If we pop sbio and BIO_free() it this may lead to libssl double free.
* Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c
*/
}
return hbio;
}
ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
const char *no_proxy, SSL_CTX *ssl_ctx,
const STACK_OF(CONF_VALUE) *headers,
long timeout, const char *expected_content_type,
const ASN1_ITEM *it)
{
APP_HTTP_TLS_INFO info;
char *server;
char *port;
int use_ssl;
ASN1_VALUE *resp = NULL;
if (url == NULL || it == NULL) {
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (!OSSL_HTTP_parse_url(url, &server, &port, NULL /* ppath */, &use_ssl))
return NULL;
if (use_ssl && ssl_ctx == NULL) {
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
ERR_add_error_data(1, "missing SSL_CTX");
goto end;
}
info.server = server;
info.port = port;
info.use_proxy = proxy != NULL;
info.timeout = timeout;
info.ssl_ctx = ssl_ctx;
resp = OSSL_HTTP_get_asn1(url, proxy, no_proxy,
NULL, NULL, app_http_tls_cb, &info,
headers, 0 /* maxline */, 0 /* max_resp_len */,
timeout, expected_content_type, it);
end:
OPENSSL_free(server);
OPENSSL_free(port);
return resp;
}
ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
const char *path, const char *proxy,
const char *no_proxy, SSL_CTX *ssl_ctx,
const STACK_OF(CONF_VALUE) *headers,
const char *content_type,
ASN1_VALUE *req, const ASN1_ITEM *req_it,
long timeout, const ASN1_ITEM *rsp_it)
{
APP_HTTP_TLS_INFO info;
info.server = host;
info.port = port;
info.use_proxy = proxy != NULL;
info.timeout = timeout;
info.ssl_ctx = ssl_ctx;
return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL,
proxy, no_proxy,
NULL, NULL, app_http_tls_cb, &info,
headers, content_type, req, req_it,
0 /* maxline */,
0 /* max_resp_len */, timeout, NULL, rsp_it);
}
#endif
/*
* Platform-specific sections
*/
@@ -2230,70 +2104,23 @@ double app_tminterval(int stop, int usertime)
return ret;
}
#elif defined(OPENSSL_SYSTEM_VMS)
# include <time.h>
# include <times.h>
double app_tminterval(int stop, int usertime)
{
static clock_t tmstart;
double ret = 0;
clock_t now;
# ifdef __TMS
struct tms rus;
now = times(&rus);
if (usertime)
now = rus.tms_utime;
# else
if (usertime)
now = clock(); /* sum of user and kernel times */
else {
struct timeval tv;
gettimeofday(&tv, NULL);
now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
(unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
);
}
# endif
if (stop == TM_START)
tmstart = now;
else
ret = (now - tmstart) / (double)(CLK_TCK);
return ret;
}
#elif defined(_SC_CLK_TCK) /* by means of unistd.h */
# include <sys/times.h>
double app_tminterval(int stop, int usertime)
{
double ret = 0;
clock_t now;
static clock_t tmstart;
long int tck = sysconf(_SC_CLK_TCK);
# ifdef __TMS
struct tms rus;
clock_t now = times(&rus);
static clock_t tmstart;
now = times(&rus);
if (usertime)
now = rus.tms_utime;
# else
if (usertime)
now = clock(); /* sum of user and kernel times */
else {
struct timeval tv;
gettimeofday(&tv, NULL);
now = (clock_t)((unsigned long long)tv.tv_sec * tck +
(unsigned long long)tv.tv_usec * (1000000 / tck)
);
}
# endif
if (stop == TM_START) {
tmstart = now;
} else {
long int tck = sysconf(_SC_CLK_TCK);
ret = (now - tmstart) / (double)tck;
}
+77 -24
View File
@@ -255,17 +255,19 @@ static int urldecode(char *p)
}
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
BIO **pcbio, BIO *acbio,
char **ppath, BIO **pcbio, BIO *acbio,
const char *prog, int accept_get, int timeout)
{
BIO *cbio = NULL, *getbio = NULL, *b64 = NULL;
int len;
char reqbuf[2048], inbuf[2048];
char *url, *end;
char *meth, *url, *end;
ASN1_VALUE *req;
int ret = 1;
*preq = NULL;
if (ppath != NULL)
*ppath = NULL;
*pcbio = NULL;
/* Connection loss before accept() is routine, ignore silently */
@@ -275,6 +277,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
cbio = BIO_pop(acbio);
*pcbio = cbio;
if (cbio == NULL) {
/* Cannot call http_server_send_status(cbio, ...) */
ret = -1;
goto out;
}
@@ -288,16 +291,26 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
/* Read the request line. */
len = BIO_gets(cbio, reqbuf, sizeof(reqbuf));
if (len <= 0)
if (len <= 0) {
log_message(prog, LOG_INFO,
"Request line read error or empty request");
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
if (accept_get && strncmp(reqbuf, "GET ", 4) == 0) {
/* Expecting GET {sp} /URL {sp} HTTP/1.x */
for (url = reqbuf + 4; *url == ' '; ++url)
continue;
meth = reqbuf;
url = meth + 3;
if ((accept_get && strncmp(meth, "GET ", 4) == 0)
|| (url++, strncmp(meth, "POST ", 5) == 0)) {
/* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
*(url++) = '\0';
while (*url == ' ')
url++;
if (*url != '/') {
log_message(prog, LOG_INFO,
"Invalid GET -- URL does not begin with '/': %s", url);
"Invalid %s -- URL does not begin with '/': %s",
meth, url);
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
url++;
@@ -308,7 +321,9 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
break;
if (strncmp(end, " HTTP/1.", 7) != 0) {
log_message(prog, LOG_INFO,
"Invalid GET -- bad HTTP/version string: %s", end + 1);
"Invalid %s -- bad HTTP/version string: %s",
meth, end + 1);
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
*end = '\0';
@@ -318,39 +333,52 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
* 'url' was incremented above to point to the first byte *after*
* the leading slash, so in case 'GET / ' it is now an empty string.
*/
if (url[0] == '\0')
if (strlen(meth) == 3 && url[0] == '\0') {
(void)http_server_send_status(cbio, 200, "OK");
goto out;
}
len = urldecode(url);
if (len <= 0) {
if (len < 0) {
log_message(prog, LOG_INFO,
"Invalid GET request -- bad URL encoding: %s", url);
"Invalid %s request -- bad URL encoding: %s",
meth, url);
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
if ((getbio = BIO_new_mem_buf(url, len)) == NULL
|| (b64 = BIO_new(BIO_f_base64())) == NULL) {
log_message(prog, LOG_ERR,
"Could not allocate base64 bio with size = %d", len);
BIO_free_all(cbio);
*pcbio = NULL;
ret = -1;
goto out;
if (strlen(meth) == 3) { /* GET */
if ((getbio = BIO_new_mem_buf(url, len)) == NULL
|| (b64 = BIO_new(BIO_f_base64())) == NULL) {
log_message(prog, LOG_ERR,
"Could not allocate base64 bio with size = %d",
len);
goto fatal;
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
getbio = BIO_push(b64, getbio);
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
getbio = BIO_push(b64, getbio);
} else if (strncmp(reqbuf, "POST ", 5) != 0) {
} else {
log_message(prog, LOG_INFO,
"HTTP request does not start with GET/POST: %s", reqbuf);
/* TODO provide better diagnosis in case client tries TLS */
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
/* chop any further/duplicate leading or trailing '/' */
while (*url == '/')
url++;
while (end >= url + 2 && end[-2] == '/' && end[-1] == '/')
end--;
*end = '\0';
/* Read and skip past the headers. */
for (;;) {
len = BIO_gets(cbio, inbuf, sizeof(inbuf));
if (len <= 0) {
log_message(prog, LOG_ERR,
"Error skipping remaining HTTP headers");
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
@@ -365,8 +393,14 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
/* Try to read and parse request */
req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL);
if (req == NULL)
if (req == NULL) {
log_message(prog, LOG_ERR, "Error parsing request");
} else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) {
log_message(prog, LOG_ERR,
"Out of memory allocating %d bytes", strlen(url) + 1);
ASN1_item_free(req, it);
goto fatal;
}
*preq = req;
@@ -378,6 +412,17 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
acfd = (int)INVALID_SOCKET;
# endif
return ret;
fatal:
(void)http_server_send_status(cbio, 500, "Internal Server Error");
if (ppath != NULL) {
OPENSSL_free(*ppath);
*ppath = NULL;
}
BIO_free_all(cbio);
*pcbio = NULL;
ret = -1;
goto out;
}
/* assumes that cbio does not do an encoding that changes the output length */
@@ -392,4 +437,12 @@ int http_server_send_asn1_resp(BIO *cbio, const char *content_type,
(void)BIO_flush(cbio);
return ret;
}
int http_server_send_status(BIO *cbio, int status, const char *reason)
{
int ret = BIO_printf(cbio, "HTTP/1.0 %d %s\r\n\r\n", status, reason) > 0;
(void)BIO_flush(cbio);
return ret;
}
#endif
+9 -18
View File
@@ -209,6 +209,7 @@ int opt_format(const char *s, unsigned long flags, int *result)
{
switch (*s) {
default:
opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
return 0;
case 'D':
case 'd':
@@ -275,6 +276,7 @@ int opt_format(const char *s, unsigned long flags, int *result)
return opt_format_error(s, flags);
*result = FORMAT_PKCS12;
} else {
opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
return 0;
}
break;
@@ -740,40 +742,29 @@ int opt_next(void)
break;
case 'p':
case 'n':
if (!opt_int(arg, &ival)
|| (o->valtype == 'p' && ival <= 0)) {
if (!opt_int(arg, &ival))
return -1;
if (o->valtype == 'p' && ival <= 0) {
opt_printf_stderr("%s: Non-positive number \"%s\" for -%s\n",
prog, arg, o->name);
return -1;
}
break;
case 'M':
if (!opt_imax(arg, &imval)) {
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
prog, arg, o->name);
if (!opt_imax(arg, &imval))
return -1;
}
break;
case 'U':
if (!opt_umax(arg, &umval)) {
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
prog, arg, o->name);
if (!opt_umax(arg, &umval))
return -1;
}
break;
case 'l':
if (!opt_long(arg, &lval)) {
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
prog, arg, o->name);
if (!opt_long(arg, &lval))
return -1;
}
break;
case 'u':
if (!opt_ulong(arg, &ulval)) {
opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
prog, arg, o->name);
if (!opt_ulong(arg, &ulval))
return -1;
}
break;
case 'c':
case 'E':
+2 -2
View File
@@ -787,7 +787,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
BIO_printf(bio_err, "HMAC not found\n");
goto end;
}
ctx = EVP_MAC_CTX_new(hmac);
ctx = EVP_MAC_new_ctx(hmac);
if (ctx == NULL) {
BIO_printf(bio_err, "HMAC context allocation failed\n");
goto end;
@@ -796,7 +796,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
*p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, cookie_secret,
COOKIE_SECRET_LENGTH);
*p = OSSL_PARAM_construct_end();
if (!EVP_MAC_CTX_set_params(ctx, params)) {
if (!EVP_MAC_set_ctx_params(ctx, params)) {
BIO_printf(bio_err, "HMAC context parameter setting failed\n");
goto end;
}