Update pre9

This commit is contained in:
2018-07-08 16:02:48 +09:00
parent 89af373a04
commit 1914ae9055
15 changed files with 416 additions and 49 deletions
+77 -3
View File
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
@@ -23,6 +24,8 @@
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
#include <openssl/bn.h>
#include <openssl/lhash.h>
#ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>
#endif
@@ -147,6 +150,68 @@ const OPTIONS req_options[] = {
{NULL}
};
/*
* An LHASH of strings, where each string is an extension name.
*/
static unsigned long ext_name_hash(const OPENSSL_STRING *a)
{
return OPENSSL_LH_strhash((const char *)a);
}
static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b)
{
return strcmp((const char *)a, (const char *)b);
}
static void exts_cleanup(OPENSSL_STRING *x)
{
OPENSSL_free((char *)x);
}
/*
* Is the |kv| key already duplicated? This is remarkably tricky to get
* right. Return 0 if unique, -1 on runtime error; 1 if found or a syntax
* error.
*/
static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
{
char *p;
/* Check syntax. */
if (strchr(kv, '=') == NULL)
return 1;
/* Skip leading whitespace, make a copy. */
while (*kv && isspace(*kv))
if (*++kv == '\0')
return 1;
if ((kv = OPENSSL_strdup(kv)) == NULL)
return -1;
/* Skip trailing space before the equal sign. */
for (p = strchr(kv, '='); p > kv; --p)
if (p[-1] != ' ' && p[-1] != '\t')
break;
if (p == kv) {
OPENSSL_free(kv);
return 1;
}
*p = '\0';
/* Finally have a clean "key"; see if it's there. */
if (lh_OPENSSL_STRING_retrieve(addexts, (OPENSSL_STRING*)kv) != NULL) {
BIO_printf(bio_err, "Extension \"%s\" repeated\n", kv);
OPENSSL_free(kv);
return 1;
}
/* Not found; add it. */
if (lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv) == NULL)
return -1;
return 0;
}
int req_main(int argc, char **argv)
{
ASN1_INTEGER *serial = NULL;
@@ -155,6 +220,7 @@ int req_main(int argc, char **argv)
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *genctx = NULL;
STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
LHASH_OF(OPENSSL_STRING) *addexts = NULL;
X509 *x509ss = NULL;
X509_REQ *req = NULL;
const EVP_CIPHER *cipher = NULL;
@@ -324,11 +390,17 @@ int req_main(int argc, char **argv)
multirdn = 1;
break;
case OPT_ADDEXT:
if (addext_bio == NULL) {
p = opt_arg();
if (addexts == NULL) {
addexts = lh_OPENSSL_STRING_new(ext_name_hash, ext_name_cmp);
addext_bio = BIO_new(BIO_s_mem());
if (addexts == NULL || addext_bio == NULL)
goto end;
}
if (addext_bio == NULL
|| BIO_printf(addext_bio, "%s\n", opt_arg()) < 0)
i = duplicated(addexts, p);
if (i == 1)
goto opthelp;
if (i < 0 || BIO_printf(addext_bio, "%s\n", opt_arg()) < 0)
goto end;
break;
case OPT_EXTENSIONS:
@@ -885,6 +957,8 @@ int req_main(int argc, char **argv)
EVP_PKEY_CTX_free(genctx);
sk_OPENSSL_STRING_free(pkeyopts);
sk_OPENSSL_STRING_free(sigopts);
lh_OPENSSL_STRING_doall(addexts, exts_cleanup);
lh_OPENSSL_STRING_free(addexts);
#ifndef OPENSSL_NO_ENGINE
ENGINE_free(gen_eng);
#endif
+20 -6
View File
@@ -192,8 +192,11 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity,
const SSL_CIPHER *cipher = NULL;
if (strlen(psk_identity) != identity_len
|| memcmp(psk_identity, identity, identity_len) != 0)
return 0;
|| memcmp(psk_identity, identity, identity_len) != 0) {
BIO_printf(bio_s_out,
"PSK warning: client identity not what we expected"
" (got '%s' expected '%s')\n", identity, psk_identity);
}
if (psksess != NULL) {
SSL_SESSION_up_ref(psksess);
@@ -748,8 +751,8 @@ typedef enum OPTION_choice {
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS,
OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY,
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY,
OPT_R_ENUM,
OPT_S_ENUM,
OPT_V_ENUM,
@@ -955,7 +958,9 @@ const OPTIONS s_server_options[] = {
#endif
{"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
{"max_early_data", OPT_MAX_EARLY, 'n',
"The maximum number of bytes of early data"},
"The maximum number of bytes of early data as advertised in tickets"},
{"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n',
"The maximum number of bytes of early data (hard limit)"},
{"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"},
{"num_tickets", OPT_S_NUM_TICKETS, 'n',
"The number of TLSv1.3 session tickets that a server will automatically issue" },
@@ -1041,7 +1046,7 @@ int s_server_main(int argc, char *argv[])
unsigned int split_send_fragment = 0, max_pipelines = 0;
const char *s_serverinfo_file = NULL;
const char *keylog_file = NULL;
int max_early_data = -1;
int max_early_data = -1, recv_max_early_data = -1;
char *psksessf = NULL;
/* Init of few remaining global variables */
@@ -1570,6 +1575,13 @@ int s_server_main(int argc, char *argv[])
goto end;
}
break;
case OPT_RECV_MAX_EARLY:
recv_max_early_data = atoi(opt_arg());
if (recv_max_early_data < 0) {
BIO_printf(bio_err, "Invalid value for recv_max_early_data\n");
goto end;
}
break;
case OPT_EARLY_DATA:
early_data = 1;
if (max_early_data == -1)
@@ -2110,6 +2122,8 @@ int s_server_main(int argc, char *argv[])
if (max_early_data >= 0)
SSL_CTX_set_max_early_data(ctx, max_early_data);
if (recv_max_early_data >= 0)
SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data);
if (rev)
server_cb = rev_body;
+46 -8
View File
@@ -196,14 +196,23 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
}
# if !defined(OPENSSL_SMALL_FOOTPRINT)
# if defined(POLY1305_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64))
# define XOR128_HELPERS
void *xor128_encrypt_n_pad(void *out, const void *inp, void *otp, size_t len);
void *xor128_decrypt_n_pad(void *out, const void *inp, void *otp, size_t len);
static const unsigned char zero[4 * CHACHA_BLK_SIZE] = { 0 };
# else
static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 };
# endif
static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
size_t i, tail, tohash_len, plen = actx->tls_payload_length;
unsigned char *buf, *tohash, *ctr, storage[2 * CHACHA_BLK_SIZE + 32];
size_t tail, tohash_len, buf_len, plen = actx->tls_payload_length;
unsigned char *buf, *tohash, *ctr, storage[sizeof(zero) + 32];
if (len != plen + POLY1305_BLOCK_SIZE)
return -1;
@@ -212,9 +221,11 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
ctr = buf + CHACHA_BLK_SIZE;
tohash = buf + CHACHA_BLK_SIZE - POLY1305_BLOCK_SIZE;
if (plen <= CHACHA_BLK_SIZE) {
# ifdef XOR128_HELPERS
if (plen <= 3 * CHACHA_BLK_SIZE) {
actx->key.counter[0] = 0;
ChaCha20_ctr32(buf, zero, 2 * CHACHA_BLK_SIZE, actx->key.key.d,
buf_len = (plen + 2 * CHACHA_BLK_SIZE - 1) & (0 - CHACHA_BLK_SIZE);
ChaCha20_ctr32(buf, zero, buf_len, actx->key.key.d,
actx->key.counter);
Poly1305_Init(POLY1305_ctx(actx), buf);
actx->key.partial_len = 0;
@@ -223,6 +234,31 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
actx->len.text = plen;
if (plen) {
if (ctx->encrypt)
ctr = xor128_encrypt_n_pad(out, in, ctr, plen);
else
ctr = xor128_decrypt_n_pad(out, in, ctr, plen);
in += plen;
out += plen;
tohash_len = (size_t)(ctr - tohash);
}
}
# else
if (plen <= CHACHA_BLK_SIZE) {
size_t i;
actx->key.counter[0] = 0;
ChaCha20_ctr32(buf, zero, (buf_len = 2 * CHACHA_BLK_SIZE),
actx->key.key.d, actx->key.counter);
Poly1305_Init(POLY1305_ctx(actx), buf);
actx->key.partial_len = 0;
memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE);
tohash_len = POLY1305_BLOCK_SIZE;
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
actx->len.text = plen;
if (ctx->encrypt) {
for (i = 0; i < plen; i++) {
out[i] = ctr[i] ^= in[i];
@@ -242,10 +278,12 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
memset(ctr + i, 0, tail);
ctr += i + tail;
tohash_len += i + tail;
} else {
}
# endif
else {
actx->key.counter[0] = 0;
ChaCha20_ctr32(buf, zero, CHACHA_BLK_SIZE, actx->key.key.d,
actx->key.counter);
ChaCha20_ctr32(buf, zero, (buf_len = CHACHA_BLK_SIZE),
actx->key.key.d, actx->key.counter);
Poly1305_Init(POLY1305_ctx(actx), buf);
actx->key.counter[0] = 1;
actx->key.partial_len = 0;
@@ -300,7 +338,7 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
}
Poly1305_Update(POLY1305_ctx(actx), tohash, tohash_len);
OPENSSL_cleanse(buf, 2 * CHACHA_BLK_SIZE);
OPENSSL_cleanse(buf, buf_len);
Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
: tohash);
+104
View File
@@ -3753,6 +3753,110 @@ poly1305_emit_base2_44:
.size poly1305_emit_base2_44,.-poly1305_emit_base2_44
___
} } }
{ # chacha20-poly1305 helpers
my ($out,$inp,$otp,$len)=$win64 ? ("%rcx","%rdx","%r8", "%r9") : # Win64 order
("%rdi","%rsi","%rdx","%rcx"); # Unix order
$code.=<<___;
.globl xor128_encrypt_n_pad
.type xor128_encrypt_n_pad,\@abi-omnipotent
.align 16
xor128_encrypt_n_pad:
sub $otp,$inp
sub $otp,$out
mov $len,%r10 # put len aside
shr \$4,$len # len / 16
jz .Ltail_enc
nop
.Loop_enc_xmm:
movdqu ($inp,$otp),%xmm0
pxor ($otp),%xmm0
movdqu %xmm0,($out,$otp)
movdqa %xmm0,($otp)
lea 16($otp),$otp
dec $len
jnz .Loop_enc_xmm
and \$15,%r10 # len % 16
jz .Ldone_enc
.Ltail_enc:
mov \$16,$len
sub %r10,$len
xor %eax,%eax
.Loop_enc_byte:
mov ($inp,$otp),%al
xor ($otp),%al
mov %al,($out,$otp)
mov %al,($otp)
lea 1($otp),$otp
dec %r10
jnz .Loop_enc_byte
xor %eax,%eax
.Loop_enc_pad:
mov %al,($otp)
lea 1($otp),$otp
dec $len
jnz .Loop_enc_pad
.Ldone_enc:
mov $otp,%rax
ret
.size xor128_encrypt_n_pad,.-xor128_encrypt_n_pad
.globl xor128_decrypt_n_pad
.type xor128_decrypt_n_pad,\@abi-omnipotent
.align 16
xor128_decrypt_n_pad:
sub $otp,$inp
sub $otp,$out
mov $len,%r10 # put len aside
shr \$4,$len # len / 16
jz .Ltail_dec
nop
.Loop_dec_xmm:
movdqu ($inp,$otp),%xmm0
movdqa ($otp),%xmm1
pxor %xmm0,%xmm1
movdqu %xmm1,($out,$otp)
movdqa %xmm0,($otp)
lea 16($otp),$otp
dec $len
jnz .Loop_dec_xmm
pxor %xmm1,%xmm1
and \$15,%r10 # len % 16
jz .Ldone_dec
.Ltail_dec:
mov \$16,$len
sub %r10,$len
xor %eax,%eax
xor %r11,%r11
.Loop_dec_byte:
mov ($inp,$otp),%r11b
mov ($otp),%al
xor %r11b,%al
mov %al,($out,$otp)
mov %r11b,($otp)
lea 1($otp),$otp
dec %r10
jnz .Loop_dec_byte
xor %eax,%eax
.Loop_dec_pad:
mov %al,($otp)
lea 1($otp),$otp
dec $len
jnz .Loop_dec_pad
.Ldone_dec:
mov $otp,%rax
ret
.size xor128_decrypt_n_pad,.-xor128_decrypt_n_pad
___
}
$code.=<<___;
.align 64
.Lconst:
+12 -10
View File
@@ -48,7 +48,8 @@ static size_t ec_field_size(const EC_GROUP *group)
if (p == NULL || a == NULL || b == NULL)
goto done;
EC_GROUP_get_curve_GFp(group, p, a, b, NULL);
if (!EC_GROUP_get_curve_GFp(group, p, a, b, NULL))
goto done;
field_size = (BN_num_bits(p) + 7) / 8;
done:
@@ -121,19 +122,20 @@ int sm2_encrypt(const EC_KEY *key,
uint8_t *msg_mask = NULL;
uint8_t *x2y2 = NULL;
uint8_t *C3 = NULL;
const size_t field_size = ec_field_size(group);
const size_t C3_size = EVP_MD_size(digest);
size_t field_size;
const int C3_size = EVP_MD_size(digest);
/* NULL these before any "goto done" */
ctext_struct.C2 = NULL;
ctext_struct.C3 = NULL;
if (hash == NULL
|| group == NULL
|| order == NULL
|| P == NULL
|| field_size == 0
|| C3_size == 0) {
if (hash == NULL || C3_size <= 0) {
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
goto done;
}
field_size = ec_field_size(group);
if (field_size == 0) {
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
goto done;
}
@@ -273,7 +275,7 @@ int sm2_decrypt(const EC_KEY *key,
int msg_len = 0;
EVP_MD_CTX *hash = NULL;
if (field_size == 0 || hash_size == 0)
if (field_size == 0 || hash_size <= 0)
goto done;
memset(ptext_buf, 0xFF, *ptext_len);
+7 -6
View File
@@ -25,19 +25,20 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
{
EVP_MD_CTX *hash = EVP_MD_CTX_new();
const int md_size = EVP_MD_size(digest);
uint8_t *za = OPENSSL_zalloc(md_size);
uint8_t *za = NULL;
BIGNUM *e = NULL;
if (hash == NULL || za == NULL) {
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
goto done;
}
if (md_size < 0) {
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST);
goto done;
}
za = OPENSSL_zalloc(md_size);
if (hash == NULL || za == NULL) {
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
goto done;
}
if (!sm2_compute_userid_digest(za, digest, user_id, key)) {
/* SM2err already called */
goto done;
-2
View File
@@ -59,8 +59,6 @@ int sm2_compute_userid_digest(uint8_t *out,
goto done;
}
memset(out, 0, EVP_MD_size(digest));
if (!EVP_DigestInit(hash, digest)) {
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
goto done;
+30 -3
View File
@@ -6,6 +6,10 @@ SSL_set_max_early_data,
SSL_CTX_set_max_early_data,
SSL_get_max_early_data,
SSL_CTX_get_max_early_data,
SSL_set_recv_max_early_data,
SSL_CTX_set_recv_max_early_data,
SSL_get_recv_max_early_data,
SSL_CTX_get_recv_max_early_data,
SSL_SESSION_get_max_early_data,
SSL_SESSION_set_max_early_data,
SSL_write_early_data,
@@ -24,6 +28,12 @@ SSL_set_allow_early_data_cb
uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx);
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data);
uint32_t SSL_get_max_early_data(const SSL *s);
int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data);
uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx);
int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data);
uint32_t SSL_get_recv_max_early_data(const SSL *s);
uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s);
int SSL_SESSION_set_max_early_data(SSL_SESSION *s, uint32_t max_early_data);
@@ -195,9 +205,26 @@ since there is no practical benefit from using only one of them. If the maximum
early data setting for a server is non-zero then replay protection is
automatically enabled (see L</REPLAY PROTECTION> below).
In the event that the current maximum early data setting for the server is
different to that originally specified in a session that a client is resuming
with then the lower of the two values will apply.
If the server rejects the early data sent by a client then it will skip over
the data that is sent. The maximum amount of received early data that is skipped
is controlled by the recv_max_early_data setting. If a client sends more than
this then the connection will abort. This value can be set by calling
SSL_CTX_set_recv_max_early_data() or SSL_set_recv_max_early_data(). The current
value for this setting can be obtained by calling
SSL_CTX_get_recv_max_early_data() or SSL_get_recv_max_early_data(). The default
value for this setting is 16,384 bytes.
The recv_max_early_data value also has an impact on early data that is accepted.
The amount of data that is accepted will always be the lower of the
max_early_data for the session and the recv_max_early_data setting for the
server. If a client sends more data than this then the connection will abort.
The configured value for max_early_data on a server may change over time as
required. However clients may have tickets containing the previously configured
max_early_data value. The recv_max_early_data should always be equal to or
higher than any recently configured max_early_data value in order to avoid
aborted connections. The recv_max_early_data should never be set to less than
the current configured max_early_data value.
Some server applications may wish to have more control over whether early data
is accepted or not, for example to mitigate replay risks (see L</REPLAY PROTECTION>
+4
View File
@@ -919,6 +919,10 @@ int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data);
uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx);
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data);
uint32_t SSL_get_max_early_data(const SSL *s);
int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data);
uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx);
int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data);
uint32_t SSL_get_recv_max_early_data(const SSL *s);
#ifdef __cplusplus
}
+8 -3
View File
@@ -103,7 +103,7 @@ static int ssl3_record_app_data_waiting(SSL *s)
int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send)
{
uint32_t max_early_data = s->max_early_data;
uint32_t max_early_data;
SSL_SESSION *sess = s->session;
/*
@@ -120,9 +120,14 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send)
}
sess = s->psksession;
}
if (!s->server
|| (s->hit && sess->ext.max_early_data < s->max_early_data))
if (!s->server)
max_early_data = sess->ext.max_early_data;
else if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED)
max_early_data = s->recv_max_early_data;
else
max_early_data = s->recv_max_early_data < sess->ext.max_early_data
? s->recv_max_early_data : sess->ext.max_early_data;
if (max_early_data == 0) {
SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE,
+35
View File
@@ -700,6 +700,7 @@ SSL *SSL_new(SSL_CTX *ctx)
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
s->max_early_data = ctx->max_early_data;
s->recv_max_early_data = ctx->recv_max_early_data;
s->num_tickets = ctx->num_tickets;
/* Shallow copy of the ciphersuites stack */
@@ -3105,6 +3106,16 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
*/
ret->max_early_data = 0;
/*
* Default recv_max_early_data is a fully loaded single record. Could be
* split across multiple records in practice. We set this differently to
* max_early_data so that, in the default case, we do not advertise any
* support for early_data, but if a client were to send us some (e.g.
* because of an old, stale ticket) then we will tolerate it and skip over
* it.
*/
ret->recv_max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
/* By default we send two session tickets automatically in TLSv1.3 */
ret->num_tickets = 2;
@@ -5444,6 +5455,30 @@ uint32_t SSL_get_max_early_data(const SSL *s)
return s->max_early_data;
}
int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data)
{
ctx->recv_max_early_data = recv_max_early_data;
return 1;
}
uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx)
{
return ctx->recv_max_early_data;
}
int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data)
{
s->recv_max_early_data = recv_max_early_data;
return 1;
}
uint32_t SSL_get_recv_max_early_data(const SSL *s)
{
return s->recv_max_early_data;
}
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
{
/* Return any active Max Fragment Len extension */
+20 -2
View File
@@ -1069,9 +1069,18 @@ struct ssl_ctx_st {
*/
SSL_CTX_keylog_cb_func keylog_callback;
/* The maximum number of bytes that can be sent as early data */
/*
* The maximum number of bytes advertised in session tickets that can be
* sent as early data.
*/
uint32_t max_early_data;
/*
* The maximum number of bytes of early data that a server will tolerate
* (which should be at least as much as max_early_data).
*/
uint32_t recv_max_early_data;
/* TLS1.3 padding callback */
size_t (*record_padding_cb)(SSL *s, int type, size_t len, void *arg);
void *record_padding_arg;
@@ -1443,8 +1452,17 @@ struct ssl_st {
ASYNC_WAIT_CTX *waitctx;
size_t asyncrw;
/* The maximum number of plaintext bytes that can be sent as early data */
/*
* The maximum number of bytes advertised in session tickets that can be
* sent as early data.
*/
uint32_t max_early_data;
/*
* The maximum number of bytes of early data that a server will tolerate
* (which should be at least as much as max_early_data).
*/
uint32_t recv_max_early_data;
/*
* The number of bytes of early data received so far. If we accepted early
* data then this is a count of the plaintext bytes. If we rejected it then
+12 -1
View File
@@ -15,13 +15,24 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
setup("test_req");
plan tests => 4;
plan tests => 8;
require_ok(srctop_file('test','recipes','tconversion.pl'));
open RND, ">>", ".rnd";
print RND "string to make the random number generator think it has randomness";
close RND;
# Check for duplicate -addext parameters
my $val = "subjectAltName=DNS:example.com";
my $val2 = " " . $val;
my $val3 = $val;
$val3 =~ s/=/ =/;
ok(!run(app(["openssl", "req", "-new", "-addext", $val, "-addext", $val])));
ok(!run(app(["openssl", "req", "-new", "-addext", $val, "-addext", $val2])));
ok(!run(app(["openssl", "req", "-new", "-addext", $val, "-addext", $val3])));
ok(!run(app(["openssl", "req", "-new", "-addext", $val2, "-addext", $val3])));
subtest "generating certificate requests" => sub {
my @req_new;
if (disabled("rsa")) {
+37 -5
View File
@@ -2314,8 +2314,11 @@ static int test_early_data_replay(int idx)
/*
* Helper function to test that a server attempting to read early data can
* handle a connection from a client where the early data should be skipped.
* testtype: 0 == No HRR
* testtype: 1 == HRR
* testtype: 2 == recv_max_early_data set to 0
*/
static int early_data_skip_helper(int hrr, int idx)
static int early_data_skip_helper(int testtype, int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
@@ -2328,7 +2331,7 @@ static int early_data_skip_helper(int hrr, int idx)
&serverssl, &sess, idx)))
goto end;
if (hrr) {
if (testtype == 1) {
/* Force an HRR to occur */
if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
goto end;
@@ -2348,13 +2351,17 @@ static int early_data_skip_helper(int hrr, int idx)
goto end;
}
if (testtype == 2
&& !TEST_true(SSL_set_recv_max_early_data(serverssl, 0)))
goto end;
/* Write some early data */
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1)))
goto end;
/* Server should reject the early data and skip over it */
/* Server should reject the early data */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_FINISH)
@@ -2363,7 +2370,7 @@ static int early_data_skip_helper(int hrr, int idx)
SSL_EARLY_DATA_REJECTED))
goto end;
if (hrr) {
if (testtype == 1) {
/*
* Finish off the handshake. We perform the same writes and reads as
* further down but we expect them to fail due to the incomplete
@@ -2373,9 +2380,24 @@ static int early_data_skip_helper(int hrr, int idx)
|| !TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
&readbytes)))
goto end;
} else if (testtype == 2) {
/*
* This client has sent more early_data than we are willing to skip so
* the connection should abort.
*/
if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
|| !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_SSL))
goto end;
/* Connection has failed - nothing more to do */
testresult = 1;
goto end;
}
/* Should be able to send normal data despite rejection of early data */
/*
* Should be able to send normal data despite rejection of early data. The
* early_data should be skipped.
*/
if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
|| !TEST_size_t_eq(written, strlen(MSG2))
|| !TEST_int_eq(SSL_get_early_data_status(clientssl),
@@ -2416,6 +2438,15 @@ static int test_early_data_skip_hrr(int idx)
return early_data_skip_helper(1, idx);
}
/*
* Test that a server attempting to read early data will abort if it tries to
* skip over too much.
*/
static int test_early_data_skip_abort(int idx)
{
return early_data_skip_helper(2, idx);
}
/*
* Test that a server attempting to read early data can handle a connection
* from a client that doesn't send any.
@@ -5267,6 +5298,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_early_data_replay, 2);
ADD_ALL_TESTS(test_early_data_skip, 3);
ADD_ALL_TESTS(test_early_data_skip_hrr, 3);
ADD_ALL_TESTS(test_early_data_skip_abort, 3);
ADD_ALL_TESTS(test_early_data_not_sent, 3);
ADD_ALL_TESTS(test_early_data_psk, 8);
ADD_ALL_TESTS(test_early_data_not_expected, 3);
+4
View File
@@ -492,3 +492,7 @@ SSL_get_num_tickets 492 1_1_1 EXIST::FUNCTION:
SSL_CTX_set_num_tickets 493 1_1_1 EXIST::FUNCTION:
SSL_CTX_set_allow_early_data_cb 494 1_1_1 EXIST::FUNCTION:
SSL_set_allow_early_data_cb 495 1_1_1 EXIST::FUNCTION:
SSL_set_recv_max_early_data 496 1_1_1 EXIST::FUNCTION:
SSL_get_recv_max_early_data 497 1_1_1 EXIST::FUNCTION:
SSL_CTX_get_recv_max_early_data 498 1_1_1 EXIST::FUNCTION:
SSL_CTX_set_recv_max_early_data 499 1_1_1 EXIST::FUNCTION: