projects
/
tinc
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Use datagram SPTPS for packet exchange between nodes.
[tinc]
/
src
/
sptps.c
diff --git
a/src/sptps.c
b/src/sptps.c
index
fa1594d
..
422940c
100644
(file)
--- a/
src/sptps.c
+++ b/
src/sptps.c
@@
-78,10
+78,10
@@
static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const char *data
if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
return false;
if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
return false;
- return s->send_data(s->handle, buffer + 2, len + 21UL);
+ return s->send_data(s->handle,
type,
buffer + 2, len + 21UL);
} else {
// Otherwise send as plaintext
} else {
// Otherwise send as plaintext
- return s->send_data(s->handle, buffer + 2, len + 5UL);
+ return s->send_data(s->handle,
type,
buffer + 2, len + 5UL);
}
}
// Send a record (private version, accepts all record types, handles encryption and authentication).
}
}
// Send a record (private version, accepts all record types, handles encryption and authentication).
@@
-110,10
+110,10
@@
static bool send_record_priv(sptps_t *s, uint8_t type, const char *data, uint16_
if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
return false;
if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
return false;
- return s->send_data(s->handle, buffer + 4, len + 19UL);
+ return s->send_data(s->handle,
type,
buffer + 4, len + 19UL);
} else {
// Otherwise send as plaintext
} else {
// Otherwise send as plaintext
- return s->send_data(s->handle, buffer + 4, len + 3UL);
+ return s->send_data(s->handle,
type,
buffer + 4, len + 3UL);
}
}
}
}
@@
-159,13
+159,14
@@
static bool send_sig(sptps_t *s) {
size_t keylen = ECDH_SIZE;
size_t siglen = ecdsa_size(&s->mykey);
size_t keylen = ECDH_SIZE;
size_t siglen = ecdsa_size(&s->mykey);
- // Concatenate both KEX messages, plus tag indicating if it is from the connection originator
- char msg[(1 + 32 + keylen) * 2 + 1];
+ // Concatenate both KEX messages, plus tag indicating if it is from the connection originator
, plus label
+ char msg[(1 + 32 + keylen) * 2 + 1
+ s->labellen
];
char sig[siglen];
msg[0] = s->initiator;
memcpy(msg + 1, s->mykex, 1 + 32 + keylen);
char sig[siglen];
msg[0] = s->initiator;
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.
if(!ecdsa_sign(&s->mykey, msg, sizeof msg, sig))
// Sign the result.
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");
// Concatenate both KEX messages, plus tag indicating if it is from the connection originator
return error(s, EIO, "Invalid KEX record length");
// 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;
memcpy(msg + 1, s->hiskex, 1 + 32 + keylen);
msg[0] = !s->initiator;
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.
if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data))
// Verify signature.
if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data))
@@
-301,7
+303,7
@@
static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
s->hiskex = NULL;
// Send cipher change record
s->hiskex = NULL;
// Send cipher change record
- if(!send_ack(s))
+ if(
s->outstate &&
!send_ack(s))
return false;
// TODO: only set new keys after ACK has been set/received
return false;
// TODO: only set new keys after ACK has been set/received
@@
-319,8
+321,6
@@
static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
return false;
}
return false;
}
- s->outstate = true;
-
return true;
}
return true;
}
@@
-352,7
+352,16
@@
static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) {
// 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 we already sent our secondary public ECDH key, we expect the peer to send his.
if(!receive_sig(s, data, len))
return false;
- s->state = SPTPS_ACK;
+ 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.
return true;
case SPTPS_ACK:
// We expect a handshake message to indicate transition to the new keys.
@@
-429,6
+438,9
@@
static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len
return error(s, EIO, "Application record received before handshake finished");
if(!s->receive_record(s->handle, type, buffer + 7, len - 21))
return false;
return error(s, EIO, "Application record received before handshake finished");
if(!s->receive_record(s->handle, type, buffer + 7, len - 21))
return false;
+ } else if(type == SPTPS_HANDSHAKE) {
+ if(!receive_handshake(s, buffer + 7, len - 21))
+ return false;
} else {
return error(s, EIO, "Invalid record type");
}
} else {
return error(s, EIO, "Invalid record type");
}
@@
-567,9
+579,14
@@
bool sptps_stop(sptps_t *s) {
// Clean up any resources.
ecdh_free(&s->ecdh);
free(s->inbuf);
// Clean up any resources.
ecdh_free(&s->ecdh);
free(s->inbuf);
+ s->inbuf = NULL;
free(s->mykex);
free(s->mykex);
+ s->mykex = NULL;
free(s->hiskex);
free(s->hiskex);
+ s->hiskex = NULL;
free(s->key);
free(s->key);
+ s->key = NULL;
free(s->label);
free(s->label);
+ s->label = NULL;
return true;
}
return true;
}