/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* https://www.openssl.org/source/license.html
*/
-/* callback functions used by s_client, s_server, and s_time */
+/*
+ * callback functions used by s_client, s_server, and s_time,
+ * as well as other common logic for those apps
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for memcpy() and strcmp() */
STACK_OF(X509) *chain, int build_chain)
{
int chflags = chain ? SSL_BUILD_CHAIN_FLAG_CHECK : 0;
+
if (cert == NULL)
return 1;
if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
const unsigned char *p;
int i;
int cert_type_num = SSL_get0_certificate_types(s, &p);
+
if (!cert_type_num)
return;
BIO_puts(bio, "Client Certificate Types: ");
case EVP_PKEY_DSA:
return "DSA";
- case EVP_PKEY_EC:
+ case EVP_PKEY_EC:
return "ECDSA";
- case NID_ED25519:
+ case NID_ED25519:
return "Ed25519";
- case NID_ED448:
+ case NID_ED448:
return "Ed448";
- case NID_id_GostR3410_2001:
+ case NID_id_GostR3410_2001:
return "gost2001";
- case NID_id_GostR3410_2012_256:
+ case NID_id_GostR3410_2012_256:
return "gost2012_256";
- case NID_id_GostR3410_2012_512:
+ case NID_id_GostR3410_2012_512:
return "gost2012_512";
default:
static int do_print_sigalgs(BIO *out, SSL *s, int shared)
{
int i, nsig, client;
+
client = SSL_is_server(s) ? 0 : 1;
if (shared)
nsig = SSL_get_shared_sigalgs(s, 0, NULL, NULL, NULL, NULL, NULL);
int ssl_print_sigalgs(BIO *out, SSL *s)
{
int nid;
+
if (!SSL_is_server(s))
ssl_print_client_cert_types(out, s);
do_print_sigalgs(out, s, 0);
{
int i, nformats;
const char *pformats;
+
nformats = SSL_get0_ec_point_formats(s, &pformats);
if (nformats <= 0)
return 1;
int ssl_print_groups(BIO *out, SSL *s, int noshared)
{
int i, ngroups, *groups, nid;
- const char *gname;
ngroups = SSL_get1_groups(s, NULL);
if (ngroups <= 0)
groups = app_malloc(ngroups * sizeof(int), "groups to print");
SSL_get1_groups(s, groups);
- BIO_puts(out, "Supported Elliptic Groups: ");
+ BIO_puts(out, "Supported groups: ");
for (i = 0; i < ngroups; i++) {
if (i)
BIO_puts(out, ":");
nid = groups[i];
- /* If unrecognised print out hex version */
- if (nid & TLSEXT_nid_unknown) {
- BIO_printf(out, "0x%04X", nid & 0xFFFF);
- } else {
- /* TODO(TLS1.3): Get group name here */
- /* Use NIST name for curve if it exists */
- gname = EC_curve_nid2nist(nid);
- if (gname == NULL)
- gname = OBJ_nid2sn(nid);
- BIO_printf(out, "%s", gname);
- }
+ BIO_printf(out, "%s", SSL_group_to_name(s, nid));
}
OPENSSL_free(groups);
if (noshared) {
BIO_puts(out, "\n");
return 1;
}
- BIO_puts(out, "\nShared Elliptic groups: ");
+ BIO_puts(out, "\nShared groups: ");
ngroups = SSL_get_shared_group(s, -1);
for (i = 0; i < ngroups; i++) {
if (i)
BIO_puts(out, ":");
nid = SSL_get_shared_group(s, i);
- /* TODO(TLS1.3): Convert for DH groups */
- gname = EC_curve_nid2nist(nid);
- if (gname == NULL)
- gname = OBJ_nid2sn(nid);
- BIO_printf(out, "%s", gname);
+ BIO_printf(out, "%s", SSL_group_to_name(s, nid));
}
if (ngroups == 0)
BIO_puts(out, "NONE");
if (!SSL_get_peer_tmp_key(s, &key))
return 1;
BIO_puts(out, "Server Temp Key: ");
- switch (EVP_PKEY_id(key)) {
+ switch (EVP_PKEY_get_id(key)) {
case EVP_PKEY_RSA:
- BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_bits(key));
+ BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_get_bits(key));
break;
case EVP_PKEY_DH:
- BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key));
+ BIO_printf(out, "DH, %d bits\n", EVP_PKEY_get_bits(key));
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
{
- EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key);
- int nid;
- const char *cname;
- nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
- EC_KEY_free(ec);
- cname = EC_curve_nid2nist(nid);
- if (cname == NULL)
- cname = OBJ_nid2sn(nid);
- BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(key));
+ char name[80];
+ size_t name_len;
+
+ if (!EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_GROUP_NAME,
+ name, sizeof(name), &name_len))
+ strcpy(name, "?");
+ BIO_printf(out, "ECDH, %s, %d bits\n", name, EVP_PKEY_get_bits(key));
}
break;
#endif
default:
- BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(key)),
- EVP_PKEY_bits(key));
+ BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_get_id(key)),
+ EVP_PKEY_get_bits(key));
}
EVP_PKEY_free(key);
return 1;
}
-long bio_dump_callback(BIO *bio, int cmd, const char *argp,
- int argi, long argl, long ret)
+long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
+ int argi, long argl, int ret, size_t *processed)
{
BIO *out;
return ret;
if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
- BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
- (void *)bio, (void *)argp, (unsigned long)argi, ret, ret);
- BIO_dump(out, argp, (int)ret);
- return ret;
+ if (ret > 0 && processed != NULL) {
+ BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n",
+ (void *)bio, (void *)argp, len, *processed, *processed);
+ BIO_dump(out, argp, (int)*processed);
+ } else {
+ BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n",
+ (void *)bio, (void *)argp, len, ret);
+ }
} else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
- BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
- (void *)bio, (void *)argp, (unsigned long)argi, ret, ret);
- BIO_dump(out, argp, (int)ret);
+ if (ret > 0 && processed != NULL) {
+ BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n",
+ (void *)bio, (void *)argp, len, *processed, *processed);
+ BIO_dump(out, argp, (int)*processed);
+ } else {
+ BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n",
+ (void *)bio, (void *)argp, len, ret);
+ }
}
return ret;
}
}
#ifndef OPENSSL_NO_SOCK
-int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
- unsigned int *cookie_len)
+int generate_stateless_cookie_callback(SSL *ssl, unsigned char *cookie,
+ size_t *cookie_len)
{
unsigned char *buffer = NULL;
size_t length = 0;
unsigned short port;
BIO_ADDR *lpeer = NULL, *peer = NULL;
int res = 0;
- EVP_MAC *hmac = NULL;
- EVP_MAC_CTX *ctx = NULL;
- OSSL_PARAM params[3], *p = params;
- size_t mac_len;
/* Initialize a random secret */
if (!cookie_initialized) {
/* Create buffer with peer's address and port */
if (!BIO_ADDR_rawaddress(peer, NULL, &length)) {
BIO_printf(bio_err, "Failed getting peer address\n");
+ BIO_ADDR_free(lpeer);
return 0;
}
OPENSSL_assert(length != 0);
memcpy(buffer, &port, sizeof(port));
BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL);
- /* Calculate HMAC of buffer using the secret */
- hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
- if (hmac == NULL) {
- BIO_printf(bio_err, "HMAC not found\n");
- goto end;
- }
- ctx = EVP_MAC_CTX_new(hmac);
- if (ctx == NULL) {
- BIO_printf(bio_err, "HMAC context allocation failed\n");
- goto end;
- }
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "SHA1", 0);
- *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)) {
- BIO_printf(bio_err, "HMAC context parameter setting failed\n");
- goto end;
- }
- if (!EVP_MAC_init(ctx)) {
- BIO_printf(bio_err, "HMAC context initialisation failed\n");
- goto end;
- }
- if (!EVP_MAC_update(ctx, buffer, length)) {
- BIO_printf(bio_err, "HMAC context update failed\n");
- goto end;
- }
- if (!EVP_MAC_final(ctx, cookie, &mac_len, DTLS1_COOKIE_LENGTH)) {
- BIO_printf(bio_err, "HMAC context final failed\n");
- goto end;
+ if (EVP_Q_mac(NULL, "HMAC", NULL, "SHA1", NULL,
+ cookie_secret, COOKIE_SECRET_LENGTH, buffer, length,
+ cookie, DTLS1_COOKIE_LENGTH, cookie_len) == NULL) {
+ BIO_printf(bio_err,
+ "Error calculating HMAC-SHA1 of buffer with secret\n");
+ goto end;
}
- *cookie_len = (int)mac_len;
res = 1;
end:
OPENSSL_free(buffer);
return res;
}
-int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
- unsigned int cookie_len)
+int verify_stateless_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ size_t cookie_len)
{
unsigned char result[EVP_MAX_MD_SIZE];
- unsigned int resultlength;
+ size_t resultlength;
/* Note: we check cookie_initialized because if it's not,
* it cannot be valid */
if (cookie_initialized
- && generate_cookie_callback(ssl, result, &resultlength)
+ && generate_stateless_cookie_callback(ssl, result, &resultlength)
&& cookie_len == resultlength
&& memcmp(result, cookie, resultlength) == 0)
return 1;
return 0;
}
-int generate_stateless_cookie_callback(SSL *ssl, unsigned char *cookie,
- size_t *cookie_len)
+int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
+ unsigned int *cookie_len)
{
- unsigned int temp = 0;
+ size_t temp = 0;
+ int res = generate_stateless_cookie_callback(ssl, cookie, &temp);
- int res = generate_cookie_callback(ssl, cookie, &temp);
- *cookie_len = temp;
+ if (res != 0)
+ *cookie_len = (unsigned int)temp;
return res;
}
-int verify_stateless_cookie_callback(SSL *ssl, const unsigned char *cookie,
- size_t cookie_len)
+int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ unsigned int cookie_len)
{
- return verify_cookie_callback(ssl, cookie, cookie_len);
+ return verify_stateless_cookie_callback(ssl, cookie, cookie_len);
}
#endif
SSL_EXCERT *exc = arg;
#ifdef CERT_CB_TEST_RETRY
static int retry_cnt;
+
if (retry_cnt < 5) {
retry_cnt++;
BIO_printf(bio_err,
if (!SSL_build_cert_chain(ssl, 0))
return 0;
} else if (exc->chain != NULL) {
- SSL_set1_chain(ssl, exc->chain);
+ if (!SSL_set1_chain(ssl, exc->chain))
+ return 0;
}
}
exc = exc->prev;
while (exc) {
X509_free(exc->cert);
EVP_PKEY_free(exc->key);
- sk_X509_pop_free(exc->chain, X509_free);
+ OSSL_STACK_OF_X509_free(exc->chain);
curr = exc;
exc = exc->next;
OPENSSL_free(curr);
int load_excert(SSL_EXCERT **pexc)
{
SSL_EXCERT *exc = *pexc;
+
if (exc == NULL)
return 1;
/* If nothing in list, free and set to NULL */
return 0;
if (exc->keyfile != NULL) {
exc->key = load_key(exc->keyfile, exc->keyform,
- 0, NULL, NULL, "Server Key");
+ 0, NULL, NULL, "server key");
} else {
exc->key = load_key(exc->certfile, exc->certform,
- 0, NULL, NULL, "Server Key");
+ 0, NULL, NULL, "server key");
}
if (exc->key == NULL)
return 0;
if (exc->chainfile != NULL) {
- if (!load_certs(exc->chainfile, &exc->chain, NULL, "Server Chain"))
+ if (!load_certs(exc->chainfile, 0, &exc->chain, NULL, "server chain"))
return 0;
}
}
const unsigned char *rlist;
static const unsigned char scsv_id[] = { 0, 0xFF };
size_t i, rlistlen, num;
+
if (!SSL_is_server(s))
return;
num = SSL_get0_raw_cipherlist(s, NULL);
for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) {
const char *flag = sk_OPENSSL_STRING_value(str, i);
const char *arg = sk_OPENSSL_STRING_value(str, i + 1);
+
if (SSL_CONF_cmd(cctx, flag, arg) <= 0) {
- if (arg != NULL)
- BIO_printf(bio_err, "Error with command: \"%s %s\"\n",
- flag, arg);
- else
- BIO_printf(bio_err, "Error with command: \"%s\"\n", flag);
+ BIO_printf(bio_err, "Call to SSL_CONF_cmd(%s, %s) failed\n",
+ flag, arg == NULL ? "<NULL>" : arg);
ERR_print_errors(bio_err);
return 0;
}
static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls)
{
X509_CRL *crl;
- int i;
+ int i, ret = 1;
+
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
crl = sk_X509_CRL_value(crls, i);
- X509_STORE_add_crl(st, crl);
+ if (!X509_STORE_add_crl(st, crl))
+ ret = 0;
}
- return 1;
+ return ret;
}
int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download)
{
X509_STORE *st;
+
st = SSL_CTX_get_cert_store(ctx);
add_crls_store(st, crls);
if (crl_download)
{
X509_STORE *vfy = NULL, *ch = NULL;
int rv = 0;
+
if (vfyCApath != NULL || vfyCAfile != NULL || vfyCAstore != NULL) {
vfy = X509_STORE_new();
if (vfy == NULL)
int rv, show_bits = 1, cert_md = 0;
const char *nm;
int show_nm;
+
rv = sdb->old_cb(s, ctx, op, bits, nid, other, ex);
if (rv == 1 && sdb->verbose < 2)
return 1;
BIO_puts(sdb->out, cname);
}
break;
-#endif
-#ifndef OPENSSL_NO_DH
- case SSL_SECOP_OTHER_DH:
- {
- DH *dh = other;
- EVP_PKEY *pkey = EVP_PKEY_new();
- int fail = 1;
-
- if (pkey != NULL) {
- if (EVP_PKEY_set1_DH(pkey, dh)) {
- BIO_printf(sdb->out, "%d", EVP_PKEY_bits(pkey));
- fail = 0;
- }
-
- EVP_PKEY_free(pkey);
- }
- if (fail)
- BIO_printf(sdb->out, "s_cb.c:security_callback_debug op=0x%x",
- op);
- break;
- }
#endif
case SSL_SECOP_OTHER_CERT:
{
if (cert_md) {
int sig_nid = X509_get_signature_nid(other);
+
BIO_puts(sdb->out, OBJ_nid2sn(sig_nid));
} else {
EVP_PKEY *pkey = X509_get0_pubkey(other);
- const char *algname = "";
- EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL,
- &algname, EVP_PKEY_get0_asn1(pkey));
- BIO_printf(sdb->out, "%s, bits=%d",
- algname, EVP_PKEY_bits(pkey));
+
+ if (pkey == NULL) {
+ BIO_printf(sdb->out, "Public key missing");
+ } else {
+ const char *algname = "";
+
+ EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL,
+ &algname, EVP_PKEY_get0_asn1(pkey));
+ BIO_printf(sdb->out, "%s, bits=%d",
+ algname, EVP_PKEY_get_bits(pkey));
+ }
}
break;
}
return;
}
- BIO_printf(bio, "---\nAcceptable %s certificate CA names\n",cs);
+ BIO_printf(bio, "---\nAcceptable %s certificate CA names\n", cs);
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
X509_NAME_print_ex(bio, sk_X509_NAME_value(sk, i), 0, get_nameopt());
BIO_write(bio, "\n", 1);
}
}
+
+void ssl_print_secure_renegotiation_notes(BIO *bio, SSL *s)
+{
+ if (SSL_VERSION_ALLOWS_RENEGOTIATION(s)) {
+ BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
+ SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
+ } else {
+ BIO_printf(bio, "This TLS version forbids renegotiation.\n");
+ }
+}
+
+int progress_cb(EVP_PKEY_CTX *ctx)
+{
+ BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+ int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+ static const char symbols[] = ".+*\n";
+ char c = (p >= 0 && (size_t)p <= sizeof(symbols) - 1) ? symbols[p] : '?';
+
+ BIO_write(b, &c, 1);
+ (void)BIO_flush(b);
+ return 1;
+}
+