2 * keydb_db2.c - Routines to store and fetch keys in a DB2 file (a la pksd)
4 * Jonathan McDowell <noodles@earth.li>
6 * Copyright 2002 Project Purple
19 #include "charfuncs.h"
23 #include "keystructs.h"
25 #include "onak-conf.h"
28 #define KEYDB_KEYID_BYTES 4
31 * db2_numdb - The number of database files we have.
33 static int db2_numdb = 16;
36 * db2_keydbfiles - An array of DB structs for our key database files.
38 static DB **db2_keydbfiles = NULL;
41 * db2_env - Database environment variable.
43 static DB_ENV db2_env;
48 * keyid's are 8 bytes, msb first. so start from the end. use 16
49 * bits, since that's enough to divide by any small number of db files.
51 unsigned char *keydata = (unsigned char *) key->data;
52 unsigned long keyidnum;
54 keyidnum = (keydata[KEYDB_KEYID_BYTES-2]<<8)|keydata[KEYDB_KEYID_BYTES-1];
55 return(db2_keydbfiles[keyidnum % db2_numdb]);
59 * initdb - Initialize the key database.
61 * This function should be called before any of the other functions in
62 * this file are called in order to allow the DB to be initialized ready
72 memset(&db2_env, 0, sizeof(db2_env));
75 * Tunable param. Just using what pksd does for the moment. Bigger uses
76 * more memory but improves performance. Bigger than physical memory
79 db2_env.mp_size = 20 * 1024 * 1024;
81 ret = db_appinit(config.db_dir, NULL,
82 &db2_env, DB_INIT_MPOOL|DB_INIT_LOCK);
84 db2_keydbfiles = (DB **) malloc(sizeof (DB *) * db2_numdb);
85 memset(&keydbinfo, 0, sizeof(keydbinfo));
86 keydbinfo.db_pagesize = 8192;
87 for (i = 0; i < db2_numdb; i++) {
88 db2_keydbfiles[i] = NULL;
89 snprintf(keydbname, 19, "keydb%03d", i);
90 ret = db_open(keydbname, DB_HASH, DB_RDONLY, 0644,
94 fprintf(stderr, "Error opening db file %d (errno %d)\n",
100 fprintf(stderr, "Error initializing db (%d).\n", ret);
106 * cleanupdb - De-initialize the key database.
108 * This function should be called upon program exit to allow the DB to
109 * cleanup after itself.
115 for (i = 0; i < db2_numdb; i++) {
116 if (db2_keydbfiles[i] != NULL) {
117 (*(db2_keydbfiles[i]->close))(db2_keydbfiles[i], 0);
118 db2_keydbfiles[i] = NULL;
122 db_appexit(&db2_env);
126 * starttrans - Start a transaction.
128 * Start a transaction. Intended to be used if we're about to perform many
129 * operations on the database to help speed it all up, or if we want
130 * something to only succeed if all relevant operations are successful.
132 bool starttrans(void)
138 * endtrans - End a transaction.
140 * Ends a transaction.
148 * fetch_key - Given a keyid fetch the key from storage.
149 * @keyid: The keyid to fetch.
150 * @publickey: A pointer to a structure to return the key in.
151 * @intrans: If we're already in a transaction.
153 * We use the hex representation of the keyid as the filename to fetch the
154 * key from. The key is stored in the file as a binary OpenPGP stream of
155 * packets, so we can just use read_openpgp_stream() to read the packets
156 * in and then parse_keys() to parse the packets into a publickey
159 int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
162 struct openpgp_packet_list *packets = NULL;
165 char id[KEYDB_KEYID_BYTES];
166 struct buffer_ctx fetchbuf;
168 memset(&key, 0, sizeof(key));
169 memset(&data, 0, sizeof(data));
171 id[0] = (keyid >> 24) & 0xFF;
172 id[1] = (keyid >> 16) & 0xFF;
173 id[2] = (keyid >> 8) & 0xFF;
174 id[3] = keyid & 0xFF;
177 key.size = KEYDB_KEYID_BYTES;
179 ret = (*(keydb(&key)->get))(keydb(&key), NULL, &key, &data, 0);
181 fetchbuf.buffer = data.data;
183 fetchbuf.size = data.size;
184 read_openpgp_stream(buffer_fetchchar, &fetchbuf, &packets);
185 parse_keys(packets, publickey);
186 free_packet_list(packets);
194 * fetch_key_text - Trys to find the keys that contain the supplied text.
195 * @search: The text to search for.
196 * @publickey: A pointer to a structure to return the key in.
198 * This function searches for the supplied text and returns the keys that
201 int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
207 * store_key - Takes a key and stores it.
208 * @publickey: A pointer to the public key to store.
209 * @intrans: If we're already in a transaction.
210 * @update: If true the key exists and should be updated.
212 * Again we just use the hex representation of the keyid as the filename
213 * to store the key to. We flatten the public key to a list of OpenPGP
214 * packets and then use write_openpgp_stream() to write the stream out to
217 int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
223 * delete_key - Given a keyid delete the key from storage.
224 * @keyid: The keyid to delete.
225 * @intrans: If we're already in a transaction.
227 * This function deletes a public key from whatever storage mechanism we
228 * are using. Returns 0 if the key existed.
230 int delete_key(uint64_t keyid, bool intrans)
236 * Include the basic keydb routines.
238 #define NEED_KEYID2UID 1
239 #define NEED_GETKEYSIGS 1
240 #define NEED_GETFULLKEYID 1