mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 03:50:57 +01:00
fixed integer overflows when importing keys with invalid header sizes (or invalid headers, that is)
This commit is contained in:
@@ -246,6 +246,7 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras
|
|||||||
/* helpers */
|
/* helpers */
|
||||||
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h);
|
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h);
|
||||||
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk);
|
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk);
|
||||||
|
int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader);
|
||||||
|
|
||||||
#endif // _HAVE_PCP_MGMT_H
|
#endif // _HAVE_PCP_MGMT_H
|
||||||
|
|
||||||
|
|||||||
@@ -42,37 +42,42 @@ int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) {
|
|||||||
h->numsubs = be16toh(h->numsubs);
|
h->numsubs = be16toh(h->numsubs);
|
||||||
|
|
||||||
if(h->version != EXP_SIG_VERSION) {
|
if(h->version != EXP_SIG_VERSION) {
|
||||||
fatal(ptx, "Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION);
|
fatal(ptx, "Unsupported pubkey signature version %d, expected %d\n", h->version, EXP_SIG_VERSION);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->type != EXP_SIG_TYPE) {
|
if(h->type != EXP_SIG_TYPE) {
|
||||||
fatal(ptx, "Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE);
|
fatal(ptx, "Unsupported pubkey signature type %d, expected %d\n", h->type, EXP_SIG_TYPE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->pkcipher != EXP_SIG_CIPHER) {
|
if(h->pkcipher != EXP_SIG_CIPHER) {
|
||||||
fatal(ptx, "Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER);
|
fatal(ptx, "Unsupported pubkey signature cipher %d, expected %d\n", h->pkcipher, EXP_SIG_CIPHER);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->hashcipher != EXP_HASH_CIPHER) {
|
if(h->hashcipher != EXP_HASH_CIPHER) {
|
||||||
fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER);
|
fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d\n", h->hashcipher, EXP_HASH_CIPHER);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) {
|
if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) {
|
||||||
fatal(ptx, "Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld",
|
fatal(ptx, "Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld\n",
|
||||||
sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs);
|
sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal(ptx, "Error: input data too small, import failed");
|
fatal(ptx, "Error: input data too small, import failed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
|
int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
|
||||||
byte *ignore = ucmalloc(32);
|
byte *ignore = ucmalloc(32);
|
||||||
|
|
||||||
|
if(subheader->size > buffer_left(blob)) {
|
||||||
|
fatal(ptx, "Invalid header size %ld specified in source\n", subheader->size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(subheader->type == EXP_SIG_SUB_NOTATION) {
|
if(subheader->type == EXP_SIG_SUB_NOTATION) {
|
||||||
/* mail or owner */
|
/* mail or owner */
|
||||||
uint16_t nsize = buffer_get16na(blob);
|
uint16_t nsize = buffer_get16na(blob);
|
||||||
@@ -80,19 +85,35 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
|
|||||||
|
|
||||||
char *notation = ucmalloc(nsize+1);
|
char *notation = ucmalloc(nsize+1);
|
||||||
|
|
||||||
if(buffer_get_chunk(blob, notation, nsize) == 0)
|
if(nsize > buffer_left(blob)) {
|
||||||
|
fatal(ptx, "Invalid notation size %ld specified in source\n", nsize);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer_get_chunk(blob, notation, nsize) == 0) {
|
||||||
|
fatal(ptx, "Invalid notation size, expected %ld bytes, but got 0\n", nsize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
notation[nsize] = '\0';
|
notation[nsize] = '\0';
|
||||||
|
|
||||||
if(strncmp(notation, "owner", 5) == 0) {
|
if(vsize > buffer_left(blob)) {
|
||||||
if(buffer_get_chunk(blob, p->owner, vsize) == 0)
|
fatal(ptx, "Invalid notation value size %ld specified in source\n", vsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(strncmp(notation, "mail", 4) == 0) {
|
|
||||||
if(buffer_get_chunk(blob, p->mail, vsize) == 0)
|
if(strncmp(notation, "owner", 5) == 0) {
|
||||||
|
if(buffer_get_chunk(blob, p->owner, vsize) == 0) {
|
||||||
|
fatal(ptx, "Invalid 'owner' notation, expected %ld bytes, but got 0\n", vsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if(strncmp(notation, "mail", 4) == 0) {
|
||||||
|
if(buffer_get_chunk(blob, p->mail, vsize) == 0) {
|
||||||
|
fatal(ptx, "Invalid 'mail' notation, expected %ld bytes, but got 0\n", vsize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(strncmp(notation, "serial", 6) == 0) {
|
else if(strncmp(notation, "serial", 6) == 0) {
|
||||||
p->serial = buffer_get32na(blob);
|
p->serial = buffer_get32na(blob);
|
||||||
}
|
}
|
||||||
@@ -100,9 +121,11 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* unsupported or ignored sig sub */
|
/* unsupported or ignored sig sub */
|
||||||
if(buffer_get_chunk(blob, ignore, subheader->size) == 0)
|
if(buffer_get_chunk(blob, ignore, subheader->size) == 0) {
|
||||||
|
fatal(ptx, "Invalid 'unsupported' notation, expected %ld bytes, but got 0\n", subheader->size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -245,7 +268,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
|
|||||||
if(buffer_done(blob)) goto be;
|
if(buffer_done(blob)) goto be;
|
||||||
|
|
||||||
if(pkcipher != EXP_PK_CIPHER) {
|
if(pkcipher != EXP_PK_CIPHER) {
|
||||||
fatal(ptx, "Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER);
|
fatal(ptx, "Unsupported pk cipher %d, expected %d\n", pkcipher, EXP_PK_CIPHER);
|
||||||
goto bef;
|
goto bef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +285,8 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
|
|||||||
for (i=0; i<sigheader->numsubs; i++) {
|
for (i=0; i<sigheader->numsubs; i++) {
|
||||||
subheader->size = buffer_get32na(blob);
|
subheader->size = buffer_get32na(blob);
|
||||||
subheader->type = buffer_get8(blob);
|
subheader->type = buffer_get8(blob);
|
||||||
_check_sigsubs(blob, p, subheader);
|
if(_check_sigsubs(ptx, blob, p, subheader) != 0)
|
||||||
|
goto bes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calc id */
|
/* calc id */
|
||||||
@@ -290,7 +314,9 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
|
|||||||
|
|
||||||
|
|
||||||
be:
|
be:
|
||||||
fatal(ptx, "Error: input data too small, import failed");
|
fatal(ptx, "Error: input data too small, import failed\n");
|
||||||
|
|
||||||
|
bes:
|
||||||
|
|
||||||
bef:
|
bef:
|
||||||
buffer_free(blob);
|
buffer_free(blob);
|
||||||
|
|||||||
Reference in New Issue
Block a user