1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
#include "system.h"
#include <rpm/rpmstring.h>
#include <rpm/rpmpgp.h>
#include <rpm/rpmfileutil.h>
#include <rpm/rpmlog.h>
#include <rpm/rpmkeyring.h>
#include "rpmio/base64.h"
#include "rpmio/digest.h"
#include "debug.h"
struct rpmPubkey_s {
uint8_t *pkt;
size_t pktlen;
pgpKeyID_t keyid;
};
struct rpmKeyring_s {
struct rpmPubkey_s **keys;
size_t numkeys;
};
static int keyidcmp(const void *k1, const void *k2)
{
const struct rpmPubkey_s *key1 = *(const struct rpmPubkey_s **) k1;
const struct rpmPubkey_s *key2 = *(const struct rpmPubkey_s **) k2;
return memcmp(key1->keyid, key2->keyid, sizeof(key1->keyid));
}
rpmKeyring rpmKeyringNew(void)
{
rpmKeyring keyring = xcalloc(1, sizeof(*keyring));
keyring->keys = NULL;
keyring->numkeys = 0;
return keyring;
}
rpmKeyring rpmKeyringFree(rpmKeyring keyring)
{
if (keyring && keyring->keys) {
for (int i = 0; i < keyring->numkeys; i++) {
keyring->keys[i] = rpmPubkeyFree(keyring->keys[i]);
}
free(keyring->keys);
}
free(keyring);
return NULL;
}
static rpmPubkey rpmKeyringFindKeyid(rpmKeyring keyring, rpmPubkey key)
{
rpmPubkey *found = NULL;
found = bsearch(&key, keyring->keys, keyring->numkeys, sizeof(*keyring->keys), keyidcmp);
return found ? *found : NULL;
}
int rpmKeyringAddKey(rpmKeyring keyring, rpmPubkey key)
{
if (keyring == NULL || key == NULL)
return -1;
/* check if we already have this key */
if (rpmKeyringFindKeyid(keyring, key)) {
return 1;
}
keyring->keys = xrealloc(keyring->keys, (keyring->numkeys + 1) * sizeof(rpmPubkey));
keyring->keys[keyring->numkeys] = key;
keyring->numkeys++;
qsort(keyring->keys, keyring->numkeys, sizeof(*keyring->keys), keyidcmp);
return 0;
}
rpmPubkey rpmPubkeyRead(const char *filename)
{
uint8_t *pkt = NULL;
size_t pktlen;
rpmPubkey key = NULL;
if (pgpReadPkts(filename, &pkt, &pktlen) <= 0) {
goto exit;
}
key = rpmPubkeyNew(pkt, pktlen);
free(pkt);
exit:
return key;
}
rpmPubkey rpmPubkeyNew(const uint8_t *pkt, size_t pktlen)
{
rpmPubkey key = NULL;
if (pkt == NULL || pktlen == 0)
goto exit;
key = xcalloc(1, sizeof(*key));
pgpPubkeyFingerprint(pkt, pktlen, key->keyid);
key->pkt = xmalloc(pktlen);
key->pktlen = pktlen;
memcpy(key->pkt, pkt, pktlen);
exit:
return key;
}
rpmPubkey rpmPubkeyFree(rpmPubkey key)
{
if (key == NULL)
return NULL;
free(key->pkt);
free(key);
return NULL;
}
rpmRC rpmKeyringLookup(rpmKeyring keyring, pgpDig sig)
{
rpmRC res = RPMRC_NOKEY;
if (keyring && sig) {
pgpDigParams sigp = &sig->signature;
pgpDigParams pubp = &sig->pubkey;
struct rpmPubkey_s needle, *key;
needle.pkt = NULL;
needle.pktlen = 0;
memcpy(needle.keyid, sigp->signid, sizeof(needle.keyid));
if ((key = rpmKeyringFindKeyid(keyring, &needle))) {
/* Retrieve parameters from pubkey packet(s) */
(void) pgpPrtPkts(key->pkt, key->pktlen, sig, 0);
/* Do the parameters match the signature? */
if (sigp->pubkey_algo == pubp->pubkey_algo &&
memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)) == 0) {
res = RPMRC_OK;
}
}
}
return res;
}
|