X-Git-Url: https://the.earth.li/gitweb/?a=blobdiff_plain;f=keyid.c;h=d5244943f8e0c4480294900ad02c8577dc0b1fa2;hb=5719b2b50c87d77e4ed1cc054f000845fc9aa8cc;hp=d114852bd3081b2f44da24fd785ccce3bada8dfe;hpb=e0dd4d10f385cd19da389ec66622eea8aa66ae59;p=onak.git diff --git a/keyid.c b/keyid.c index d114852..d524494 100644 --- a/keyid.c +++ b/keyid.c @@ -13,8 +13,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * this program. If not, see . */ #include @@ -31,12 +30,26 @@ #ifdef HAVE_NETTLE #include +#include #include #else #include "md5.h" #include "sha1.h" #endif +uint64_t fingerprint2keyid(struct openpgp_fingerprint *fingerprint) +{ + uint64_t keyid; + int i; + + for (keyid = 0, i = 12; i < 20; i++) { + keyid <<= 8; + keyid += fingerprint->fp[i]; + } + + return keyid; +} + /** * get_keyid - Given a public key returns the keyid. @@ -58,8 +71,7 @@ onak_status_t get_keyid(struct openpgp_publickey *publickey, uint64_t *keyid) * which we've returned. */ onak_status_t get_fingerprint(struct openpgp_packet *packet, - unsigned char *fingerprint, - size_t *len) + struct openpgp_fingerprint *fingerprint) { struct sha1_ctx sha_ctx; struct md5_ctx md5_context; @@ -68,10 +80,8 @@ onak_status_t get_fingerprint(struct openpgp_packet *packet, if (fingerprint == NULL) return ONAK_E_INVALID_PARAM; - if (len == NULL) - return ONAK_E_INVALID_PARAM; - *len = 0; + fingerprint->length = 0; switch (packet->data[0]) { case 2: @@ -89,8 +99,8 @@ onak_status_t get_fingerprint(struct openpgp_packet *packet, packet->data[11+modlen] + 7) >> 3; md5_update(&md5_context, explen, &packet->data[12 + modlen]); - *len = 16; - md5_digest(&md5_context, *len, fingerprint); + fingerprint->length = 16; + md5_digest(&md5_context, fingerprint->length, fingerprint->fp); break; @@ -108,8 +118,8 @@ onak_status_t get_fingerprint(struct openpgp_packet *packet, sha1_update(&sha_ctx, sizeof(c), &c); sha1_update(&sha_ctx, packet->length, packet->data); - *len = 20; - sha1_digest(&sha_ctx, *len, fingerprint); + fingerprint->length = 20; + sha1_digest(&sha_ctx, fingerprint->length, fingerprint->fp); break; default: @@ -128,15 +138,56 @@ onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid) { int offset = 0; int i = 0; - size_t length = 0; - unsigned char buff[20]; + struct openpgp_fingerprint fingerprint; +#ifdef NETTLE_WITH_RIPEMD160 + struct ripemd160_ctx ripemd160_context; + uint8_t data; +#endif - if (packet == NULL) + if (packet == NULL || packet->data == NULL) return ONAK_E_INVALID_PARAM; switch (packet->data[0]) { case 2: case 3: + /* + * Old versions of GnuPG would put Elgamal keys inside + * a V3 key structure, then generate the keyid using + * RIPED160. + */ +#ifdef NETTLE_WITH_RIPEMD160 + if (packet->data[7] == 16) { + ripemd160_init(&ripemd160_context); + data = 0x99; + ripemd160_update(&ripemd160_context, 1, &data); + data = packet->length >> 8; + ripemd160_update(&ripemd160_context, 1, &data); + data = packet->length & 0xFF; + ripemd160_update(&ripemd160_context, 1, &data); + ripemd160_update(&ripemd160_context, + packet->length, + packet->data); + + ripemd160_digest(&ripemd160_context, + RIPEMD160_DIGEST_SIZE, + fingerprint.fp); + fingerprint.length = RIPEMD160_DIGEST_SIZE; + + *keyid = fingerprint2keyid(&fingerprint); + + return ONAK_E_OK; + } +#endif + /* + * Check for an RSA key; if not return an error. + * 1 == RSA + * 2 == RSA Encrypt-Only + * 3 == RSA Sign-Only + */ + if (packet->data[7] < 1 || packet->data[7] > 3) { + return ONAK_E_INVALID_PKT; + } + /* * For a type 2 or 3 key the keyid is the last 64 bits of the * public modulus n, which is stored as an MPI from offset 8 @@ -150,23 +201,11 @@ onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid) *keyid <<= 8; *keyid += packet->data[offset++]; } - /* - * Check for an RSA key; if not return an error. - * 1 == RSA - * 2 == RSA Encrypt-Only - * 3 == RSA Sign-Only - */ - if (packet->data[7] < 1 || packet->data[7] > 3) { - return ONAK_E_INVALID_PKT; - } break; case 4: - get_fingerprint(packet, buff, &length); - - for (*keyid = 0, i = 12; i < 20; i++) { - *keyid <<= 8; - *keyid += buff[i]; - } + get_fingerprint(packet, &fingerprint); + + *keyid = fingerprint2keyid(&fingerprint); break; default: