Handling secio negotiation differently to comply with protocol
This commit is contained in:
parent
6f77a64adb
commit
4f52a20314
6 changed files with 57 additions and 45 deletions
|
@ -50,4 +50,4 @@ int libp2p_secio_propose_protobuf_encode(struct Propose* in, unsigned char* buff
|
||||||
* @param out a pointer to the new struct Propose NOTE: this method allocates memory
|
* @param out a pointer to the new struct Propose NOTE: this method allocates memory
|
||||||
* @returns true(1) on success, otherwise false(0)
|
* @returns true(1) on success, otherwise false(0)
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_propose_protobuf_decode(unsigned char* buffer, size_t max_buffer_length, struct Propose** out);
|
int libp2p_secio_propose_protobuf_decode(const unsigned char* buffer, size_t max_buffer_length, struct Propose** out);
|
||||||
|
|
|
@ -21,4 +21,4 @@ struct Libp2pProtocolHandler* libp2p_secio_build_protocol_handler(struct RsaPriv
|
||||||
* @param remote_requested the other side is who asked for the upgrade
|
* @param remote_requested the other side is who asked for the upgrade
|
||||||
* @returns true(1) on success, false(0) otherwise
|
* @returns true(1) on success, false(0) otherwise
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_handshake(struct SessionContext* session, struct RsaPrivateKey* private_key, struct Peerstore* peerstore, int remote_requested);
|
int libp2p_secio_handshake(struct SessionContext* session, struct RsaPrivateKey* private_key, struct Peerstore* peerstore, const uint8_t* buffer, size_t buffer_size);
|
||||||
|
|
|
@ -117,7 +117,7 @@ int libp2p_peer_connect(struct RsaPrivateKey* privateKey, struct Libp2pPeer* pee
|
||||||
peer->sessionContext->default_stream = peer->sessionContext->insecure_stream;
|
peer->sessionContext->default_stream = peer->sessionContext->insecure_stream;
|
||||||
peer->connection_type = CONNECTION_TYPE_CONNECTED;
|
peer->connection_type = CONNECTION_TYPE_CONNECTED;
|
||||||
}
|
}
|
||||||
libp2p_secio_handshake(peer->sessionContext, privateKey, peerstore, 0);
|
libp2p_secio_handshake(peer->sessionContext, privateKey, peerstore, NULL, 0);
|
||||||
free(ip);
|
free(ip);
|
||||||
} // is IP
|
} // is IP
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
|
|
|
@ -99,7 +99,7 @@ int libp2p_secio_propose_protobuf_encode(struct Propose* in, unsigned char* buff
|
||||||
* @param out a pointer to the new struct Propose NOTE: this method allocates memory
|
* @param out a pointer to the new struct Propose NOTE: this method allocates memory
|
||||||
* @returns true(1) on success, otherwise false(0)
|
* @returns true(1) on success, otherwise false(0)
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_propose_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Propose** out) {
|
int libp2p_secio_propose_protobuf_decode(const unsigned char* buffer, size_t buffer_length, struct Propose** out) {
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
int retVal = 0, got_something = 0;;
|
int retVal = 0, got_something = 0;;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ int libp2p_secio_can_handle(const uint8_t* incoming, size_t incoming_size) {
|
||||||
|
|
||||||
int libp2p_secio_handle_message(const uint8_t* incoming, size_t incoming_size, struct SessionContext* session_context, void* protocol_context) {
|
int libp2p_secio_handle_message(const uint8_t* incoming, size_t incoming_size, struct SessionContext* session_context, void* protocol_context) {
|
||||||
struct SecioContext* ctx = (struct SecioContext*)protocol_context;
|
struct SecioContext* ctx = (struct SecioContext*)protocol_context;
|
||||||
return libp2p_secio_handshake(session_context, ctx->private_key, ctx->peer_store, 1);
|
return libp2p_secio_handshake(session_context, ctx->private_key, ctx->peer_store, incoming, incoming_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int libp2p_secio_shutdown(void* context) {
|
int libp2p_secio_shutdown(void* context) {
|
||||||
|
@ -770,6 +770,29 @@ int libp2p_secio_encrypted_read(void* stream_context, unsigned char** bytes, siz
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pull the Propose struct out of what the remote node sent us
|
||||||
|
* @param buffer incoming bytes
|
||||||
|
* @param buffer_size the size of the incoming buffer
|
||||||
|
* @returns a Propose struct or NULL on error
|
||||||
|
*/
|
||||||
|
struct Propose* libp2p_secio_get_propose_in(const uint8_t* buffer, size_t buffer_size) {
|
||||||
|
struct Propose* retVal = NULL;
|
||||||
|
const uint8_t* buffer_ptr = buffer;
|
||||||
|
// strip off the protocol id
|
||||||
|
for(int i = 0; i < buffer_size; i++) {
|
||||||
|
if (buffer[i] == '\n') {
|
||||||
|
buffer_ptr = &buffer[i+1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get the Propose struct
|
||||||
|
if (!libp2p_secio_propose_protobuf_decode(buffer_ptr, buffer_size - (buffer_ptr - buffer), &retVal)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* performs initial communication over an insecure channel to share
|
* performs initial communication over an insecure channel to share
|
||||||
* keys, IDs, and initiate connection. This is a framed messaging system
|
* keys, IDs, and initiate connection. This is a framed messaging system
|
||||||
|
@ -779,7 +802,7 @@ int libp2p_secio_encrypted_read(void* stream_context, unsigned char** bytes, siz
|
||||||
* @param remote_requested it is the other side that requested the upgrade to secio
|
* @param remote_requested it is the other side that requested the upgrade to secio
|
||||||
* @returns true(1) on success, false(0) otherwise
|
* @returns true(1) on success, false(0) otherwise
|
||||||
*/
|
*/
|
||||||
int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPrivateKey* private_key, struct Peerstore* peerstore, int remote_requested) {
|
int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPrivateKey* private_key, struct Peerstore* peerstore, const uint8_t* incoming, size_t incoming_size) {
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
size_t results_size = 0, bytes_written = 0;
|
size_t results_size = 0, bytes_written = 0;
|
||||||
unsigned char* propose_in_bytes = NULL; // the remote protobuf
|
unsigned char* propose_in_bytes = NULL; // the remote protobuf
|
||||||
|
@ -804,30 +827,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
|
||||||
|
|
||||||
//TODO: make sure we're not talking to ourself
|
//TODO: make sure we're not talking to ourself
|
||||||
|
|
||||||
// prepare the multistream send of the protocol ID
|
// send the protocol id and the outgoing Propose struct
|
||||||
const unsigned char* protocol = (unsigned char*)"/secio/1.0.0\n";
|
|
||||||
int protocol_len = strlen((char*)protocol);
|
|
||||||
unsigned char* total = malloc(protocol_len + propose_out_size);
|
|
||||||
memcpy(total, protocol, protocol_len);
|
|
||||||
memcpy(&total[protocol_len], propose_out_bytes, propose_out_size);
|
|
||||||
|
|
||||||
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing protocol\n");
|
|
||||||
bytes_written = libp2p_net_multistream_write(local_session, total, protocol_len + propose_out_size);
|
|
||||||
free(total);
|
|
||||||
if (bytes_written <= 0)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (!remote_requested) {
|
|
||||||
// we should get back the secio confirmation
|
|
||||||
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Reading protocol response\n");
|
|
||||||
bytes_written = libp2p_net_multistream_read(local_session, &results, &results_size, 20);
|
|
||||||
if (bytes_written < 5 || strstr((char*)results, "secio") == NULL)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
free(results);
|
|
||||||
results = NULL;
|
|
||||||
results_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate 16 byte nonce
|
// generate 16 byte nonce
|
||||||
if (!libp2p_secio_generate_nonce(&local_session->local_nonce[0], 16)) {
|
if (!libp2p_secio_generate_nonce(&local_session->local_nonce[0], 16)) {
|
||||||
|
@ -868,26 +868,40 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
|
||||||
// supported hashes
|
// supported hashes
|
||||||
libp2p_secio_propose_set_property((void**)&propose_out->hashes, &propose_out->hashes_size, SupportedHashes, strlen(SupportedHashes));
|
libp2p_secio_propose_set_property((void**)&propose_out->hashes, &propose_out->hashes_size, SupportedHashes, strlen(SupportedHashes));
|
||||||
|
|
||||||
// send proposal
|
// protobuf the proposal
|
||||||
propose_out_size = libp2p_secio_propose_protobuf_encode_size(propose_out);
|
propose_out_size = libp2p_secio_propose_protobuf_encode_size(propose_out);
|
||||||
propose_out_bytes = (unsigned char*)malloc(propose_out_size);
|
propose_out_bytes = (unsigned char*)malloc(propose_out_size);
|
||||||
if (libp2p_secio_propose_protobuf_encode(propose_out, propose_out_bytes, propose_out_size, &propose_out_size) == 0)
|
if (libp2p_secio_propose_protobuf_encode(propose_out, propose_out_bytes, propose_out_size, &propose_out_size) == 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
// tack on the protocol id in front
|
||||||
|
const unsigned char* protocol = (unsigned char*)"/secio/1.0.0\n";
|
||||||
|
int protocol_len = strlen((char*)protocol);
|
||||||
|
unsigned char* total = malloc(protocol_len + propose_out_size);
|
||||||
|
memcpy(total, protocol, protocol_len);
|
||||||
|
memcpy(&total[protocol_len], propose_out_bytes, propose_out_size);
|
||||||
|
|
||||||
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Writing propose_out\n");
|
// write the Proposal to the stream
|
||||||
bytes_written = libp2p_secio_unencrypted_write(local_session, propose_out_bytes, propose_out_size);
|
bytes_written = libp2p_secio_unencrypted_write(local_session, total, protocol_len + propose_out_size);
|
||||||
if (bytes_written < propose_out_size)
|
if (bytes_written < propose_out_size + protocol_len)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// now receive the proposal from the new connection
|
if (incoming_size > 0) {
|
||||||
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "receiving propose_in\n");
|
propose_in_bytes = (uint8_t*)incoming;
|
||||||
|
propose_in_size = incoming_size;
|
||||||
|
} else {
|
||||||
bytes_written = libp2p_secio_unencrypted_read(local_session, &propose_in_bytes, &propose_in_size, 10);
|
bytes_written = libp2p_secio_unencrypted_read(local_session, &propose_in_bytes, &propose_in_size, 10);
|
||||||
if (bytes_written <= 0)
|
if (bytes_written <= 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
if (!libp2p_secio_propose_protobuf_decode(propose_in_bytes, propose_in_size, &propose_in))
|
propose_in = libp2p_secio_get_propose_in(propose_in_bytes, propose_in_size);
|
||||||
|
if (propose_in == NULL) {
|
||||||
|
libp2p_logger_error("secio", "Unable to get the remote's Propose struct\n");
|
||||||
|
if (incoming_size == 0) {
|
||||||
|
free(propose_in_bytes);
|
||||||
|
}
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
// get their nonce
|
// get their nonce
|
||||||
if (propose_in->rand_size != 16)
|
if (propose_in->rand_size != 16)
|
||||||
|
@ -1102,8 +1116,6 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva
|
||||||
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake complete\n");
|
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake complete\n");
|
||||||
exit:
|
exit:
|
||||||
|
|
||||||
if (propose_in_bytes != NULL)
|
|
||||||
free(propose_in_bytes);
|
|
||||||
if (propose_out_bytes != NULL)
|
if (propose_out_bytes != NULL)
|
||||||
free(propose_out_bytes);
|
free(propose_out_bytes);
|
||||||
if (results != NULL)
|
if (results != NULL)
|
||||||
|
|
|
@ -69,7 +69,7 @@ int test_secio_handshake() {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
//secure_session.host = "www.jmjatlanta.com";
|
//secure_session.host = "www.jmjatlanta.com";
|
||||||
secure_session.host = "10.211.55.2";
|
secure_session.host = "10.211.55.4";
|
||||||
secure_session.port = 4001;
|
secure_session.port = 4001;
|
||||||
secure_session.traffic_type = TCP;
|
secure_session.traffic_type = TCP;
|
||||||
// connect to host
|
// connect to host
|
||||||
|
@ -80,7 +80,7 @@ int test_secio_handshake() {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!libp2p_secio_handshake(&secure_session, rsa_private_key, NULL, 0)) {
|
if (!libp2p_secio_handshake(&secure_session, rsa_private_key, NULL, NULL, 0)) {
|
||||||
fprintf(stderr, "test_secio_handshake: Unable to do handshake\n");
|
fprintf(stderr, "test_secio_handshake: Unable to do handshake\n");
|
||||||
fprintf(stdout, "Shared key: ");
|
fprintf(stdout, "Shared key: ");
|
||||||
for(int i = 0; i < secure_session.shared_key_size; i++)
|
for(int i = 0; i < secure_session.shared_key_size; i++)
|
||||||
|
|
Loading…
Reference in a new issue