Added API for external hashing of ServerKeyExchange, and signature algorithm identifiers in the 0x080* format (preparatory steps for EdDSA support).
This commit is contained in:
parent
44c79c1add
commit
ef318ef83a
11 changed files with 933 additions and 729 deletions
|
|
@ -169,6 +169,44 @@ do_static_ecdh(br_ssl_server_context *ctx, int prf_id)
|
|||
do_ecdh(ctx, prf_id, cpoint, cpoint_len);
|
||||
}
|
||||
|
||||
static size_t
|
||||
hash_data(br_ssl_server_context *ctx,
|
||||
void *dst, int hash_id, const void *src, size_t len)
|
||||
{
|
||||
const br_hash_class *hf;
|
||||
br_hash_compat_context hc;
|
||||
|
||||
if (hash_id == 0) {
|
||||
unsigned char tmp[36];
|
||||
|
||||
hf = br_multihash_getimpl(&ctx->eng.mhash, br_md5_ID);
|
||||
if (hf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
hf->init(&hc.vtable);
|
||||
hf->update(&hc.vtable, src, len);
|
||||
hf->out(&hc.vtable, tmp);
|
||||
hf = br_multihash_getimpl(&ctx->eng.mhash, br_sha1_ID);
|
||||
if (hf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
hf->init(&hc.vtable);
|
||||
hf->update(&hc.vtable, src, len);
|
||||
hf->out(&hc.vtable, tmp + 16);
|
||||
memcpy(dst, tmp, 36);
|
||||
return 36;
|
||||
} else {
|
||||
hf = br_multihash_getimpl(&ctx->eng.mhash, hash_id);
|
||||
if (hf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
hf->init(&hc.vtable);
|
||||
hf->update(&hc.vtable, src, len);
|
||||
hf->out(&hc.vtable, dst);
|
||||
return (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the ECDHE key exchange (part 1: generation of transient key, and
|
||||
* computing of the point to send to the client). Returned value is the
|
||||
|
|
@ -179,12 +217,10 @@ do_static_ecdh(br_ssl_server_context *ctx, int prf_id)
|
|||
static int
|
||||
do_ecdhe_part1(br_ssl_server_context *ctx, int curve)
|
||||
{
|
||||
int hash;
|
||||
unsigned algo_id;
|
||||
unsigned mask;
|
||||
const unsigned char *order;
|
||||
size_t olen, glen;
|
||||
br_multihash_context mhc;
|
||||
unsigned char head[4];
|
||||
size_t hv_len, sig_len;
|
||||
|
||||
if (!((ctx->eng.iec->supported_curves >> curve) & 1)) {
|
||||
|
|
@ -213,55 +249,33 @@ do_ecdhe_part1(br_ssl_server_context *ctx, int curve)
|
|||
/*
|
||||
* Compute our ECDH point.
|
||||
*/
|
||||
#if 0
|
||||
/* obsolete */
|
||||
generator = ctx->eng.iec->generator(curve, &glen);
|
||||
memcpy(ctx->eng.ecdhe_point, generator, glen);
|
||||
ctx->eng.ecdhe_point_len = glen;
|
||||
if (!ctx->eng.iec->mul(ctx->eng.ecdhe_point, glen,
|
||||
ctx->ecdhe_key, olen, curve))
|
||||
{
|
||||
return -BR_ERR_INVALID_ALGORITHM;
|
||||
}
|
||||
#endif
|
||||
glen = ctx->eng.iec->mulgen(ctx->eng.ecdhe_point,
|
||||
ctx->ecdhe_key, olen, curve);
|
||||
ctx->eng.ecdhe_point_len = glen;
|
||||
|
||||
/*
|
||||
* Compute the signature.
|
||||
* Assemble the message to be signed, and possibly hash it.
|
||||
*/
|
||||
br_multihash_zero(&mhc);
|
||||
br_multihash_copyimpl(&mhc, &ctx->eng.mhash);
|
||||
br_multihash_init(&mhc);
|
||||
br_multihash_update(&mhc,
|
||||
ctx->eng.client_random, sizeof ctx->eng.client_random);
|
||||
br_multihash_update(&mhc,
|
||||
ctx->eng.server_random, sizeof ctx->eng.server_random);
|
||||
head[0] = 3;
|
||||
head[1] = 0;
|
||||
head[2] = curve;
|
||||
head[3] = ctx->eng.ecdhe_point_len;
|
||||
br_multihash_update(&mhc, head, sizeof head);
|
||||
br_multihash_update(&mhc,
|
||||
memcpy(ctx->eng.pad, ctx->eng.client_random, 32);
|
||||
memcpy(ctx->eng.pad + 32, ctx->eng.server_random, 32);
|
||||
ctx->eng.pad[64 + 0] = 0x03;
|
||||
ctx->eng.pad[64 + 1] = 0x00;
|
||||
ctx->eng.pad[64 + 2] = curve;
|
||||
ctx->eng.pad[64 + 3] = ctx->eng.ecdhe_point_len;
|
||||
memcpy(ctx->eng.pad + 64 + 4,
|
||||
ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len);
|
||||
hash = ctx->sign_hash_id;
|
||||
if (hash) {
|
||||
hv_len = br_multihash_out(&mhc, hash, ctx->eng.pad);
|
||||
hv_len = 64 + 4 + ctx->eng.ecdhe_point_len;
|
||||
algo_id = ctx->sign_hash_id;
|
||||
if (algo_id >= (unsigned)0xFF00) {
|
||||
hv_len = hash_data(ctx, ctx->eng.pad, algo_id & 0xFF,
|
||||
ctx->eng.pad, hv_len);
|
||||
if (hv_len == 0) {
|
||||
return -BR_ERR_INVALID_ALGORITHM;
|
||||
}
|
||||
} else {
|
||||
if (!br_multihash_out(&mhc, br_md5_ID, ctx->eng.pad)
|
||||
|| !br_multihash_out(&mhc,
|
||||
br_sha1_ID, ctx->eng.pad + 16))
|
||||
{
|
||||
return -BR_ERR_INVALID_ALGORITHM;
|
||||
}
|
||||
hv_len = 36;
|
||||
}
|
||||
|
||||
sig_len = (*ctx->policy_vtable)->do_sign(ctx->policy_vtable,
|
||||
hash, hv_len, ctx->eng.pad, sizeof ctx->eng.pad);
|
||||
algo_id, ctx->eng.pad, hv_len, sizeof ctx->eng.pad);
|
||||
return sig_len ? (int)sig_len : -BR_ERR_INVALID_ALGORITHM;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +523,7 @@ cc: set-max-frag-len ( len -- ) {
|
|||
\ Open extension value.
|
||||
read16 open-elt
|
||||
|
||||
read-list-sign-algos addr-hashes set16
|
||||
read-list-sign-algos addr-hashes set32
|
||||
|
||||
\ Close extension value.
|
||||
close-elt ;
|
||||
|
|
@ -578,7 +592,7 @@ cc: call-policy-handler ( -- bool ) {
|
|||
x = (*CTX->policy_vtable)->choose(
|
||||
CTX->policy_vtable, CTX, &choices);
|
||||
ENG->session.cipher_suite = choices.cipher_suite;
|
||||
CTX->sign_hash_id = choices.hash_id;
|
||||
CTX->sign_hash_id = choices.algo_id;
|
||||
ENG->chain = choices.chain;
|
||||
ENG->chain_len = choices.chain_len;
|
||||
T0_PUSHi(-(x != 0));
|
||||
|
|
@ -714,7 +728,7 @@ cc: save-session ( -- ) {
|
|||
\ -- client is reputed to know RSA and ECDSA, both with SHA-1
|
||||
\ -- the default elliptic curve is P-256 (secp256r1, id = 23)
|
||||
0 addr-server_name set8
|
||||
0x404 addr-hashes set16
|
||||
0x0404 addr-hashes set32
|
||||
0x800000 addr-curves set32
|
||||
|
||||
\ Process extensions, if any.
|
||||
|
|
@ -813,8 +827,8 @@ cc: save-session ( -- ) {
|
|||
\ Filter hash function support by what the server also supports.
|
||||
\ If no common hash function remains with RSA and/or ECDSA, then
|
||||
\ the corresponding ECDHE suites are not possible.
|
||||
supported-hash-functions drop 257 *
|
||||
addr-hashes get16 and dup addr-hashes set16
|
||||
supported-hash-functions drop 257 * 0xFFFF0000 or
|
||||
addr-hashes get32 and dup addr-hashes set32
|
||||
\ In 'can-ecdhe', bit 12 is set if ECDHE_RSA is possible, bit 13 is
|
||||
\ set if ECDHE_ECDSA is possible.
|
||||
dup 0xFF and 0<> neg
|
||||
|
|
@ -1008,11 +1022,18 @@ cc: do-ecdhe-part1 ( curve -- len ) {
|
|||
|
||||
\ If TLS-1.2+, write hash and signature identifiers.
|
||||
tls1.2+ if
|
||||
\ Hash identifier is in the sign_hash_id field.
|
||||
addr-sign_hash_id get8 write8
|
||||
\ 'use-rsa-ecdhe?' returns -1 for RSA, 0 for ECDSA.
|
||||
\ The byte on the wire shall be 1 for RSA, 3 for ECDSA.
|
||||
addr-cipher_suite get16 use-rsa-ecdhe? 1 << 3 + write8
|
||||
\ sign_hash_id contains either a hash identifier,
|
||||
\ or the complete 16-bit value to write.
|
||||
addr-sign_hash_id get16
|
||||
dup 0xFF00 < if
|
||||
write16
|
||||
else
|
||||
0xFF and write8
|
||||
\ 'use-rsa-ecdhe?' returns -1 for RSA, 0 for
|
||||
\ ECDSA. The byte on the wire shall be 1 for RSA,
|
||||
\ 3 for ECDSA.
|
||||
addr-cipher_suite get16 use-rsa-ecdhe? 1 << 3 + write8
|
||||
then
|
||||
then
|
||||
|
||||
\ Signature.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue