Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
/*
|
|
|
|
sptps.h -- Simple Peer-to-Peer Security
|
2013-01-20 20:03:22 +00:00
|
|
|
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2012-02-25 17:25:21 +00:00
|
|
|
#ifndef __SPTPS_H__
|
|
|
|
#define __SPTPS_H__
|
|
|
|
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
#include "system.h"
|
|
|
|
|
|
|
|
#include "cipher.h"
|
|
|
|
#include "digest.h"
|
|
|
|
#include "ecdh.h"
|
|
|
|
#include "ecdsa.h"
|
|
|
|
|
2011-10-06 13:32:12 +00:00
|
|
|
#define SPTPS_VERSION 0
|
|
|
|
|
|
|
|
// Record types
|
|
|
|
#define SPTPS_HANDSHAKE 128 // Key exchange and authentication
|
|
|
|
#define SPTPS_ALERT 129 // Warning or error messages
|
|
|
|
#define SPTPS_CLOSE 130 // Application closed the connection
|
|
|
|
|
|
|
|
// Key exchange states
|
|
|
|
#define SPTPS_KEX 0 // Waiting for the first Key EXchange record
|
|
|
|
#define SPTPS_SECONDARY_KEX 1 // Ready to receive a secondary Key EXchange record
|
|
|
|
#define SPTPS_SIG 2 // Waiting for a SIGnature record
|
|
|
|
#define SPTPS_ACK 3 // Waiting for an ACKnowledgement record
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
|
2012-07-30 16:36:59 +00:00
|
|
|
typedef bool (*send_data_t)(void *handle, uint8_t type, const char *data, size_t len);
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
typedef bool (*receive_record_t)(void *handle, uint8_t type, const char *data, uint16_t len);
|
|
|
|
|
|
|
|
typedef struct sptps {
|
|
|
|
bool initiator;
|
2012-03-18 15:42:02 +00:00
|
|
|
bool datagram;
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
int state;
|
|
|
|
|
|
|
|
char *inbuf;
|
|
|
|
size_t buflen;
|
2012-02-25 14:18:15 +00:00
|
|
|
uint16_t reclen;
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
|
2011-10-05 20:00:51 +00:00
|
|
|
bool instate;
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
cipher_t incipher;
|
|
|
|
digest_t indigest;
|
|
|
|
uint32_t inseqno;
|
2013-01-15 12:33:16 +00:00
|
|
|
uint32_t received;
|
2012-07-31 18:39:15 +00:00
|
|
|
unsigned int replaywin;
|
|
|
|
unsigned int farfuture;
|
|
|
|
char *late;
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
|
2011-10-05 20:00:51 +00:00
|
|
|
bool outstate;
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
cipher_t outcipher;
|
|
|
|
digest_t outdigest;
|
|
|
|
uint32_t outseqno;
|
|
|
|
|
|
|
|
ecdsa_t mykey;
|
|
|
|
ecdsa_t hiskey;
|
|
|
|
ecdh_t ecdh;
|
|
|
|
|
2011-10-05 20:00:51 +00:00
|
|
|
char *mykex;
|
|
|
|
char *hiskex;
|
Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 13:44:51 +00:00
|
|
|
char *key;
|
|
|
|
char *label;
|
|
|
|
size_t labellen;
|
|
|
|
|
|
|
|
void *handle;
|
|
|
|
send_data_t send_data;
|
|
|
|
receive_record_t receive_record;
|
|
|
|
} sptps_t;
|
|
|
|
|
2012-07-31 18:39:15 +00:00
|
|
|
extern unsigned int sptps_replaywin;
|
2012-10-14 13:37:24 +00:00
|
|
|
extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap);
|
|
|
|
extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap);
|
|
|
|
extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap);
|
2012-03-18 15:42:02 +00:00
|
|
|
extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record);
|
2012-02-26 11:33:16 +00:00
|
|
|
extern bool sptps_stop(sptps_t *s);
|
|
|
|
extern bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len);
|
|
|
|
extern bool sptps_receive_data(sptps_t *s, const char *data, size_t len);
|
|
|
|
extern bool sptps_force_kex(sptps_t *s);
|
2012-07-31 18:36:35 +00:00
|
|
|
extern bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len);
|
2012-02-25 17:25:21 +00:00
|
|
|
|
|
|
|
#endif
|