2 * wotsap.c - Output a set of wotsap files from an onak keyring
6 * http://www.lysator.liu.se/~jc/wotsap/wotfileformat.txt
8 * for more details of the format.
10 * Copyright 2013 Jonathan McDowell <noodles@earth.li>
12 * This program is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; version 2 of the License.
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * You should have received a copy of the GNU General Public License along with
22 * this program. If not, see <https://www.gnu.org/licenses/>.
29 #include <arpa/inet.h>
31 #include "build-config.h"
35 #include "onak-conf.h"
38 static struct ll *sortkeyll(struct ll *keys)
40 struct ll *newll, *tmp, **curobj;
41 struct stats_key *curkey, *toadd;
45 toadd = (struct stats_key *) keys->object;
48 curkey = (struct stats_key *) (*curobj)->object;
49 if (curkey->keyid >= toadd->keyid) {
52 curobj = &((*curobj)->next);
56 if (*curobj == NULL || curkey->keyid != toadd->keyid) {
65 static void output_key(struct onak_dbctx *dbctx,
66 FILE *names, FILE *keys, uint64_t keyid)
68 fprintf(names, "%s\n", dbctx->keyid2uid(dbctx, keyid));
69 fprintf(keys, "%c%c%c%c", (int) (keyid >> 24) & 0xFF,
70 (int) (keyid >> 16) & 0xFF,
71 (int) (keyid >> 8) & 0xFF,
72 (int) (keyid ) & 0xFF);
75 static void wotsap(struct onak_dbctx *dbctx, uint64_t keyid, char *dir)
77 struct ll *pending, *sigll, *sigsave;
79 struct stats_key *curkey, *addkey;
81 FILE *names, *keys, *sigs, *file;
83 uint32_t sigcount, sigentry;
85 /* Length of dir + "/" + "signatures" + NUL */
86 tmppath = malloc(strlen(dir) + 12);
87 if (tmppath == NULL) {
88 fprintf(stderr, "Couldn't allocate memory for directory\n");
92 sprintf(tmppath, "%s/WOTVERSION", dir);
93 file = fopen(tmppath, "w");
95 fprintf(stderr, "Couldn't open %s\n", tmppath);
98 fprintf(file, "0.2\n");
101 sprintf(tmppath, "%s/README", dir);
102 file = fopen(tmppath, "w");
104 fprintf(stderr, "Couldn't open %s\n", tmppath);
107 fprintf(file, "This is a Web of Trust archive.\n");
108 fprintf(file, "The file format is documented at:\n");
109 fprintf(file, " http://www.lysator.liu.se/~jc/wotsap/wotfileformat.txt\n\n");
110 fprintf(file, "This file was generated by onak " ONAK_VERSION " \n");
113 sprintf(tmppath, "%s/names", dir);
114 names = fopen(tmppath, "w");
116 fprintf(stderr, "Couldn't open %s\n", tmppath);
119 sprintf(tmppath, "%s/keys", dir);
120 keys = fopen(tmppath, "wb");
122 fprintf(stderr, "Couldn't open %s\n", tmppath);
125 sprintf(tmppath, "%s/signatures", dir);
126 sigs = fopen(tmppath, "wb");
128 fprintf(stderr, "Couldn't open %s\n", tmppath);
132 dbctx->cached_getkeysigs(dbctx, keyid);
133 curkey = findinhash(keyid);
134 curkey->colour = ++curidx;
135 pending = lladd(NULL, curkey);
137 output_key(dbctx, names, keys, curkey->keyid);
139 while (pending != NULL) {
140 curkey = (struct stats_key *) pending->object;
141 sigll = dbctx->cached_getkeysigs(dbctx, curkey->keyid);
142 sigsave = sigll = sortkeyll(sigll);
144 while (sigll != NULL) {
145 addkey = (struct stats_key *) sigll->object;
146 if (addkey->colour == 0 && !addkey->revoked) {
147 uid = dbctx->keyid2uid(dbctx, addkey->keyid);
149 /* Force it to be loaded so we know if it's revoked */
150 dbctx->cached_getkeysigs(dbctx,
152 if (!addkey->revoked) {
153 addkey->colour = ++curidx;
154 pending = lladdend(pending, addkey);
155 output_key(dbctx, names, keys,
160 if (addkey->colour != 0) {
165 /* Now output the signatures */
166 sigcount = htonl(sigcount);
167 fwrite(&sigcount, sizeof (sigcount), 1, sigs);
169 while (sigll != NULL) {
170 addkey = (struct stats_key *) sigll->object;
171 if (addkey->colour != 0) {
172 sigentry = addkey->colour - 1;
173 /* Pretend it's on the primary UID for now */
174 sigentry |= 0x40000000;
175 sigentry = htonl(sigentry);
176 fwrite(&sigentry, sizeof (sigentry), 1, sigs);
180 pending = pending->next;
190 int main(int argc, char *argv[])
193 char *configfile = NULL, *dir = NULL;
194 uint64_t keyid = 0x94FA372B2DA8B985;
195 struct onak_dbctx *dbctx;
197 while ((optchar = getopt(argc, argv, "c:")) != -1 ) {
200 if (configfile != NULL) {
203 configfile = strdup(optarg);
212 readconfig(configfile);
213 initlogthing("wotsap", config.logfile);
214 dbctx = config.dbinit(config.backend, true);
217 wotsap(dbctx, keyid, dir ? dir : ".");
219 dbctx->cleanupdb(dbctx);
221 fprintf(stderr, "Couldn't initialize key database.\n");