cscvs to tla changeset 41
[onak.git] / keyid.c
1 /*
2  * keyid.c - Routines to calculate key IDs.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2002 Project Purple
7  */
8
9 #include <sys/types.h>
10
11 #include "keyid.h"
12 #include "keystructs.h"
13 #include "md5.h"
14 #include "sha.h"
15
16
17 /**
18  *      get_keyid - Given a public key returns the keyid.
19  *      @publickey: The key to calculate the id for.
20  */
21 uint64_t get_keyid(struct openpgp_publickey *publickey)
22 {
23         return (get_packetid(publickey->publickey));
24 }
25
26 /**
27  *      get_packetid - Given a PGP packet returns the keyid.
28  *      @packet: The packet to calculate the id for.
29  */
30 uint64_t get_packetid(struct openpgp_packet *packet)
31 {
32         SHA1_CONTEXT sha_ctx;
33         uint64_t keyid = 0;
34         int offset = 0;
35         int i = 0;
36         unsigned char c;
37         unsigned char *buff = NULL;
38
39         assert(packet != NULL);
40
41         switch (packet->data[0]) {
42         case 2:
43         case 3:
44                 /*
45                  * For a type 2 or 3 key the keyid is the last 64 bits of the
46                  * public modulus n, which is stored as an MPI from offset 8
47                  * onwards.
48                  *
49                  * We need to ensure it's an RSA key.
50                  */
51                 if (packet->data[7] == 1) {
52                         offset = (packet->data[8] << 8) +
53                                 packet->data[9];
54                         offset = ((offset + 7) / 8) + 2;
55
56                         for (keyid = 0, i = 0; i < 8; i++) {
57                                 keyid <<= 8;
58                                 keyid += packet->data[offset++];
59                         }
60                 } else {
61                         fputs("Type 2 or 3 key, but not RSA.\n", stderr);
62                 }
63                 break;
64         case 4:
65                 /*
66                  * For a type 4 key the keyid is the last 64 bits of the
67                  * fingerprint, which is the 160 bit SHA-1 hash of the packet
68                  * tag, 2 octet packet length and the public key packet
69                  * including version field.
70                  */
71                 sha1_init(&sha_ctx);
72                 /*
73                  * TODO: Can this be 0x99? Are all public key packets old
74                  * format with 2 bytes of length data?
75                  */
76                 c = 0x99;
77                 sha1_write(&sha_ctx, &c, sizeof(c));
78                 c = packet->length >> 8;
79                 sha1_write(&sha_ctx, &c, sizeof(c));
80                 c = packet->length & 0xFF;
81                 sha1_write(&sha_ctx, &c, sizeof(c));
82                 sha1_write(&sha_ctx, packet->data,
83                         packet->length);
84                 sha1_final(&sha_ctx);
85                 buff = sha1_read(&sha_ctx);
86
87                 assert(buff != NULL);
88                 
89                 for (keyid = 0, i = 12; i < 20; i++) {
90                         keyid <<= 8;
91                         keyid += buff[i];
92                 }
93
94                 break;
95         default:
96                 fprintf(stderr, "Unknown key type: %d\n",
97                                 packet->data[0]);
98         }
99
100         return keyid;
101 }