Fix SEGV bug in keyring_enter_pin()

The public and private key length fields were stored as 'int' not
'unsigned', so arithmetic for checking buffer overrun was not correct.
This commit is contained in:
Andrew Bettison 2013-03-06 14:02:33 +10:30
parent 226fcf3754
commit 705f414a4d
2 changed files with 16 additions and 11 deletions

View File

@ -638,14 +638,21 @@ int keyring_identity_mac(keyring_context *c,keyring_identity *id,
{
int ofs;
unsigned char work[65536];
#define APPEND(b,l) if (ofs+(l)>=65536) { bzero(work,ofs); return WHY("Input too long"); } bcopy((b),&work[ofs],(l)); ofs+=(l)
#define APPEND(buf, len) { \
unsigned __len = (len); \
if (ofs + __len >= sizeof work) { \
bzero(work, ofs); \
return WHY("Input too long"); \
} \
bcopy((buf), &work[ofs], __len); \
ofs += __len; \
}
ofs=0;
APPEND(&pkrsalt[0],32);
APPEND(id->keypairs[0]->private_key,id->keypairs[0]->private_key_len);
APPEND(id->keypairs[0]->public_key,id->keypairs[0]->public_key_len);
APPEND(id->PKRPin,strlen(id->PKRPin));
crypto_hash_sha512(mac,work,ofs);
APPEND(&pkrsalt[0], 32);
APPEND(id->keypairs[0]->private_key, id->keypairs[0]->private_key_len);
APPEND(id->keypairs[0]->public_key, id->keypairs[0]->public_key_len);
APPEND(id->PKRPin, strlen(id->PKRPin));
crypto_hash_sha512(mac, work, ofs);
return 0;
}
@ -662,7 +669,6 @@ int keyring_decrypt_pkr(keyring_file *k,keyring_context *c,
int exit_code=1;
unsigned char slot[KEYRING_PAGE_SIZE];
unsigned char hash[crypto_hash_sha512_BYTES];
unsigned char work[65536];
keyring_identity *id=NULL;
/* 1. Read slot. */
@ -727,7 +733,6 @@ int keyring_decrypt_pkr(keyring_file *k,keyring_context *c,
/* Clean up any potentially sensitive data before exiting */
bzero(slot,KEYRING_PAGE_SIZE);
bzero(hash,crypto_hash_sha512_BYTES);
bzero(&work[0],65536);
if (id) keyring_free_identity(id); id=NULL;
return exit_code;
}

View File

@ -195,9 +195,9 @@ struct decode_context;
typedef struct keypair {
int type;
unsigned char *private_key;
int private_key_len;
unsigned private_key_len;
unsigned char *public_key;
int public_key_len;
unsigned public_key_len;
} keypair;
/* Contains just the list of private:public key pairs and types,