Make sure the signature also covers the session label.

This commit is contained in:
Guus Sliepen 2012-03-18 21:24:46 +01:00
parent 42a0b61076
commit d7bf63c63a
2 changed files with 9 additions and 6 deletions

View file

@ -124,7 +124,7 @@ Remarks:
- After receiving the other's SIG message, the signature is verified. If it is - After receiving the other's SIG message, the signature is verified. If it is
correct, the shared secret is calculated from the public keys exchanged in the correct, the shared secret is calculated from the public keys exchanged in the
KEX message using the Elliptic Curve Diffie-Helman algorithm. KEX message using the Elliptic Curve Diffie-Helman algorithm.
- The shared secret key is expanded using a PRF. Both nonces and an application - The shared secret key is expanded using a PRF. Both nonces and the application
specific label are also used as input for the PRF. specific label are also used as input for the PRF.
- An ACK message is sent only when doing key renegotiation, and is sent using - An ACK message is sent only when doing key renegotiation, and is sent using
the old encryption keys. the old encryption keys.
@ -135,6 +135,7 @@ The signature is calculated over this string:
- uint8_t initiator (0 = local peer, 1 = remote peer is initiator) - uint8_t initiator (0 = local peer, 1 = remote peer is initiator)
- opaque remote_kex_message[1 + 32 + ECDH_SIZE] - opaque remote_kex_message[1 + 32 + ECDH_SIZE]
- opaque local_kex_message[1 + 32 + ECDH_SIZE] - opaque local_kex_message[1 + 32 + ECDH_SIZE]
- opaque label[label_length]
The PRF is calculated as follows: The PRF is calculated as follows:

View file

@ -159,13 +159,14 @@ static bool send_sig(sptps_t *s) {
size_t keylen = ECDH_SIZE; size_t keylen = ECDH_SIZE;
size_t siglen = ecdsa_size(&s->mykey); size_t siglen = ecdsa_size(&s->mykey);
// Concatenate both KEX messages, plus tag indicating if it is from the connection originator // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label
char msg[(1 + 32 + keylen) * 2 + 1]; char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
char sig[siglen]; char sig[siglen];
msg[0] = s->initiator; msg[0] = s->initiator;
memcpy(msg + 1, s->mykex, 1 + 32 + keylen); memcpy(msg + 1, s->mykex, 1 + 32 + keylen);
memcpy(msg + 2 + 32 + keylen, s->hiskex, 1 + 32 + keylen); memcpy(msg + 1 + 33 + keylen, s->hiskex, 1 + 32 + keylen);
memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);
// Sign the result. // Sign the result.
if(!ecdsa_sign(&s->mykey, msg, sizeof msg, sig)) if(!ecdsa_sign(&s->mykey, msg, sizeof msg, sig))
@ -275,11 +276,12 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
return error(s, EIO, "Invalid KEX record length"); return error(s, EIO, "Invalid KEX record length");
// Concatenate both KEX messages, plus tag indicating if it is from the connection originator // Concatenate both KEX messages, plus tag indicating if it is from the connection originator
char msg[(1 + 32 + keylen) * 2 + 1]; char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
msg[0] = !s->initiator; msg[0] = !s->initiator;
memcpy(msg + 1, s->hiskex, 1 + 32 + keylen); memcpy(msg + 1, s->hiskex, 1 + 32 + keylen);
memcpy(msg + 2 + 32 + keylen, s->mykex, 1 + 32 + keylen); memcpy(msg + 1 + 33 + keylen, s->mykex, 1 + 32 + keylen);
memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);
// Verify signature. // Verify signature.
if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data)) if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data))