From b3c67e7383ef6ece55dcf6fbfa9587f5d0a14546 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Tue, 30 Jul 2019 15:32:34 -0300 Subject: [PATCH] Add more generic OID parsing to decodekey Rather than only parsing the encoded OID to calculate the key size make a helper function in decodekey and use that. This will be useful when trying to parse key material for signature checks. --- decodekey.c | 79 ++++++++++++++++++++++++++++++++++++++++++ decodekey.h | 16 +++++++++ keyindex.c | 99 +++++++---------------------------------------------- 3 files changed, 107 insertions(+), 87 deletions(-) diff --git a/decodekey.c b/decodekey.c index 28f8cee..481b8aa 100644 --- a/decodekey.c +++ b/decodekey.c @@ -354,3 +354,82 @@ struct openpgp_fingerprint *keysubkeys(struct openpgp_publickey *key) return subkeys; } + +enum onak_oid onak_parse_oid(uint8_t *buf, size_t len) +{ + enum onak_oid oid; + + /* Elliptic curve key size is based on OID */ + if (len == 0 || (buf[0] >= len)) { + oid = ONAK_OID_INVALID; + /* Curve25519 / 1.3.6.1.4.1.3029.1.5.1 */ + } else if ((buf[0] == 10) && + (buf[1] == 0x2B) && (buf[2] == 0x06) && + (buf[3] == 0x01) && (buf[4] == 0x04) && + (buf[5] == 0x01) && (buf[6] == 0x97) && + (buf[7] == 0x55) && (buf[8] == 0x01) && + (buf[9] == 0x05) && (buf[10] == 0x01)) { + oid = ONAK_OID_CURVE25519; + /* Ed25519 / 1.3.6.1.4.1.11591.15.1 */ + } else if ((buf[0] == 9) && + (buf[1] == 0x2B) && (buf[2] == 0x06) && + (buf[3] == 0x01) && (buf[4] == 0x04) && + (buf[5] == 0x01) && (buf[6] == 0xDA) && + (buf[7] == 0x47) && (buf[8] == 0x0F) && + (buf[9] == 0x01)) { + oid = ONAK_OID_ED25519; + /* nistp256 / 1.2.840.10045.3.1.7 */ + } else if ((buf[0] == 8) && + (buf[1] == 0x2A) && (buf[2] == 0x86) && + (buf[3] == 0x48) && (buf[4] == 0xCE) && + (buf[5] == 0x3D) && (buf[6] == 0x03) && + (buf[7] == 0x01) && (buf[8] == 0x07)) { + oid = ONAK_OID_NISTP256; + /* nistp384 / 1.3.132.0.34 */ + } else if ((buf[0] == 5) && + (buf[1] == 0x2B) && (buf[2] == 0x81) && + (buf[3] == 0x04) && (buf[4] == 0x00) && + (buf[5] == 0x22)) { + oid = ONAK_OID_NISTP384; + /* nistp521 / 1.3.132.0.35 */ + } else if ((buf[0] == 5) && + (buf[1] == 0x2B) && (buf[2] == 0x81) && + (buf[3] == 0x04) && (buf[4] == 0x00) && + (buf[5] == 0x23)) { + oid = ONAK_OID_NISTP521; + /* brainpoolP256r1 / 1.3.36.3.3.2.8.1.1.7 */ + } else if ((buf[0] == 9) && + (buf[1] == 0x2B) && (buf[2] == 0x24) && + (buf[3] == 0x03) && (buf[4] == 0x03) && + (buf[5] == 0x02) && (buf[6] == 0x08) && + (buf[7] == 0x01) && (buf[8] == 0x01) && + (buf[9] == 0x07)) { + oid = ONAK_OID_BRAINPOOLP256R1; + /* brainpoolP384r1 / 1.3.36.3.3.2.8.1.1.11 */ + } else if ((buf[0] == 9) && + (buf[1] == 0x2B) && (buf[2] == 0x24) && + (buf[3] == 0x03) && (buf[4] == 0x03) && + (buf[5] == 0x02) && (buf[6] == 0x08) && + (buf[7] == 0x01) && (buf[8] == 0x01) && + (buf[9] == 0x0B)) { + oid = ONAK_OID_BRAINPOOLP384R1; + /* brainpoolP512r1 / 1.3.36.3.3.2.8.1.1.13 */ + } else if ((buf[0] == 9) && + (buf[1] == 0x2B) && (buf[2] == 0x24) && + (buf[3] == 0x03) && (buf[4] == 0x03) && + (buf[5] == 0x02) && (buf[6] == 0x08) && + (buf[7] == 0x01) && (buf[8] == 0x01) && + (buf[9] == 0x0D)) { + oid = ONAK_OID_BRAINPOOLP512R1; + /* secp256k1 / 1.3.132.0.10 */ + } else if ((buf[0] == 5) && + (buf[1] == 0x2B) && (buf[2] == 0x81) && + (buf[3] == 0x04) && (buf[4] == 0x00) && + (buf[5] == 0x0A)) { + oid = ONAK_OID_SECP256K1; + } else { + oid = ONAK_OID_UNKNOWN; + } + + return oid; +} diff --git a/decodekey.h b/decodekey.h index 24d5ece..5eb78d1 100644 --- a/decodekey.h +++ b/decodekey.h @@ -93,4 +93,20 @@ struct openpgp_fingerprint *keysubkeys(struct openpgp_publickey *key); onak_status_t parse_subpackets(unsigned char *data, size_t len, size_t *parselen, uint64_t *keyid, time_t *creation); +enum onak_oid { + ONAK_OID_UNKNOWN = 0, + ONAK_OID_INVALID, + ONAK_OID_CURVE25519, + ONAK_OID_ED25519, + ONAK_OID_NISTP256, + ONAK_OID_NISTP384, + ONAK_OID_NISTP521, + ONAK_OID_BRAINPOOLP256R1, + ONAK_OID_BRAINPOOLP384R1, + ONAK_OID_BRAINPOOLP512R1, + ONAK_OID_SECP256K1, +}; + +enum onak_oid onak_parse_oid(uint8_t *buf, size_t len); + #endif diff --git a/keyindex.c b/keyindex.c index f6784d7..eeac56c 100644 --- a/keyindex.c +++ b/keyindex.c @@ -81,6 +81,7 @@ unsigned int keylength(struct openpgp_packet *keydata) { unsigned int length; uint8_t keyofs; + enum onak_oid oid; switch (keydata->data[0]) { case 2: @@ -97,101 +98,25 @@ unsigned int keylength(struct openpgp_packet *keydata) case OPENPGP_PKALGO_ECDSA: case OPENPGP_PKALGO_EDDSA: /* Elliptic curve key size is based on OID */ - /* Curve25519 / 1.3.6.1.4.1.3029.1.5.1 */ - if ((keydata->data[keyofs] == 10) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x06) && - (keydata->data[keyofs + 3] == 0x01) && - (keydata->data[keyofs + 4] == 0x04) && - (keydata->data[keyofs + 5] == 0x01) && - (keydata->data[keyofs + 6] == 0x97) && - (keydata->data[keyofs + 7] == 0x55) && - (keydata->data[keyofs + 8] == 0x01) && - (keydata->data[keyofs + 9] == 0x05) && - (keydata->data[keyofs + 10] == 0x01)) { + oid = onak_parse_oid(&keydata->data[keyofs], + keydata->length - keyofs); + if (oid == ONAK_OID_CURVE25519) { length = 255; - /* Ed25519 / 1.3.6.1.4.1.11591.15.1 */ - } else if ((keydata->data[keyofs] == 9) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x06) && - (keydata->data[keyofs + 3] == 0x01) && - (keydata->data[keyofs + 4] == 0x04) && - (keydata->data[keyofs + 5] == 0x01) && - (keydata->data[keyofs + 6] == 0xDA) && - (keydata->data[keyofs + 7] == 0x47) && - (keydata->data[keyofs + 8] == 0x0F) && - (keydata->data[keyofs + 9] == 0x01)) { + } else if (oid == ONAK_OID_ED25519) { length = 255; - /* nistp256 / 1.2.840.10045.3.1.7 */ - } else if ((keydata->data[keyofs] == 8) && - (keydata->data[keyofs + 1] == 0x2A) && - (keydata->data[keyofs + 2] == 0x86) && - (keydata->data[keyofs + 3] == 0x48) && - (keydata->data[keyofs + 4] == 0xCE) && - (keydata->data[keyofs + 5] == 0x3D) && - (keydata->data[keyofs + 6] == 0x03) && - (keydata->data[keyofs + 7] == 0x01) && - (keydata->data[keyofs + 8] == 0x07)) { + } else if (oid == ONAK_OID_NISTP256) { length = 256; - /* nistp384 / 1.3.132.0.34 */ - } else if ((keydata->data[keyofs] == 5) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x81) && - (keydata->data[keyofs + 3] == 0x04) && - (keydata->data[keyofs + 4] == 0x00) && - (keydata->data[keyofs + 5] == 0x22)) { + } else if (oid == ONAK_OID_NISTP384) { length = 384; - /* nistp521 / 1.3.132.0.35 */ - } else if ((keydata->data[keyofs] == 5) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x81) && - (keydata->data[keyofs + 3] == 0x04) && - (keydata->data[keyofs + 4] == 0x00) && - (keydata->data[keyofs + 5] == 0x23)) { + } else if (oid == ONAK_OID_NISTP521) { length = 521; - /* brainpoolP256r1 / 1.3.36.3.3.2.8.1.1.7 */ - } else if ((keydata->data[keyofs] == 9) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x24) && - (keydata->data[keyofs + 3] == 0x03) && - (keydata->data[keyofs + 4] == 0x03) && - (keydata->data[keyofs + 5] == 0x02) && - (keydata->data[keyofs + 6] == 0x08) && - (keydata->data[keyofs + 7] == 0x01) && - (keydata->data[keyofs + 8] == 0x01) && - (keydata->data[keyofs + 9] == 0x07)) { + } else if (oid == ONAK_OID_BRAINPOOLP256R1) { length = 256; - /* brainpoolP384r1 / 1.3.36.3.3.2.8.1.1.11 */ - } else if ((keydata->data[keyofs] == 9) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x24) && - (keydata->data[keyofs + 3] == 0x03) && - (keydata->data[keyofs + 4] == 0x03) && - (keydata->data[keyofs + 5] == 0x02) && - (keydata->data[keyofs + 6] == 0x08) && - (keydata->data[keyofs + 7] == 0x01) && - (keydata->data[keyofs + 8] == 0x01) && - (keydata->data[keyofs + 9] == 0x0B)) { + } else if (oid == ONAK_OID_BRAINPOOLP384R1) { length = 384; - /* brainpoolP512r1 / 1.3.36.3.3.2.8.1.1.13 */ - } else if ((keydata->data[keyofs] == 9) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x24) && - (keydata->data[keyofs + 3] == 0x03) && - (keydata->data[keyofs + 4] == 0x03) && - (keydata->data[keyofs + 5] == 0x02) && - (keydata->data[keyofs + 6] == 0x08) && - (keydata->data[keyofs + 7] == 0x01) && - (keydata->data[keyofs + 8] == 0x01) && - (keydata->data[keyofs + 9] == 0x0D)) { + } else if (oid == ONAK_OID_BRAINPOOLP512R1) { length = 512; - /* secp256k1 / 1.3.132.0.10 */ - } else if ((keydata->data[keyofs] == 5) && - (keydata->data[keyofs + 1] == 0x2B) && - (keydata->data[keyofs + 2] == 0x81) && - (keydata->data[keyofs + 3] == 0x04) && - (keydata->data[keyofs + 4] == 0x00) && - (keydata->data[keyofs + 5] == 0x0A)) { + } else if (oid == ONAK_OID_SECP256K1) { length = 256; } else { logthing(LOGTHING_ERROR, -- 2.39.2