mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-22 23:56:01 +00:00
fix a security issue
This commit is contained in:
+7
-7
@@ -512,7 +512,7 @@ static int priv_key_b58_to_address(const char *priv_key_b58,
|
||||
// -1 : invalid private key
|
||||
// 1 : compressed
|
||||
// 0 : uncompressed
|
||||
static int isCompressedAddress(const char *priv_key_b58, const char *address)
|
||||
static int isCompressedAddress(const char *priv_key_b58, const char *address, const size_t addr_len)
|
||||
{
|
||||
int is_compressed_pubkey;
|
||||
char buf[64];
|
||||
@@ -526,7 +526,7 @@ static int isCompressedAddress(const char *priv_key_b58, const char *address)
|
||||
if (res != 1) {
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(buf, address, strlen(address)) == 0) {
|
||||
if (memcmp(buf, address, addr_len) == 0) {
|
||||
return 1; // compressed
|
||||
}
|
||||
|
||||
@@ -538,7 +538,7 @@ static int isCompressedAddress(const char *priv_key_b58, const char *address)
|
||||
if (res != 1) {
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(buf, address, strlen(address)) == 0) {
|
||||
if (memcmp(buf, address, addr_len) == 0) {
|
||||
return 0; // uncompressed
|
||||
}
|
||||
|
||||
@@ -657,15 +657,15 @@ static int sign_message(uint8_t *signature_65,
|
||||
|
||||
int bitcoin_sign_message(unsigned char *buf_65,
|
||||
const void *msg, const size_t msg_len,
|
||||
const char *priv_key_b58, const char *address)
|
||||
const char *priv_key_b58, const char *address, const size_t addr_len)
|
||||
{
|
||||
int is_compressed = isCompressedAddress(priv_key_b58, address);
|
||||
int is_compressed = isCompressedAddress(priv_key_b58, address, addr_len);
|
||||
return sign_message(buf_65, (uint8_t *)msg, msg_len,
|
||||
priv_key_b58, is_compressed);
|
||||
}
|
||||
|
||||
int bitcoin_verify_message(const char *address, const unsigned char *sig,
|
||||
const void *msg, const size_t msglen)
|
||||
const void *msg, const size_t msglen, const size_t addr_len)
|
||||
{
|
||||
EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
uint8_t hash[32] = { 0 };
|
||||
@@ -693,7 +693,7 @@ int bitcoin_verify_message(const char *address, const unsigned char *sig,
|
||||
is_compressed_pubkey ?
|
||||
POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED,
|
||||
BITCOIN_ADDRESS_PREFIX_PUBKEY, ecprot);
|
||||
if (memcmp(address, ecprot, strlen(address)) == 0) {
|
||||
if (memcmp(address, ecprot, addr_len) == 0) {
|
||||
fOK = 1;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -26,10 +26,10 @@
|
||||
|
||||
extern int bitcoin_sign_message(unsigned char *buf_65,
|
||||
const void *msg, const size_t msg_len,
|
||||
const char *priv_key_b58, const char *address);
|
||||
const char *priv_key_b58, const char *address, const size_t addr_len);
|
||||
|
||||
extern int bitcoin_verify_message(const char *address, const unsigned char *sig_65,
|
||||
const void *msg, const size_t msglen);
|
||||
const void *msg, const size_t msg_len, const size_t addr_len);
|
||||
|
||||
struct btc_client;
|
||||
struct btc_list;
|
||||
|
||||
+8
-7
@@ -435,17 +435,17 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
if (bitcoin_address != NULL && bitcoin_privkey != NULL) {
|
||||
/*
|
||||
* bitcoin information:
|
||||
* +-----------+-----------+----------+
|
||||
* | Signature | Timestamp | Address |
|
||||
* +-----------+-----------+----------+
|
||||
* | 65 | 4 | String |
|
||||
* +-----------+-----------+----------+
|
||||
* +-----------+-----------+---------+-----------+
|
||||
* | Signature | Timestamp | AddLen | Address |
|
||||
* +-----------+-----------+---------+-----------+
|
||||
* | 65 | 4 | 1 | 26 - 35 |
|
||||
* +-----------+-----------+---------+-----------+
|
||||
*/
|
||||
uint32_t now = (uint32_t)time(NULL);
|
||||
uint8_t msg[4] = { (uint8_t)(now >> 24), (uint8_t)(now >> 16),
|
||||
(uint8_t)(now >> 8), (uint8_t)(now >> 0) };
|
||||
uint8_t sig[65] = { 0 }; // signature buf size always 65 bytes
|
||||
if (!bitcoin_sign_message(sig, msg, sizeof(msg), bitcoin_privkey, bitcoin_address)) {
|
||||
if (!bitcoin_sign_message(sig, msg, sizeof(msg), bitcoin_privkey, bitcoin_address, strlen(bitcoin_address))) {
|
||||
FATAL("bitcoin sign message fail");
|
||||
}
|
||||
size_t addr_len_ori = addr_len;
|
||||
@@ -453,9 +453,10 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
addr_len += 65;
|
||||
memcpy(ss_addr_to_send + addr_len, msg, sizeof(msg));
|
||||
addr_len += 4;
|
||||
ss_addr_to_send[addr_len] = (uint8_t)strlen(bitcoin_address);
|
||||
addr_len += 1;
|
||||
memcpy(ss_addr_to_send + addr_len, bitcoin_address, strlen(bitcoin_address));
|
||||
addr_len += strlen(bitcoin_address);
|
||||
ss_addr_to_send[addr_len++] = '\0';
|
||||
|
||||
bitcoin_len = addr_len - addr_len_ori;
|
||||
ss_addr_to_send[0] |= 0x10; // set bitcoin flag
|
||||
|
||||
+8
-7
@@ -568,17 +568,18 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
/*
|
||||
* bitcoin information:
|
||||
* +-----------+-----------+----------+
|
||||
* | Signature | Timestamp | Address |
|
||||
* +-----------+-----------+----------+
|
||||
* | 65 | 4 | String |
|
||||
* +-----------+-----------+----------+
|
||||
* +-----------+-----------+---------+-----------+
|
||||
* | Signature | Timestamp | AddLen | Address |
|
||||
* +-----------+-----------+---------+-----------+
|
||||
* | 65 | 4 | 1 | 26 - 35 |
|
||||
* +-----------+-----------+---------+-----------+
|
||||
*/
|
||||
char *signature = server->buf + offset;
|
||||
uint8_t *t = (uint8_t *)server->buf + offset + 65;
|
||||
uint32_t ts = ((uint32_t)*(t + 0) << 24) + ((uint32_t)*(t + 1) << 16)
|
||||
+ ((uint32_t)*(t + 2) << 8) + ((uint32_t)*(t + 3) << 0);
|
||||
char *address = server->buf + offset + 65 + 4;
|
||||
int addr_len = server->buf[offset + 64 + 4];
|
||||
char *address = server->buf + offset + 65 + 4 + 1;
|
||||
int64_t ts_offset = (int64_t)time(NULL) - (int64_t)ts;
|
||||
if (labs(ts_offset) > 60 * 30) {
|
||||
if (verbose) {
|
||||
@@ -588,7 +589,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
if (!bitcoin_verify_message(address, (uint8_t *)signature, t, 4)) {
|
||||
if (!bitcoin_verify_message(address, (uint8_t *)signature, t, 4, addr_len)) {
|
||||
if (verbose) {
|
||||
LOGE("invalid signature, address: %s", address);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user