X-Git-Url: http://git.meshlink.io/?p=meshlink;a=blobdiff_plain;f=src%2Fsptps.c;h=ed1f67ff95afd11ac1adfd6f6b95edcca72bf7de;hp=f44374ee4bf472b7fea3127ff3b777ffa26aa517;hb=963c5055505f2fc117cd5efa06eaa02c9b2bf85d;hpb=dc0e52cb3e42620c3139e713b373d130aa30b698 diff --git a/src/sptps.c b/src/sptps.c index f44374ee..ed1f67ff 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -27,8 +27,6 @@ #include "prf.h" #include "sptps.h" -unsigned int sptps_replaywin = 32; - /* Nonce MUST be exchanged first (done) Signatures MUST be done over both nonces, to guarantee the signature is fresh @@ -54,19 +52,27 @@ void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap) { (void)s_errno; (void)format; (void)ap; + + assert(format); } void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap) { (void)s; (void)s_errno; + + assert(format); + vfprintf(stderr, format, ap); fputc('\n', stderr); } -void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = sptps_log_stderr; +void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = sptps_log_quiet; // Log an error message. static bool error(sptps_t *s, int s_errno, const char *format, ...) { + assert(s_errno); + assert(format); + if(format) { va_list ap; va_start(ap, format); @@ -79,6 +85,8 @@ static bool error(sptps_t *s, int s_errno, const char *format, ...) { } static void warning(sptps_t *s, const char *format, ...) { + assert(format); + va_list ap; va_start(ap, format); sptps_log(s, 0, format, ap); @@ -134,6 +142,8 @@ static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_ // Send an application record. bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len) { + assert(!len || data); + // Sanity checks: application cannot send data before handshake is finished, // and only record types 0..127 are allowed. if(!s->outstate) { @@ -201,6 +211,9 @@ static bool send_sig(sptps_t *s) { // Generate key material from the shared secret created from the ECDHE key exchange. static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { + assert(shared); + assert(len); + // Initialise cipher and digest structures if necessary if(!s->outstate) { s->incipher = chacha_poly1305_init(); @@ -445,9 +458,7 @@ bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) { seqno = ntohl(seqno); // TODO: check whether seqno makes sense, to avoid CPU intensive decrypt - char buffer[len]; - size_t outlen; - return chacha_poly1305_decrypt(s->incipher, seqno, (const char *)data + 4, len - 4, buffer, &outlen); + return chacha_poly1305_verify(s->incipher, seqno, (const char *)data + 4, len - 4); } // Receive incoming data, datagram version. @@ -480,11 +491,20 @@ static bool sptps_receive_data_datagram(sptps_t *s, const void *vdata, size_t le // Decrypt - char buffer[len]; + if(len > s->decrypted_buffer_len) { + s->decrypted_buffer_len *= 2; + char *new_buffer = realloc(s->decrypted_buffer, s->decrypted_buffer_len); + + if(!new_buffer) { + return error(s, errno, strerror(errno)); + } + + s->decrypted_buffer = new_buffer; + } size_t outlen; - if(!chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, buffer, &outlen)) { + if(!chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, s->decrypted_buffer, &outlen)) { return error(s, EIO, "Failed to decrypt and verify packet"); } @@ -528,20 +548,20 @@ static bool sptps_receive_data_datagram(sptps_t *s, const void *vdata, size_t le } // Append a NULL byte for safety. - buffer[len - 20] = 0; + s->decrypted_buffer[len - 20] = 0; - uint8_t type = buffer[0]; + uint8_t type = s->decrypted_buffer[0]; if(type < SPTPS_HANDSHAKE) { if(!s->instate) { return error(s, EIO, "Application record received before handshake finished"); } - if(!s->receive_record(s->handle, type, buffer + 1, len - 21)) { + if(!s->receive_record(s->handle, type, s->decrypted_buffer + 1, len - 21)) { abort(); } } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, buffer + 1, len - 21)) { + if(!receive_handshake(s, s->decrypted_buffer + 1, len - 21)) { abort(); } } else { @@ -670,7 +690,13 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ s->datagram = datagram; s->mykey = mykey; s->hiskey = hiskey; - s->replaywin = sptps_replaywin; + s->replaywin = 32; + s->decrypted_buffer_len = 1024; + s->decrypted_buffer = malloc(s->decrypted_buffer_len); + + if(!s->decrypted_buffer) { + return error(s, errno, strerror(errno)); + } if(s->replaywin) { s->late = malloc(s->replaywin); @@ -721,6 +747,8 @@ bool sptps_stop(sptps_t *s) { free(s->key); free(s->label); free(s->late); + memset(s->decrypted_buffer, 0, s->decrypted_buffer_len); + free(s->decrypted_buffer); memset(s, 0, sizeof(*s)); return true; }