Beispiel #1
0
// encode packet
static int packetEncode(unsigned char *pbuf, const int pbuf_size, const struct s_packet_data *data, struct s_crypto *ctx) {
	unsigned char dec_buf[packet_CRHDR_SIZE + data->pl_buf_size];
	int32_t *scr_peerid = ((int32_t *)pbuf);
	int32_t ne_peerid;
	int len;
	
	// check if enough space is available for the operation
	if(data->pl_length > data->pl_buf_size) { return 0; }
	
	// prepare buffer
	utilWriteInt64(&dec_buf[packet_CRHDR_SEQ_START], data->seq);
	utilWriteInt16(&dec_buf[packet_CRHDR_PLLEN_START], data->pl_length);
	dec_buf[packet_CRHDR_PLTYPE_START] = data->pl_type;
	dec_buf[packet_CRHDR_PLOPT_START] = data->pl_options;
	memcpy(&dec_buf[packet_CRHDR_SIZE], data->pl_buf, data->pl_length);
	
	// encrypt buffer
	len = cryptoEnc(ctx, &pbuf[packet_PEERID_SIZE], (pbuf_size - packet_PEERID_SIZE), dec_buf, (packet_CRHDR_SIZE + data->pl_length), packet_HMAC_SIZE, packet_IV_SIZE);
	if(len < (packet_HMAC_SIZE + packet_IV_SIZE + packet_CRHDR_SIZE)) { return 0; }
	
	// write the scrambled peer ID
	utilWriteInt32((unsigned char *)&ne_peerid, data->peerid);
	scr_peerid[0] = (ne_peerid ^ (scr_peerid[1] ^ scr_peerid[2]));

	// return length of encoded packet
	return (packet_PEERID_SIZE + len);
}
Beispiel #2
0
// Generate auth message S3
static void authGenS3(struct s_auth_state *authstate) {
	// generate msg(remote_authid, msgnum, enc(keygen_nonce, local_seq, local_peerid, local_flags))
	unsigned char unencrypted_nextmsg[auth_MAXMSGSIZE_S3];
	int unencrypted_nextmsg_size = (4 + 2 + auth_NONCESIZE + seq_SIZE + 4 + 8);
	int msgnum = authstate->state;
	int encsize;
	if(authstate->local_cneg_set) {
		memcpy(unencrypted_nextmsg, authstate->remote_authid, 4);
		utilWriteInt16(&unencrypted_nextmsg[4], msgnum);
		memcpy(authstate->nextmsg, unencrypted_nextmsg, 6);
		memcpy(&unencrypted_nextmsg[(4 + 2)], authstate->local_keygen_nonce, auth_NONCESIZE);
		memcpy(&unencrypted_nextmsg[(4 + 2 + auth_NONCESIZE)], authstate->local_seq, seq_SIZE);
		utilWriteInt32(&unencrypted_nextmsg[(4 + 2 + auth_NONCESIZE + seq_SIZE)], authstate->local_peerid);
		memcpy(&unencrypted_nextmsg[(4 + 2 + auth_NONCESIZE + seq_SIZE + 4)], authstate->local_flags, 8);
		encsize = cryptoEnc(&authstate->crypto_ctx[auth_CRYPTOCTX_CNEG], &authstate->nextmsg[(4 + 2)], (auth_MAXMSGSIZE - 2 - 4), &unencrypted_nextmsg[(4 + 2)], (unencrypted_nextmsg_size - 2 - 4), auth_CNEGHMACSIZE, auth_CNEGIVSIZE);
		if(encsize > 0) {
			authstate->nextmsg_size = (encsize + 4 + 2);
		}
		else {
			authstate->nextmsg_size = 0;
		}
	}
	else {
		authstate->nextmsg_size = 0;
	}
}
Beispiel #3
0
// Generate auth message S2
static void authGenS2(struct s_auth_state *authstate) {
	// generate msg(remote_authid, msgnum, enc(pubkey_len, pubkey, sig_len, sig(authid, msgnum, local_nonce, remote_nonce, remote_dhkey, local_dhkey), hmac(pubkey)))
	unsigned char unencrypted_nextmsg[auth_MAXMSGSIZE_S2];
	int unencrypted_nextmsg_size;
	int msgnum = authstate->state;
	unsigned char siginbuf[auth_SIGINBUFSIZE];
	struct s_nodekey *local_nodekey;
	struct s_rsa *rsakey;
	int siginbuf_size;
	int nksize;
	int signsize;
	int encsize;
	memcpy(unencrypted_nextmsg, authstate->remote_authid, 4);
	utilWriteInt16(&unencrypted_nextmsg[4], msgnum);
	memcpy(authstate->nextmsg, unencrypted_nextmsg, 6);
	siginbuf_size = authGenSigIn(authstate, siginbuf, &unencrypted_nextmsg[4]);
	local_nodekey = authstate->local_nodekey;
	nksize = nodekeyGetDER(&unencrypted_nextmsg[(4 + 2 + 2)], nodekey_MAXSIZE, local_nodekey);
	if(nksize > nodekey_MINSIZE) {
		utilWriteInt16(&unencrypted_nextmsg[(4 + 2)], nksize);
		rsakey = &local_nodekey->key;
		signsize = rsaSign(rsakey, &unencrypted_nextmsg[(4 + 2 + 2 + nksize + 2)], nodekey_MAXSIZE, siginbuf, siginbuf_size);
		if(signsize > 0) {
			utilWriteInt16(&unencrypted_nextmsg[(4 + 2 + 2 + nksize)], signsize);
			if(cryptoHMAC(&authstate->crypto_ctx[auth_CRYPTOCTX_AUTH], &unencrypted_nextmsg[(4 + 2 + 2 + nksize + 2 + signsize)], auth_HMACSIZE, &unencrypted_nextmsg[(4 + 2 + 2)], nksize)) {
				unencrypted_nextmsg_size = (4 + 2 + 2 + nksize + 2 + signsize + auth_HMACSIZE);
				encsize = cryptoEnc(&authstate->crypto_ctx[auth_CRYPTOCTX_IDP], &authstate->nextmsg[(4 + 2)], (auth_MAXMSGSIZE - 2 - 4), &unencrypted_nextmsg[(2 + 4)], (unencrypted_nextmsg_size - 2 - 4), auth_IDPHMACSIZE, auth_IDPIVSIZE);
				if(encsize > 0) {
					authstate->nextmsg_size = (encsize + 4 + 2);
				}
				else {
					authstate->nextmsg_size = 0;
				}
			}
			else {
				authstate->nextmsg_size = 0;
			}
		}
		else {
			authstate->nextmsg_size = 0;
		}
	}
	else {
		authstate->nextmsg_size = 0;
	}
}
Beispiel #4
0
// Generate auth message S4
static void authGenS4(struct s_auth_state *authstate) {
	// generate msg(remote_authid, msgnum, nonce, hmac_nonce)
	int msgnum = authstate->state;
	memcpy(authstate->nextmsg, authstate->remote_authid, 4);
	utilWriteInt16(&authstate->nextmsg[4], msgnum);
	memcpy(&authstate->nextmsg[6], authstate->s4msg_nonce, auth_NONCESIZE);
	if(cryptoHMAC(&authstate->crypto_ctx[auth_CRYPTOCTX_CNEG], &authstate->nextmsg[(6 + auth_NONCESIZE)], auth_CNEGHMACSIZE, authstate->s4msg_nonce, auth_NONCESIZE)) {
		authstate->nextmsg_size = (6 + auth_NONCESIZE + auth_CNEGHMACSIZE);
	}
	else {
		authstate->nextmsg_size = 0;
	}
}
Beispiel #5
0
// Generate auth message S1
static void authGenS1(struct s_auth_state *authstate) {
	// generate msg(remote_authid, msgnum, checksum, sesstoken, nonce, dhkey_len, dhkey)
	int msgnum = authstate->state;
	int dhsize;
	memcpy(authstate->nextmsg, authstate->remote_authid, 4);
	utilWriteInt16(&authstate->nextmsg[4], msgnum);
	memcpy(&authstate->nextmsg[(4 + 2 + 8)], &authstate->remote_sesstoken, 4);
	memcpy(&authstate->nextmsg[(4 + 2 + 8 + 4)], authstate->local_nonce, auth_NONCESIZE);
	dhsize = dhGetPubkey(&authstate->nextmsg[(4 + 2 + 8 + 4 + auth_NONCESIZE + 2)], dh_MAXSIZE, authstate->dhstate);
	if(dhsize > dh_MINSIZE) {
		utilWriteInt16(&authstate->nextmsg[(4 + 2 + 8 + 4 + auth_NONCESIZE)], dhsize);
		if(cryptoCalculateSHA256(&authstate->nextmsg[(4 + 2)], 8, &authstate->nextmsg[(4 + 2 + 8)], (4 + auth_NONCESIZE + 2 + dhsize))) {
			authstate->nextmsg_size = (4 + 2 + 8 + 4 + auth_NONCESIZE + 2 + dhsize);
		}
		else {
			authstate->nextmsg_size = 0;
		}
	}
	else {
		authstate->nextmsg_size = 0;
	}
}
Beispiel #6
0
// Generate auth message S0
static void authGenS0(struct s_auth_state *authstate) {
	// generate msg(remote_authid, msgnum, checksum, authid, sesstoken, netid)
	int msgnum = authstate->state;
	memcpy(authstate->nextmsg, authstate->remote_authid, 4);
	utilWriteInt16(&authstate->nextmsg[4], msgnum);
	memcpy(&authstate->nextmsg[(4 + 2 + 8)], &authstate->local_authid, 4);
	memcpy(&authstate->nextmsg[(4 + 2 + 8 + 4)], &authstate->local_sesstoken, 4);
	memcpy(&authstate->nextmsg[(4 + 2 + 8 + 4 + 4)], authstate->netid->id, netid_SIZE);
	if(cryptoCalculateSHA256(&authstate->nextmsg[(4 + 2)], 8, &authstate->nextmsg[(4 + 2 + 8)], (4 + 4 + netid_SIZE))) {
		authstate->nextmsg_size = (4 + 2 + 8 + 4 + 4 + netid_SIZE);
	}
	else {
		authstate->nextmsg_size = 0;
	}
}
Beispiel #7
0
// Generate peer manager status report.
static void peermgtStatus(struct s_peermgt *mgt, char *report, const int report_len) {
	int tnow = utilGetTime();
	int pos = 0;
	int size = mapGetMapSize(&mgt->map);
	int maxpos = (((size + 2) * (160)) + 1);
	unsigned char infoid[packet_PEERID_SIZE];
	unsigned char infostate[1];
	unsigned char infoflags[2];
	unsigned char inforq[1];
	unsigned char timediff[4];
	struct s_nodeid nodeid;
	int i = 0;
	
	if(maxpos > report_len) { maxpos = report_len; }
	
	memcpy(&report[pos], "PeerID    NodeID                                                            Address                                       Status  LastPkt   SessAge   Flag  RQ", 158);
	pos = pos + 158;
	report[pos++] = '\n';
	
	while(i < size && pos < maxpos) {
		if(peermgtGetNodeID(mgt, &nodeid, i)) {
			utilWriteInt32(infoid, i);
			utilByteArrayToHexstring(&report[pos], ((packet_PEERID_SIZE * 2) + 2), infoid, packet_PEERID_SIZE);
			pos = pos + (packet_PEERID_SIZE * 2);
			report[pos++] = ' ';
			report[pos++] = ' ';
			utilByteArrayToHexstring(&report[pos], ((nodeid_SIZE * 2) + 2), nodeid.id, nodeid_SIZE);
			pos = pos + (nodeid_SIZE * 2);
			report[pos++] = ' ';
			report[pos++] = ' ';
			utilByteArrayToHexstring(&report[pos], ((peeraddr_SIZE * 2) + 2), mgt->data[i].remoteaddr.addr, peeraddr_SIZE);
			pos = pos + (peeraddr_SIZE * 2);
			report[pos++] = ' ';
			report[pos++] = ' ';
			infostate[0] = mgt->data[i].state;
			utilByteArrayToHexstring(&report[pos], 4, infostate, 1);
			pos = pos + 2;
			report[pos++] = ' ';
			report[pos++] = ' ';
			utilWriteInt32(timediff, (tnow - mgt->data[i].lastrecv));
			utilByteArrayToHexstring(&report[pos], 10, timediff, 4);
			pos = pos + 8;
			report[pos++] = ' ';
			report[pos++] = ' ';
			utilWriteInt32(timediff, (tnow - mgt->data[i].conntime));
			utilByteArrayToHexstring(&report[pos], 10, timediff, 4);
			pos = pos + 8;
			report[pos++] = ' ';
			report[pos++] = ' ';
			utilWriteInt16(infoflags, mgt->data[i].remoteflags);
			utilByteArrayToHexstring(&report[pos], 6, infoflags, 2);
			pos = pos + 4;
			report[pos++] = ' ';
			report[pos++] = ' ';
			inforq[0] = seqRQ(&mgt->data[i].seq);
			utilByteArrayToHexstring(&report[pos], 4, inforq, 1);
			pos = pos + 2;
			report[pos++] = '\n';
		}
		i++;
	}
	report[pos++] = '\0';
}
Beispiel #8
0
// generate keys
static int cryptoSetKeys(struct s_crypto *ctxs, const int count, const unsigned char *secret_buf, const int secret_len, const unsigned char *nonce_buf, const int nonce_len) {
	int cur_key_len;
	unsigned char cur_key[EVP_MAX_MD_SIZE];
	int seed_key_len;
	unsigned char seed_key[EVP_MAX_MD_SIZE];
	const EVP_MD *keygen_md = EVP_sha512();
	const EVP_MD *out_md = EVP_sha256();
	const EVP_CIPHER *out_cipher = EVP_aes_256_cbc();
	const int key_size = EVP_CIPHER_key_length(out_cipher);
	HMAC_CTX hmac_ctx;
	int16_t i;
	unsigned char in[2];
	int j,k;

	// setup hmac as the pseudorandom function
	HMAC_CTX_init(&hmac_ctx);
	
	// calculate seed key
	HMAC_Init_ex(&hmac_ctx, nonce_buf, nonce_len, keygen_md, NULL);
	HMAC_Update(&hmac_ctx, secret_buf, secret_len);
	HMAC_Final(&hmac_ctx, seed_key, (unsigned int *)&seed_key_len);
	
	// calculate derived keys
	HMAC_Init_ex(&hmac_ctx, seed_key, seed_key_len, keygen_md, NULL);
	HMAC_Update(&hmac_ctx, nonce_buf, nonce_len);
	HMAC_Final(&hmac_ctx, cur_key, (unsigned int *)&cur_key_len);
	i = 0;
	j = 0;
	k = 0;
	while(k < count) {
		// calculate next key
		utilWriteInt16(in, i);
		HMAC_Init_ex(&hmac_ctx, NULL, -1, NULL, NULL);
		HMAC_Update(&hmac_ctx, cur_key, cur_key_len);
		HMAC_Update(&hmac_ctx, nonce_buf, nonce_len);
		HMAC_Update(&hmac_ctx, in, 2);
		HMAC_Final(&hmac_ctx, cur_key, (unsigned int *)&cur_key_len);
		if(cur_key_len < key_size) return 0; // check if key is long enough
		switch(j) {
			case 1:
				// save this key as the decryption and encryption key
				if(!EVP_EncryptInit_ex(&ctxs[k].enc_ctx, out_cipher, NULL, cur_key, NULL)) return 0;
				if(!EVP_DecryptInit_ex(&ctxs[k].dec_ctx, out_cipher, NULL, cur_key, NULL)) return 0;
				break;
			case 2:
				// save this key as the hmac key
				HMAC_Init_ex(&ctxs[k].hmac_ctx, cur_key, cur_key_len, out_md, NULL);
				break;
			default:
				// throw this key away
				break;
		}
		if(j > 3) {
			j = 0;
			k++;
		}
		j++;
		i++;
	}
	
	// clean up
	HMAC_CTX_cleanup(&hmac_ctx);
	return 1;
}