#include "prf.h"
#include "sptps.h"
-unsigned int sptps_replaywin = 16;
+unsigned int sptps_replaywin = 32;
/*
Nonce MUST be exchanged first (done)
memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);
// Sign the result.
- if(!ecdsa_sign(s->mykey, msg, sizeof msg, sig))
+ if(!ecdsa_sign(s->mykey, msg, sizeof(msg), sig))
return error(s, EINVAL, "Failed to sign SIG record");
// Send the SIG exchange record.
- return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof sig);
+ return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof(sig));
}
// Generate key material from the shared secret created from the ECDHE key exchange.
memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);
// Verify signature.
- if(!ecdsa_verify(s->hiskey, msg, sizeof msg, data))
+ if(!ecdsa_verify(s->hiskey, msg, sizeof(msg), data))
return error(s, EIO, "Failed to verify SIG record");
// Compute shared secret.
s->ecdh = NULL;
// Generate key material from shared secret.
- if(!generate_key_material(s, shared, sizeof shared))
+ if(!generate_key_material(s, shared, sizeof(shared)))
return false;
free(s->mykex);
static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) {
// Only a few states to deal with handshaking.
switch(s->state) {
- case SPTPS_SECONDARY_KEX:
- // We receive a secondary KEX request, first respond by sending our own.
- if(!send_kex(s))
- return false;
- case SPTPS_KEX:
- // We have sent our KEX request, we expect our peer to sent one as well.
- if(!receive_kex(s, data, len))
- return false;
- s->state = SPTPS_SIG;
- return true;
- case SPTPS_SIG:
- // If we already sent our secondary public ECDH key, we expect the peer to send his.
- if(!receive_sig(s, data, len))
- return false;
- if(s->outstate)
- s->state = SPTPS_ACK;
- else {
- s->outstate = true;
- if(!receive_ack(s, NULL, 0))
- return false;
- s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0);
- s->state = SPTPS_SECONDARY_KEX;
- }
-
- return true;
- case SPTPS_ACK:
- // We expect a handshake message to indicate transition to the new keys.
- if(!receive_ack(s, data, len))
+ case SPTPS_SECONDARY_KEX:
+ // We receive a secondary KEX request, first respond by sending our own.
+ if(!send_kex(s))
+ return false;
+ case SPTPS_KEX:
+ // We have sent our KEX request, we expect our peer to sent one as well.
+ if(!receive_kex(s, data, len))
+ return false;
+ s->state = SPTPS_SIG;
+ return true;
+ case SPTPS_SIG:
+ // If we already sent our secondary public ECDH key, we expect the peer to send his.
+ if(!receive_sig(s, data, len))
+ return false;
+ if(s->outstate)
+ s->state = SPTPS_ACK;
+ else {
+ s->outstate = true;
+ if(!receive_ack(s, NULL, 0))
return false;
s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0);
s->state = SPTPS_SECONDARY_KEX;
- return true;
- // TODO: split ACK into a VERify and ACK?
- default:
- return error(s, EIO, "Invalid session state %d", s->state);
+ }
+
+ return true;
+ case SPTPS_ACK:
+ // We expect a handshake message to indicate transition to the new keys.
+ if(!receive_ack(s, data, len))
+ return false;
+ s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0);
+ s->state = SPTPS_SECONDARY_KEX;
+ return true;
+ // TODO: split ACK into a VERify and ACK?
+ default:
+ return error(s, EIO, "Invalid session state %d", s->state);
}
}
// Check datagram for valid HMAC
bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) {
- if (!s->instate)
+ if(!s->instate)
return error(s, EIO, "SPTPS state not ready to verify this datagram");
if(len < 21)
warning(s, "Lost %d packets\n", seqno - s->inseqno);
// Mark all packets in the replay window as being late.
memset(s->late, 255, s->replaywin);
- } else if (seqno < s->inseqno) {
+ } else if(seqno < s->inseqno) {
// If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it.
if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8)))
return error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno);
} else if(type == SPTPS_HANDSHAKE) {
if(!receive_handshake(s, buffer + 1, len - 21))
abort();
- } else {
+ } else
return error(s, EIO, "Invalid record type %d", type);
- }
return true;
}
} else if(type == SPTPS_HANDSHAKE) {
if(!receive_handshake(s, s->inbuf + 3, s->reclen))
return false;
- } else {
+ } else
return error(s, EIO, "Invalid record type %d", type);
- }
s->buflen = 0;
}
return error(s, EINVAL, "Invalid argument to sptps_start()");
// Initialise struct sptps
- memset(s, 0, sizeof *s);
+ memset(s, 0, sizeof(*s));
s->handle = handle;
s->initiator = initiator;
free(s->key);
free(s->label);
free(s->late);
- memset(s, 0, sizeof *s);
+ memset(s, 0, sizeof(*s));
return true;
}