コード例 #1
0
ファイル: auth.c プロジェクト: AbrahamJewowich/peervpn
// Decode auth message S3
static int authDecodeS3(struct s_auth_state *authstate, const unsigned char *msg, const int msg_len) {
	int msgnum;
	int decmsg_len;
	unsigned char decmsg[auth_MAXMSGSIZE_S3];
	if(msg_len > 6) {
		memcpy(decmsg, msg, 6);
		msgnum = utilReadInt16(&decmsg[4]);
		if(msgnum == (authstate->state + 1)) {
			decmsg_len = (4 + 2 + cryptoDec(&authstate->crypto_ctx[auth_CRYPTOCTX_CNEG], &decmsg[(4 + 2)], (auth_MAXMSGSIZE_S3 - 2 - 4), &msg[(4 + 2)], (msg_len - 2 - 4), auth_CNEGHMACSIZE, auth_CNEGIVSIZE));
			if(decmsg_len >= (4 + 2 + auth_NONCESIZE + seq_SIZE + 4 + 8)) {
				memcpy(authstate->remote_keygen_nonce, &decmsg[(4 + 2)], auth_NONCESIZE);
				if((msgnum % 2) == 0) {
					memcpy(&authstate->keygen_nonce[0], authstate->local_keygen_nonce, auth_NONCESIZE);
					memcpy(&authstate->keygen_nonce[auth_NONCESIZE], authstate->remote_keygen_nonce, auth_NONCESIZE);
				}
				else {
					memcpy(&authstate->keygen_nonce[0], authstate->remote_keygen_nonce, auth_NONCESIZE);
					memcpy(&authstate->keygen_nonce[auth_NONCESIZE], authstate->local_keygen_nonce, auth_NONCESIZE);
				}
				memcpy(authstate->remote_seq, &decmsg[(4 + 2 + auth_NONCESIZE)], seq_SIZE);
				authstate->remote_peerid = utilReadInt32(&decmsg[(4 + 2 + auth_NONCESIZE + seq_SIZE)]);
				memcpy(authstate->remote_flags, &decmsg[(4 + 2 + auth_NONCESIZE + seq_SIZE + 4)], 8);
				return 1;
			}
		}
	}
	return 0;
}
コード例 #2
0
ファイル: packet.c プロジェクト: Ragsboss/peervpn
// decode packet
static int packetDecode(struct s_packet_data *data, const unsigned char *pbuf, const int pbuf_size, struct s_crypto *ctx, struct s_seq_state *seqstate) {
	unsigned char dec_buf[pbuf_size];
	int len;

	// decrypt packet
	if(pbuf_size < (packet_PEERID_SIZE + packet_HMAC_SIZE + packet_IV_SIZE)) { return 0; }
	len = cryptoDec(ctx, dec_buf, pbuf_size, &pbuf[packet_PEERID_SIZE], (pbuf_size - packet_PEERID_SIZE), packet_HMAC_SIZE, packet_IV_SIZE);
	if(len < packet_CRHDR_SIZE) { return 0; };

	// get packet data
	data->peerid = packetGetPeerID(pbuf);
	data->seq = utilReadInt64(&dec_buf[packet_CRHDR_SEQ_START]);
	if(seqstate != NULL) if(!seqVerify(seqstate, data->seq)) { return 0; }
	data->pl_options = dec_buf[packet_CRHDR_PLOPT_START];
	data->pl_type = dec_buf[packet_CRHDR_PLTYPE_START];
	data->pl_length = utilReadInt16(&dec_buf[packet_CRHDR_PLLEN_START]);
	if(!(data->pl_length > 0)) {
		data->pl_length = 0;
		return 0;
	}
	if(len < (packet_CRHDR_SIZE + data->pl_length)) { return 0; }
	if(data->pl_length > data->pl_buf_size) { return 0; }
	memcpy(data->pl_buf, &dec_buf[packet_CRHDR_SIZE], data->pl_length);

	// return length of decoded payload
	return (data->pl_length);
}
コード例 #3
0
ファイル: auth.c プロジェクト: AbrahamJewowich/peervpn
// Decode auth message S2
static int authDecodeS2(struct s_auth_state *authstate, const unsigned char *msg, const int msg_len) {
	int msgnum;
	int nksize;
	int signsize;
	int decmsg_len;
	unsigned char hmac[auth_HMACSIZE];
	unsigned char siginbuf[auth_SIGINBUFSIZE];
	unsigned char decmsg[auth_MAXMSGSIZE_S2];
	int siginbuf_size;
	if(msg_len > 10) {
		memcpy(decmsg, msg, 6);
		msgnum = utilReadInt16(&decmsg[4]);
		if(msgnum == (authstate->state + 1)) {
			decmsg_len = (4 + 2 + cryptoDec(&authstate->crypto_ctx[auth_CRYPTOCTX_IDP], &decmsg[(4 + 2)], (auth_MAXMSGSIZE_S2 - 2 - 4), &msg[(4 + 2)], (msg_len - 2 - 4), auth_IDPHMACSIZE, auth_IDPIVSIZE)); // decrypt IDP layer
			if(decmsg_len > 10) {
				nksize = utilReadInt16(&decmsg[(4 + 2)]);
				if((nksize > nodekey_MINSIZE) && (decmsg_len > (10 + nksize))) {
					signsize = utilReadInt16(&decmsg[(4 + 4 + nksize)]);
					if((signsize > 0) && (decmsg_len >= (10 + nksize + signsize + auth_HMACSIZE))) { // check message length
						if(cryptoHMAC(&authstate->crypto_ctx[auth_CRYPTOCTX_AUTH], hmac, auth_HMACSIZE, &decmsg[(4 + 4)], nksize)) { // generate HMAC tag
							if(memcmp(&decmsg[(10 + nksize + signsize)], hmac, auth_HMACSIZE) == 0) { // verify HMAC tag
								if(nodekeyLoadDER(&authstate->remote_nodekey, &decmsg[(4 + 4)], nksize)) { // load remote public key
									if(memcmp(authstate->remote_nodekey.nodeid.id, authstate->local_nodekey->nodeid.id, nodeid_SIZE) != 0) { // check if remote public key is different from local public key
										siginbuf_size = authGenRemoteSigIn(authstate, siginbuf, &decmsg[4]);
										if(rsaVerify(&authstate->remote_nodekey.key, &decmsg[(10 + nksize)], signsize, siginbuf, siginbuf_size)) { // verify signature
											return 1;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	return 0;
}