Update pre9
This commit is contained in:
+77
-3
@@ -11,6 +11,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "progs.h"
|
#include "progs.h"
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
@@ -23,6 +24,8 @@
|
|||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/lhash.h>
|
||||||
#ifndef OPENSSL_NO_RSA
|
#ifndef OPENSSL_NO_RSA
|
||||||
# include <openssl/rsa.h>
|
# include <openssl/rsa.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -147,6 +150,68 @@ const OPTIONS req_options[] = {
|
|||||||
{NULL}
|
{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)
|
int req_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
ASN1_INTEGER *serial = NULL;
|
ASN1_INTEGER *serial = NULL;
|
||||||
@@ -155,6 +220,7 @@ int req_main(int argc, char **argv)
|
|||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
EVP_PKEY_CTX *genctx = NULL;
|
EVP_PKEY_CTX *genctx = NULL;
|
||||||
STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
|
STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
|
||||||
|
LHASH_OF(OPENSSL_STRING) *addexts = NULL;
|
||||||
X509 *x509ss = NULL;
|
X509 *x509ss = NULL;
|
||||||
X509_REQ *req = NULL;
|
X509_REQ *req = NULL;
|
||||||
const EVP_CIPHER *cipher = NULL;
|
const EVP_CIPHER *cipher = NULL;
|
||||||
@@ -324,11 +390,17 @@ int req_main(int argc, char **argv)
|
|||||||
multirdn = 1;
|
multirdn = 1;
|
||||||
break;
|
break;
|
||||||
case OPT_ADDEXT:
|
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());
|
addext_bio = BIO_new(BIO_s_mem());
|
||||||
|
if (addexts == NULL || addext_bio == NULL)
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
if (addext_bio == NULL
|
i = duplicated(addexts, p);
|
||||||
|| BIO_printf(addext_bio, "%s\n", opt_arg()) < 0)
|
if (i == 1)
|
||||||
|
goto opthelp;
|
||||||
|
if (i < 0 || BIO_printf(addext_bio, "%s\n", opt_arg()) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
break;
|
break;
|
||||||
case OPT_EXTENSIONS:
|
case OPT_EXTENSIONS:
|
||||||
@@ -885,6 +957,8 @@ int req_main(int argc, char **argv)
|
|||||||
EVP_PKEY_CTX_free(genctx);
|
EVP_PKEY_CTX_free(genctx);
|
||||||
sk_OPENSSL_STRING_free(pkeyopts);
|
sk_OPENSSL_STRING_free(pkeyopts);
|
||||||
sk_OPENSSL_STRING_free(sigopts);
|
sk_OPENSSL_STRING_free(sigopts);
|
||||||
|
lh_OPENSSL_STRING_doall(addexts, exts_cleanup);
|
||||||
|
lh_OPENSSL_STRING_free(addexts);
|
||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
ENGINE_free(gen_eng);
|
ENGINE_free(gen_eng);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+20
-6
@@ -192,8 +192,11 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity,
|
|||||||
const SSL_CIPHER *cipher = NULL;
|
const SSL_CIPHER *cipher = NULL;
|
||||||
|
|
||||||
if (strlen(psk_identity) != identity_len
|
if (strlen(psk_identity) != identity_len
|
||||||
|| memcmp(psk_identity, identity, identity_len) != 0)
|
|| memcmp(psk_identity, identity, identity_len) != 0) {
|
||||||
return 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) {
|
if (psksess != NULL) {
|
||||||
SSL_SESSION_up_ref(psksess);
|
SSL_SESSION_up_ref(psksess);
|
||||||
@@ -748,8 +751,8 @@ typedef enum OPTION_choice {
|
|||||||
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
|
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
|
||||||
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
||||||
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
||||||
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS,
|
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
|
||||||
OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY,
|
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY,
|
||||||
OPT_R_ENUM,
|
OPT_R_ENUM,
|
||||||
OPT_S_ENUM,
|
OPT_S_ENUM,
|
||||||
OPT_V_ENUM,
|
OPT_V_ENUM,
|
||||||
@@ -955,7 +958,9 @@ const OPTIONS s_server_options[] = {
|
|||||||
#endif
|
#endif
|
||||||
{"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
|
{"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
|
||||||
{"max_early_data", OPT_MAX_EARLY, 'n',
|
{"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"},
|
{"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"},
|
||||||
{"num_tickets", OPT_S_NUM_TICKETS, 'n',
|
{"num_tickets", OPT_S_NUM_TICKETS, 'n',
|
||||||
"The number of TLSv1.3 session tickets that a server will automatically issue" },
|
"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;
|
unsigned int split_send_fragment = 0, max_pipelines = 0;
|
||||||
const char *s_serverinfo_file = NULL;
|
const char *s_serverinfo_file = NULL;
|
||||||
const char *keylog_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;
|
char *psksessf = NULL;
|
||||||
|
|
||||||
/* Init of few remaining global variables */
|
/* Init of few remaining global variables */
|
||||||
@@ -1570,6 +1575,13 @@ int s_server_main(int argc, char *argv[])
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case OPT_EARLY_DATA:
|
||||||
early_data = 1;
|
early_data = 1;
|
||||||
if (max_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)
|
if (max_early_data >= 0)
|
||||||
SSL_CTX_set_max_early_data(ctx, max_early_data);
|
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)
|
if (rev)
|
||||||
server_cb = rev_body;
|
server_cb = rev_body;
|
||||||
|
|||||||
@@ -196,14 +196,23 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
# if !defined(OPENSSL_SMALL_FOOTPRINT)
|
# 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 };
|
static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 };
|
||||||
|
# endif
|
||||||
|
|
||||||
static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
const unsigned char *in, size_t len)
|
const unsigned char *in, size_t len)
|
||||||
{
|
{
|
||||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||||
size_t i, tail, tohash_len, plen = actx->tls_payload_length;
|
size_t tail, tohash_len, buf_len, plen = actx->tls_payload_length;
|
||||||
unsigned char *buf, *tohash, *ctr, storage[2 * CHACHA_BLK_SIZE + 32];
|
unsigned char *buf, *tohash, *ctr, storage[sizeof(zero) + 32];
|
||||||
|
|
||||||
if (len != plen + POLY1305_BLOCK_SIZE)
|
if (len != plen + POLY1305_BLOCK_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -212,9 +221,11 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
|||||||
ctr = buf + CHACHA_BLK_SIZE;
|
ctr = buf + CHACHA_BLK_SIZE;
|
||||||
tohash = buf + CHACHA_BLK_SIZE - POLY1305_BLOCK_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;
|
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);
|
actx->key.counter);
|
||||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||||
actx->key.partial_len = 0;
|
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.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||||
actx->len.text = plen;
|
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) {
|
if (ctx->encrypt) {
|
||||||
for (i = 0; i < plen; i++) {
|
for (i = 0; i < plen; i++) {
|
||||||
out[i] = ctr[i] ^= in[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);
|
memset(ctr + i, 0, tail);
|
||||||
ctr += i + tail;
|
ctr += i + tail;
|
||||||
tohash_len += i + tail;
|
tohash_len += i + tail;
|
||||||
} else {
|
}
|
||||||
|
# endif
|
||||||
|
else {
|
||||||
actx->key.counter[0] = 0;
|
actx->key.counter[0] = 0;
|
||||||
ChaCha20_ctr32(buf, zero, CHACHA_BLK_SIZE, actx->key.key.d,
|
ChaCha20_ctr32(buf, zero, (buf_len = CHACHA_BLK_SIZE),
|
||||||
actx->key.counter);
|
actx->key.key.d, actx->key.counter);
|
||||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||||
actx->key.counter[0] = 1;
|
actx->key.counter[0] = 1;
|
||||||
actx->key.partial_len = 0;
|
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);
|
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
|
Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
|
||||||
: tohash);
|
: tohash);
|
||||||
|
|
||||||
|
|||||||
@@ -3753,6 +3753,110 @@ poly1305_emit_base2_44:
|
|||||||
.size poly1305_emit_base2_44,.-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.=<<___;
|
$code.=<<___;
|
||||||
.align 64
|
.align 64
|
||||||
.Lconst:
|
.Lconst:
|
||||||
|
|||||||
+12
-10
@@ -48,7 +48,8 @@ static size_t ec_field_size(const EC_GROUP *group)
|
|||||||
if (p == NULL || a == NULL || b == NULL)
|
if (p == NULL || a == NULL || b == NULL)
|
||||||
goto done;
|
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;
|
field_size = (BN_num_bits(p) + 7) / 8;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@@ -121,19 +122,20 @@ int sm2_encrypt(const EC_KEY *key,
|
|||||||
uint8_t *msg_mask = NULL;
|
uint8_t *msg_mask = NULL;
|
||||||
uint8_t *x2y2 = NULL;
|
uint8_t *x2y2 = NULL;
|
||||||
uint8_t *C3 = NULL;
|
uint8_t *C3 = NULL;
|
||||||
const size_t field_size = ec_field_size(group);
|
size_t field_size;
|
||||||
const size_t C3_size = EVP_MD_size(digest);
|
const int C3_size = EVP_MD_size(digest);
|
||||||
|
|
||||||
/* NULL these before any "goto done" */
|
/* NULL these before any "goto done" */
|
||||||
ctext_struct.C2 = NULL;
|
ctext_struct.C2 = NULL;
|
||||||
ctext_struct.C3 = NULL;
|
ctext_struct.C3 = NULL;
|
||||||
|
|
||||||
if (hash == NULL
|
if (hash == NULL || C3_size <= 0) {
|
||||||
|| group == NULL
|
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
|
||||||
|| order == NULL
|
goto done;
|
||||||
|| P == NULL
|
}
|
||||||
|| field_size == 0
|
|
||||||
|| C3_size == 0) {
|
field_size = ec_field_size(group);
|
||||||
|
if (field_size == 0) {
|
||||||
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
|
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -273,7 +275,7 @@ int sm2_decrypt(const EC_KEY *key,
|
|||||||
int msg_len = 0;
|
int msg_len = 0;
|
||||||
EVP_MD_CTX *hash = NULL;
|
EVP_MD_CTX *hash = NULL;
|
||||||
|
|
||||||
if (field_size == 0 || hash_size == 0)
|
if (field_size == 0 || hash_size <= 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
memset(ptext_buf, 0xFF, *ptext_len);
|
memset(ptext_buf, 0xFF, *ptext_len);
|
||||||
|
|||||||
@@ -25,19 +25,20 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
|
|||||||
{
|
{
|
||||||
EVP_MD_CTX *hash = EVP_MD_CTX_new();
|
EVP_MD_CTX *hash = EVP_MD_CTX_new();
|
||||||
const int md_size = EVP_MD_size(digest);
|
const int md_size = EVP_MD_size(digest);
|
||||||
uint8_t *za = OPENSSL_zalloc(md_size);
|
uint8_t *za = NULL;
|
||||||
BIGNUM *e = 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) {
|
if (md_size < 0) {
|
||||||
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST);
|
SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST);
|
||||||
goto done;
|
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)) {
|
if (!sm2_compute_userid_digest(za, digest, user_id, key)) {
|
||||||
/* SM2err already called */
|
/* SM2err already called */
|
||||||
goto done;
|
goto done;
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ int sm2_compute_userid_digest(uint8_t *out,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(out, 0, EVP_MD_size(digest));
|
|
||||||
|
|
||||||
if (!EVP_DigestInit(hash, digest)) {
|
if (!EVP_DigestInit(hash, digest)) {
|
||||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
|
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
|
||||||
goto done;
|
goto done;
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ SSL_set_max_early_data,
|
|||||||
SSL_CTX_set_max_early_data,
|
SSL_CTX_set_max_early_data,
|
||||||
SSL_get_max_early_data,
|
SSL_get_max_early_data,
|
||||||
SSL_CTX_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_get_max_early_data,
|
||||||
SSL_SESSION_set_max_early_data,
|
SSL_SESSION_set_max_early_data,
|
||||||
SSL_write_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);
|
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);
|
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data);
|
||||||
uint32_t SSL_get_max_early_data(const SSL *s);
|
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);
|
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);
|
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
|
early data setting for a server is non-zero then replay protection is
|
||||||
automatically enabled (see L</REPLAY PROTECTION> below).
|
automatically enabled (see L</REPLAY PROTECTION> below).
|
||||||
|
|
||||||
In the event that the current maximum early data setting for the server is
|
If the server rejects the early data sent by a client then it will skip over
|
||||||
different to that originally specified in a session that a client is resuming
|
the data that is sent. The maximum amount of received early data that is skipped
|
||||||
with then the lower of the two values will apply.
|
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
|
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>
|
is accepted or not, for example to mitigate replay risks (see L</REPLAY PROTECTION>
|
||||||
|
|||||||
@@ -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);
|
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);
|
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data);
|
||||||
uint32_t SSL_get_max_early_data(const SSL *s);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
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;
|
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;
|
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;
|
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) {
|
if (max_early_data == 0) {
|
||||||
SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE,
|
SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE,
|
||||||
|
|||||||
@@ -700,6 +700,7 @@ SSL *SSL_new(SSL_CTX *ctx)
|
|||||||
s->mode = ctx->mode;
|
s->mode = ctx->mode;
|
||||||
s->max_cert_list = ctx->max_cert_list;
|
s->max_cert_list = ctx->max_cert_list;
|
||||||
s->max_early_data = ctx->max_early_data;
|
s->max_early_data = ctx->max_early_data;
|
||||||
|
s->recv_max_early_data = ctx->recv_max_early_data;
|
||||||
s->num_tickets = ctx->num_tickets;
|
s->num_tickets = ctx->num_tickets;
|
||||||
|
|
||||||
/* Shallow copy of the ciphersuites stack */
|
/* Shallow copy of the ciphersuites stack */
|
||||||
@@ -3105,6 +3106,16 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
|||||||
*/
|
*/
|
||||||
ret->max_early_data = 0;
|
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 */
|
/* By default we send two session tickets automatically in TLSv1.3 */
|
||||||
ret->num_tickets = 2;
|
ret->num_tickets = 2;
|
||||||
|
|
||||||
@@ -5444,6 +5455,30 @@ uint32_t SSL_get_max_early_data(const SSL *s)
|
|||||||
return s->max_early_data;
|
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)
|
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
|
||||||
{
|
{
|
||||||
/* Return any active Max Fragment Len extension */
|
/* Return any active Max Fragment Len extension */
|
||||||
|
|||||||
+20
-2
@@ -1069,9 +1069,18 @@ struct ssl_ctx_st {
|
|||||||
*/
|
*/
|
||||||
SSL_CTX_keylog_cb_func keylog_callback;
|
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;
|
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 */
|
/* TLS1.3 padding callback */
|
||||||
size_t (*record_padding_cb)(SSL *s, int type, size_t len, void *arg);
|
size_t (*record_padding_cb)(SSL *s, int type, size_t len, void *arg);
|
||||||
void *record_padding_arg;
|
void *record_padding_arg;
|
||||||
@@ -1443,8 +1452,17 @@ struct ssl_st {
|
|||||||
ASYNC_WAIT_CTX *waitctx;
|
ASYNC_WAIT_CTX *waitctx;
|
||||||
size_t asyncrw;
|
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;
|
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
|
* 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
|
* data then this is a count of the plaintext bytes. If we rejected it then
|
||||||
|
|||||||
@@ -15,13 +15,24 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
|
|||||||
|
|
||||||
setup("test_req");
|
setup("test_req");
|
||||||
|
|
||||||
plan tests => 4;
|
plan tests => 8;
|
||||||
|
|
||||||
require_ok(srctop_file('test','recipes','tconversion.pl'));
|
require_ok(srctop_file('test','recipes','tconversion.pl'));
|
||||||
|
|
||||||
open RND, ">>", ".rnd";
|
open RND, ">>", ".rnd";
|
||||||
print RND "string to make the random number generator think it has randomness";
|
print RND "string to make the random number generator think it has randomness";
|
||||||
close RND;
|
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 {
|
subtest "generating certificate requests" => sub {
|
||||||
my @req_new;
|
my @req_new;
|
||||||
if (disabled("rsa")) {
|
if (disabled("rsa")) {
|
||||||
|
|||||||
+37
-5
@@ -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
|
* 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.
|
* 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_CTX *cctx = NULL, *sctx = NULL;
|
||||||
SSL *clientssl = NULL, *serverssl = NULL;
|
SSL *clientssl = NULL, *serverssl = NULL;
|
||||||
@@ -2328,7 +2331,7 @@ static int early_data_skip_helper(int hrr, int idx)
|
|||||||
&serverssl, &sess, idx)))
|
&serverssl, &sess, idx)))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (hrr) {
|
if (testtype == 1) {
|
||||||
/* Force an HRR to occur */
|
/* Force an HRR to occur */
|
||||||
if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
|
if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
|
||||||
goto end;
|
goto end;
|
||||||
@@ -2348,13 +2351,17 @@ static int early_data_skip_helper(int hrr, int idx)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testtype == 2
|
||||||
|
&& !TEST_true(SSL_set_recv_max_early_data(serverssl, 0)))
|
||||||
|
goto end;
|
||||||
|
|
||||||
/* Write some early data */
|
/* Write some early data */
|
||||||
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
|
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
|
||||||
&written))
|
&written))
|
||||||
|| !TEST_size_t_eq(written, strlen(MSG1)))
|
|| !TEST_size_t_eq(written, strlen(MSG1)))
|
||||||
goto end;
|
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),
|
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
|
||||||
&readbytes),
|
&readbytes),
|
||||||
SSL_READ_EARLY_DATA_FINISH)
|
SSL_READ_EARLY_DATA_FINISH)
|
||||||
@@ -2363,7 +2370,7 @@ static int early_data_skip_helper(int hrr, int idx)
|
|||||||
SSL_EARLY_DATA_REJECTED))
|
SSL_EARLY_DATA_REJECTED))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (hrr) {
|
if (testtype == 1) {
|
||||||
/*
|
/*
|
||||||
* Finish off the handshake. We perform the same writes and reads as
|
* Finish off the handshake. We perform the same writes and reads as
|
||||||
* further down but we expect them to fail due to the incomplete
|
* 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),
|
|| !TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
|
||||||
&readbytes)))
|
&readbytes)))
|
||||||
goto end;
|
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))
|
if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
|
||||||
|| !TEST_size_t_eq(written, strlen(MSG2))
|
|| !TEST_size_t_eq(written, strlen(MSG2))
|
||||||
|| !TEST_int_eq(SSL_get_early_data_status(clientssl),
|
|| !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);
|
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
|
* Test that a server attempting to read early data can handle a connection
|
||||||
* from a client that doesn't send any.
|
* 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_replay, 2);
|
||||||
ADD_ALL_TESTS(test_early_data_skip, 3);
|
ADD_ALL_TESTS(test_early_data_skip, 3);
|
||||||
ADD_ALL_TESTS(test_early_data_skip_hrr, 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_not_sent, 3);
|
||||||
ADD_ALL_TESTS(test_early_data_psk, 8);
|
ADD_ALL_TESTS(test_early_data_psk, 8);
|
||||||
ADD_ALL_TESTS(test_early_data_not_expected, 3);
|
ADD_ALL_TESTS(test_early_data_not_expected, 3);
|
||||||
|
|||||||
@@ -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_num_tickets 493 1_1_1 EXIST::FUNCTION:
|
||||||
SSL_CTX_set_allow_early_data_cb 494 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_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:
|
||||||
Reference in New Issue
Block a user