Sat May 2 04:19:44 2009 UTC ()
Reorder the args to a static function to mirror some other function calls.

Attempt to use mmap(2) to read a file, and fall back to multiple read(2)
calls if that fails.


(agc)
diff -r1.5 -r1.6 src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c

cvs diff -r1.5 -r1.6 src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c (switch to unified diff)

--- src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c 2009/05/02 02:38:55 1.5
+++ src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c 2009/05/02 04:19:43 1.6
@@ -1,515 +1,532 @@ @@ -1,515 +1,532 @@
1/*- 1/*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc. 2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This code is derived from software contributed to The NetBSD Foundation 5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@netbsd.org) 6 * by Alistair Crooks (agc@netbsd.org)
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29#include "config.h" 29#include "config.h"
30 30
31#include <sys/types.h> 31#include <sys/types.h>
 32#include <sys/stat.h>
32#include <sys/param.h> 33#include <sys/param.h>
 34#include <sys/mman.h>
33 35
34#ifdef HAVE_OPENSSL_CAST_H 36#ifdef HAVE_OPENSSL_CAST_H
35#include <openssl/cast.h> 37#include <openssl/cast.h>
36#endif 38#endif
37 39
38#include <netpgp.h> 40#include <netpgp.h>
39 41
40#include "packet.h" 42#include "packet.h"
41#include "packet-parse.h" 43#include "packet-parse.h"
42#include "keyring.h" 44#include "keyring.h"
43#include "errors.h" 45#include "errors.h"
44#include "packet-show.h" 46#include "packet-show.h"
45#include "create.h" 47#include "create.h"
46#include "netpgpsdk.h" 48#include "netpgpsdk.h"
47#include "memory.h" 49#include "memory.h"
48#include "validate.h" 50#include "validate.h"
49#include "readerwriter.h" 51#include "readerwriter.h"
50#include "netpgpdefs.h" 52#include "netpgpdefs.h"
51#include "parse_local.h" 53#include "parse_local.h"
52 54
53#ifdef HAVE_ASSERT_H 55#ifdef HAVE_ASSERT_H
54#include <assert.h> 56#include <assert.h>
55#endif 57#endif
56 58
57#ifdef HAVE_FCNTL_H 59#ifdef HAVE_FCNTL_H
58#include <fcntl.h> 60#include <fcntl.h>
59#endif 61#endif
60 62
61#include <regex.h> 63#include <regex.h>
62#include <stdarg.h> 64#include <stdarg.h>
63#include <stdlib.h> 65#include <stdlib.h>
64#include <string.h> 66#include <string.h>
65#include <time.h> 67#include <time.h>
66 68
67#ifdef HAVE_UNISTD_H 69#ifdef HAVE_UNISTD_H
68#include <unistd.h> 70#include <unistd.h>
69#endif 71#endif
70 72
71#include <errno.h> 73#include <errno.h>
72 74
73#ifdef HAVE_LIMITS_H 75#ifdef HAVE_LIMITS_H
74#include <limits.h> 76#include <limits.h>
75#endif 77#endif
76 78
77enum { 79enum {
78 MAX_ID_LENGTH = 128, 80 MAX_ID_LENGTH = 128,
79 MAX_PASSPHRASE_LENGTH = 256 81 MAX_PASSPHRASE_LENGTH = 256
80}; 82};
81 83
82/* read any gpg config file */ 84/* read any gpg config file */
83static int 85static int
84conffile(char *homedir, char *userid, size_t length, int verbose) 86conffile(char *homedir, char *userid, size_t length, int verbose)
85{ 87{
86 regmatch_t matchv[10]; 88 regmatch_t matchv[10];
87 regex_t r; 89 regex_t r;
88 char buf[BUFSIZ]; 90 char buf[BUFSIZ];
89 FILE *fp; 91 FILE *fp;
90 92
91 (void) snprintf(buf, sizeof(buf), "%s/.gnupg/gpg.conf", homedir); 93 (void) snprintf(buf, sizeof(buf), "%s/.gnupg/gpg.conf", homedir);
92 if ((fp = fopen(buf, "r")) == NULL) { 94 if ((fp = fopen(buf, "r")) == NULL) {
93 return 0; 95 return 0;
94 } 96 }
95 (void) regcomp(&r, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)", 97 (void) regcomp(&r, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)",
96 REG_EXTENDED); 98 REG_EXTENDED);
97 while (fgets(buf, sizeof(buf), fp) != NULL) { 99 while (fgets(buf, sizeof(buf), fp) != NULL) {
98 if (regexec(&r, buf, 10, matchv, 0) == 0) { 100 if (regexec(&r, buf, 10, matchv, 0) == 0) {
99 (void) memcpy(userid, &buf[(int)matchv[1].rm_so], 101 (void) memcpy(userid, &buf[(int)matchv[1].rm_so],
100 MIN((unsigned)(matchv[1].rm_eo - matchv[1].rm_so), length)); 102 MIN((unsigned)(matchv[1].rm_eo - matchv[1].rm_so), length));
101 if (verbose) { 103 if (verbose) {
102 printf("setting default key to \"%.*s\"\n", 104 printf("setting default key to \"%.*s\"\n",
103 (int)(matchv[1].rm_eo - matchv[1].rm_so), 105 (int)(matchv[1].rm_eo - matchv[1].rm_so),
104 &buf[(int)matchv[1].rm_so]); 106 &buf[(int)matchv[1].rm_so]);
105 } 107 }
106 } 108 }
107 } 109 }
108 (void) fclose(fp); 110 (void) fclose(fp);
109 return 1; 111 return 1;
110} 112}
111 113
112/* wrapper to get a pass phrase from the user */ 114/* wrapper to get a pass phrase from the user */
113static void 115static void
114get_pass_phrase(char *phrase, size_t size) 116get_pass_phrase(char *phrase, size_t size)
115{ 117{
116 char *p; 118 char *p;
117 119
118 while ((p = getpass("netpgp passphrase: ")) == NULL) { 120 while ((p = getpass("netpgp passphrase: ")) == NULL) {
119 } 121 }
120 (void) snprintf(phrase, size, "%s", p); 122 (void) snprintf(phrase, size, "%s", p);
121} 123}
122 124
123/* small function to pretty print an 8-character raw userid */ 125/* small function to pretty print an 8-character raw userid */
124static char * 126static char *
125userid_to_id(const unsigned char *userid, char *id) 127userid_to_id(const unsigned char *userid, char *id)
126{ 128{
127 static const char *hexes = "0123456789ABCDEF"; 129 static const char *hexes = "0123456789ABCDEF";
128 int i; 130 int i;
129 131
130 for (i = 0; i < 8 ; i++) { 132 for (i = 0; i < 8 ; i++) {
131 id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4]; 133 id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
132 id[(i * 2) + 1] = hexes[userid[i] & 0xf]; 134 id[(i * 2) + 1] = hexes[userid[i] & 0xf];
133 } 135 }
134 id[8 * 2] = 0x0; 136 id[8 * 2] = 0x0;
135 return id; 137 return id;
136} 138}
137 139
138/* print out the successful signature information */ 140/* print out the successful signature information */
139static void 141static void
140psuccess(char *f, __ops_validation_t *results, __ops_keyring_t *pubring) 142psuccess(char *f, __ops_validation_t *results, __ops_keyring_t *pubring)
141{ 143{
142 const __ops_keydata_t *pubkey; 144 const __ops_keydata_t *pubkey;
143 unsigned i; 145 unsigned i;
144 char id[MAX_ID_LENGTH + 1]; 146 char id[MAX_ID_LENGTH + 1];
145 147
146 for (i = 0; i < results->validc; i++) { 148 for (i = 0; i < results->validc; i++) {
147 printf("Good signature for %s made %susing %s key %s\n", 149 printf("Good signature for %s made %susing %s key %s\n",
148 f, 150 f,
149 ctime(&results->valid_sigs[i].creation_time), 151 ctime(&results->valid_sigs[i].creation_time),
150 __ops_show_pka(results->valid_sigs[i].key_algorithm), 152 __ops_show_pka(results->valid_sigs[i].key_algorithm),
151 userid_to_id(results->valid_sigs[i].signer_id, id)); 153 userid_to_id(results->valid_sigs[i].signer_id, id));
152 pubkey = __ops_keyring_find_key_by_id(pubring, 154 pubkey = __ops_keyring_find_key_by_id(pubring,
153 (const unsigned char *) 155 (const unsigned char *)
154 results->valid_sigs[i].signer_id); 156 results->valid_sigs[i].signer_id);
155 __ops_print_public_keydata(pubkey); 157 __ops_print_public_keydata(pubkey);
156 } 158 }
157} 159}
158 160
159/* sign a file, and put the signature in a separate file */ 161/* sign a file, and put the signature in a separate file */
160static int 162static int
161sign_detached(__ops_secret_key_t *seckey, const char *hashstr, char *f, 163sign_detached(char *f, char *sigfile, __ops_secret_key_t *seckey,
162 char *sigfile) 164 const char *hashstr)
163{ 165{
164 __ops_create_signature_t *sig; 166 __ops_create_signature_t *sig;
165 __ops_hash_algorithm_t alg; 167 __ops_hash_algorithm_t alg;
166 __ops_create_info_t *info; 168 __ops_create_info_t *info;
167 unsigned char keyid[OPS_KEY_ID_SIZE]; 169 unsigned char keyid[OPS_KEY_ID_SIZE];
 170 unsigned char *mmapped;
 171 struct stat st;
168 time_t t; 172 time_t t;
169 char fname[MAXPATHLEN]; 173 char fname[MAXPATHLEN];
170 int fd; 174 int fd;
171 175
172 /* find out which hash algorithm to use */ 176 /* find out which hash algorithm to use */
173 alg = __ops_hash_algorithm_from_text(hashstr); 177 alg = __ops_hash_algorithm_from_text(hashstr);
174 if (alg == OPS_HASH_UNKNOWN) { 178 if (alg == OPS_HASH_UNKNOWN) {
175 (void) fprintf(stderr,"Unknown hash algorithm: %s\n", hashstr); 179 (void) fprintf(stderr,"Unknown hash algorithm: %s\n", hashstr);
176 return 0; 180 return 0;
177 } 181 }
178 182
179 /* create a new signature */ 183 /* create a new signature */
180 sig = __ops_create_signature_new(); 184 sig = __ops_create_signature_new();
181 __ops_signature_start_cleartext_signature(sig, seckey, alg, 185 __ops_signature_start_cleartext_signature(sig, seckey, alg,
182 OPS_SIG_BINARY); 186 OPS_SIG_BINARY);
183 187
184 /* read the contents of 'f' */ 188 /* read the contents of 'f' */
185 fd = open(f, O_RDONLY); 189 fd = open(f, O_RDONLY);
186 if (fd < 0) { 190 if (fd < 0) {
187 (void) fprintf(stderr, "can't open file \"%s\" to sign\n", 191 (void) fprintf(stderr, "can't open file \"%s\" to sign\n",
188 f); 192 f);
189 return 0; 193 return 0;
190 } 194 }
191 for (;;) { 195 /* attempt to mmap(2) the file - if that fails, fall back to
192 unsigned char buf[8192]; 196 * standard read(2) */
193 int n; 197 mmapped = MAP_FAILED;
 198 if (fstat(fd, &st) == 0) {
 199 mmapped = mmap(NULL, (size_t)st.st_size, PROT_READ,
 200 MAP_FILE | MAP_PRIVATE, fd, 0);
 201 }
 202 if (mmapped == MAP_FAILED) {
 203 for (;;) {
 204 unsigned char buf[8192];
 205 int n;
194 206
195 if ((n = read(fd, buf, sizeof(buf))) == 0) { 207 if ((n = read(fd, buf, sizeof(buf))) == 0) {
196 break; 208 break;
197 } 209 }
198 if (n < 0) { 210 if (n < 0) {
199 (void) fprintf(stderr, "short read \"%s\"\n", f); 211 (void) fprintf(stderr, "short read \"%s\"\n",
200 (void) close(fd); 212 f);
201 return 0; 213 (void) close(fd);
 214 return 0;
 215 }
 216 __ops_signature_add_data(sig, buf, (unsigned)n);
202 } 217 }
203 __ops_signature_add_data(sig, buf, (unsigned)n); 218 } else {
 219 __ops_signature_add_data(sig, mmapped, (unsigned)st.st_size);
 220 (void) munmap(mmapped, (unsigned)st.st_size);
204 } 221 }
205 (void) close(fd); 222 (void) close(fd);
206 223
207 /* calculate the signature */ 224 /* calculate the signature */
208 t = time(NULL); 225 t = time(NULL);
209 __ops_signature_add_creation_time(sig, t); 226 __ops_signature_add_creation_time(sig, t);
210 __ops_keyid(keyid, OPS_KEY_ID_SIZE, OPS_KEY_ID_SIZE, 227 __ops_keyid(keyid, OPS_KEY_ID_SIZE, OPS_KEY_ID_SIZE,
211 &seckey->public_key); 228 &seckey->public_key);
212 __ops_signature_add_issuer_key_id(sig, keyid); 229 __ops_signature_add_issuer_key_id(sig, keyid);
213 __ops_signature_hashed_subpackets_end(sig); 230 __ops_signature_hashed_subpackets_end(sig);
214 231
215 /* write the signature to the detached file */ 232 /* write the signature to the detached file */
216 if (sigfile == NULL) { 233 if (sigfile == NULL) {
217 (void) snprintf(fname, sizeof(fname), "%s.sig", f); 234 (void) snprintf(fname, sizeof(fname), "%s.sig", f);
218 sigfile = fname; 235 sigfile = fname;
219 } 236 }
220 fd = open(sigfile, O_CREAT|O_TRUNC|O_WRONLY, 0666); 237 fd = open(sigfile, O_CREAT|O_TRUNC|O_WRONLY, 0666);
221 if (fd < 0) { 238 if (fd < 0) {
222 (void) fprintf(stderr, "can't write signature to \"%s\"\n", 239 (void) fprintf(stderr, "can't write signature to \"%s\"\n",
223 sigfile); 240 sigfile);
224 return 0; 241 return 0;
225 } 242 }
226 243
227 info = __ops_create_info_new(); 244 info = __ops_create_info_new();
228 __ops_writer_set_fd(info, fd); 245 __ops_writer_set_fd(info, fd);
229 __ops_write_signature(sig, &seckey->public_key, seckey, info); 246 __ops_write_signature(sig, &seckey->public_key, seckey, info);
230 __ops_secret_key_free(seckey); 247 __ops_secret_key_free(seckey);
231 (void) close(fd); 248 (void) close(fd);
232 249
233 return 1; 250 return 1;
234} 251}
235 252
236/***************************************************************************/ 253/***************************************************************************/
237/* exported functions start here */ 254/* exported functions start here */
238/***************************************************************************/ 255/***************************************************************************/
239 256
240/* initialise a netpgp_t structure */ 257/* initialise a netpgp_t structure */
241int 258int
242netpgp_init(netpgp_t *netpgp, char *userid, char *pubring, char *secring) 259netpgp_init(netpgp_t *netpgp, char *userid, char *pubring, char *secring)
243{ 260{
244 __ops_keyring_t *keyring; 261 __ops_keyring_t *keyring;
245 char *homedir; 262 char *homedir;
246 char ringname[MAXPATHLEN]; 263 char ringname[MAXPATHLEN];
247 char id[MAX_ID_LENGTH]; 264 char id[MAX_ID_LENGTH];
248 265
249 (void) memset(netpgp, 0x0, sizeof(*netpgp)); 266 (void) memset(netpgp, 0x0, sizeof(*netpgp));
250 homedir = getenv("HOME"); 267 homedir = getenv("HOME");
251 if (userid == NULL) { 268 if (userid == NULL) {
252 (void) memset(id, 0x0, sizeof(id)); 269 (void) memset(id, 0x0, sizeof(id));
253 conffile(homedir, id, sizeof(id), 1); 270 conffile(homedir, id, sizeof(id), 1);
254 if (id[0] != 0x0) { 271 if (id[0] != 0x0) {
255 userid = id; 272 userid = id;
256 } 273 }
257 } 274 }
258 if (userid == NULL) { 275 if (userid == NULL) {
259 (void) fprintf(stderr, "Cannot find user id\n"); 276 (void) fprintf(stderr, "Cannot find user id\n");
260 return 0; 277 return 0;
261 } 278 }
262 if (pubring == NULL) { 279 if (pubring == NULL) {
263 (void) snprintf(ringname, sizeof(ringname), "%s/.gnupg/pubring.gpg", homedir); 280 (void) snprintf(ringname, sizeof(ringname), "%s/.gnupg/pubring.gpg", homedir);
264 pubring = ringname; 281 pubring = ringname;
265 } 282 }
266 keyring = calloc(1, sizeof(*keyring)); 283 keyring = calloc(1, sizeof(*keyring));
267 if (!__ops_keyring_read_from_file(keyring, false, pubring)) { 284 if (!__ops_keyring_read_from_file(keyring, false, pubring)) {
268 (void) fprintf(stderr, "Cannot read pub keyring %s\n", pubring); 285 (void) fprintf(stderr, "Cannot read pub keyring %s\n", pubring);
269 return 0; 286 return 0;
270 } 287 }
271 netpgp->pubring = keyring; 288 netpgp->pubring = keyring;
272 netpgp->pubringfile = strdup(pubring); 289 netpgp->pubringfile = strdup(pubring);
273 if (secring == NULL) { 290 if (secring == NULL) {
274 (void) snprintf(ringname, sizeof(ringname), "%s/.gnupg/secring.gpg", homedir); 291 (void) snprintf(ringname, sizeof(ringname), "%s/.gnupg/secring.gpg", homedir);
275 secring = ringname; 292 secring = ringname;
276 } 293 }
277 keyring = calloc(1, sizeof(*keyring)); 294 keyring = calloc(1, sizeof(*keyring));
278 if (!__ops_keyring_read_from_file(keyring, false, secring)) { 295 if (!__ops_keyring_read_from_file(keyring, false, secring)) {
279 (void) fprintf(stderr, "Cannot read sec keyring %s\n", secring); 296 (void) fprintf(stderr, "Cannot read sec keyring %s\n", secring);
280 return 0; 297 return 0;
281 } 298 }
282 netpgp->secring = keyring; 299 netpgp->secring = keyring;
283 netpgp->secringfile = strdup(secring); 300 netpgp->secringfile = strdup(secring);
284 netpgp->userid = strdup(userid); 301 netpgp->userid = strdup(userid);
285 return 1; 302 return 1;
286} 303}
287 304
288/* finish off with the netpgp_t struct */ 305/* finish off with the netpgp_t struct */
289int 306int
290netpgp_end(netpgp_t *netpgp) 307netpgp_end(netpgp_t *netpgp)
291{ 308{
292 if (netpgp->pubring != NULL) { 309 if (netpgp->pubring != NULL) {
293 __ops_keyring_free(netpgp->pubring); 310 __ops_keyring_free(netpgp->pubring);
294 } 311 }
295 if (netpgp->pubringfile != NULL) { 312 if (netpgp->pubringfile != NULL) {
296 (void) free(netpgp->pubringfile); 313 (void) free(netpgp->pubringfile);
297 } 314 }
298 if (netpgp->secring != NULL) { 315 if (netpgp->secring != NULL) {
299 __ops_keyring_free(netpgp->secring); 316 __ops_keyring_free(netpgp->secring);
300 } 317 }
301 if (netpgp->secringfile != NULL) { 318 if (netpgp->secringfile != NULL) {
302 (void) free(netpgp->secringfile); 319 (void) free(netpgp->secringfile);
303 } 320 }
304 (void) free(netpgp->userid); 321 (void) free(netpgp->userid);
305 return 1; 322 return 1;
306} 323}
307 324
308/* list the keys in a keyring */ 325/* list the keys in a keyring */
309int 326int
310netpgp_list_keys(netpgp_t *netpgp) 327netpgp_list_keys(netpgp_t *netpgp)
311{ 328{
312 __ops_keyring_list(netpgp->pubring); 329 __ops_keyring_list(netpgp->pubring);
313 return 1; 330 return 1;
314} 331}
315 332
316/* find a key in a keyring */ 333/* find a key in a keyring */
317int 334int
318netpgp_find_key(netpgp_t *netpgp, char *id) 335netpgp_find_key(netpgp_t *netpgp, char *id)
319{ 336{
320 if (id == NULL) { 337 if (id == NULL) {
321 (void) fprintf(stderr, "NULL id to search for\n"); 338 (void) fprintf(stderr, "NULL id to search for\n");
322 return 0; 339 return 0;
323 } 340 }
324 return __ops_keyring_find_key_by_userid(netpgp->pubring, id) != NULL; 341 return __ops_keyring_find_key_by_userid(netpgp->pubring, id) != NULL;
325} 342}
326 343
327/* export a given key */ 344/* export a given key */
328int 345int
329netpgp_export_key(netpgp_t *netpgp, char *userid) 346netpgp_export_key(netpgp_t *netpgp, char *userid)
330{ 347{
331 const __ops_keydata_t *keypair; 348 const __ops_keydata_t *keypair;
332 349
333 if (userid == NULL) { 350 if (userid == NULL) {
334 userid = netpgp->userid; 351 userid = netpgp->userid;
335 } 352 }
336 if ((keypair = __ops_keyring_find_key_by_userid(netpgp->pubring, userid)) == NULL) { 353 if ((keypair = __ops_keyring_find_key_by_userid(netpgp->pubring, userid)) == NULL) {
337 (void) fprintf(stderr, "Cannot find own key \"%s\" in keyring\n", userid); 354 (void) fprintf(stderr, "Cannot find own key \"%s\" in keyring\n", userid);
338 return 0; 355 return 0;
339 } 356 }
340 __ops_export_key(keypair, NULL); 357 __ops_export_key(keypair, NULL);
341 return 1; 358 return 1;
342} 359}
343 360
344/* import a key into our keyring */ 361/* import a key into our keyring */
345int 362int
346netpgp_import_key(netpgp_t *netpgp, char *f) 363netpgp_import_key(netpgp_t *netpgp, char *f)
347{ 364{
348 int done; 365 int done;
349 366
350 if ((done = __ops_keyring_read_from_file(netpgp->pubring, false, f)) == 0) { 367 if ((done = __ops_keyring_read_from_file(netpgp->pubring, false, f)) == 0) {
351 done = __ops_keyring_read_from_file(netpgp->pubring, true, f); 368 done = __ops_keyring_read_from_file(netpgp->pubring, true, f);
352 } 369 }
353 if (!done) { 370 if (!done) {
354 (void) fprintf(stderr, "Cannot import key from file %s\n", f); 371 (void) fprintf(stderr, "Cannot import key from file %s\n", f);
355 return 0; 372 return 0;
356 } 373 }
357 __ops_keyring_list(netpgp->pubring); 374 __ops_keyring_list(netpgp->pubring);
358 return 1; 375 return 1;
359} 376}
360 377
361/* generate a new key */ 378/* generate a new key */
362int 379int
363netpgp_generate_key(netpgp_t *netpgp, char *id, int numbits) 380netpgp_generate_key(netpgp_t *netpgp, char *id, int numbits)
364{ 381{
365 __ops_create_info_t *create; 382 __ops_create_info_t *create;
366 __ops_keydata_t *keypair; 383 __ops_keydata_t *keypair;
367 __ops_user_id_t uid; 384 __ops_user_id_t uid;
368 int fd; 385 int fd;
369 386
370 (void) memset(&uid, 0x0, sizeof(uid)); 387 (void) memset(&uid, 0x0, sizeof(uid));
371 uid.user_id = (unsigned char *) id; 388 uid.user_id = (unsigned char *) id;
372 if ((keypair = __ops_rsa_create_selfsigned_keypair(numbits, (const unsigned long)65537, &uid)) == NULL) { 389 if ((keypair = __ops_rsa_create_selfsigned_keypair(numbits, (const unsigned long)65537, &uid)) == NULL) {
373 (void) fprintf(stderr, "Cannot generate key\n"); 390 (void) fprintf(stderr, "Cannot generate key\n");
374 return 0; 391 return 0;
375 } 392 }
376 /* write public key */ 393 /* write public key */
377 fd = __ops_setup_file_append(&create, netpgp->pubringfile); 394 fd = __ops_setup_file_append(&create, netpgp->pubringfile);
378 __ops_write_transferable_public_key(keypair, false, create); 395 __ops_write_transferable_public_key(keypair, false, create);
379 __ops_teardown_file_write(create, fd); 396 __ops_teardown_file_write(create, fd);
380 __ops_keyring_free(netpgp->pubring); 397 __ops_keyring_free(netpgp->pubring);
381 if (!__ops_keyring_read_from_file(netpgp->pubring, false, netpgp->pubringfile)) { 398 if (!__ops_keyring_read_from_file(netpgp->pubring, false, netpgp->pubringfile)) {
382 (void) fprintf(stderr, "Cannot re-read keyring %s\n", netpgp->pubringfile); 399 (void) fprintf(stderr, "Cannot re-read keyring %s\n", netpgp->pubringfile);
383 return 0; 400 return 0;
384 } 401 }
385 /* write secret key */ 402 /* write secret key */
386 fd = __ops_setup_file_append(&create, netpgp->secringfile); 403 fd = __ops_setup_file_append(&create, netpgp->secringfile);
387 __ops_write_transferable_secret_key(keypair, NULL, 0, false, create); 404 __ops_write_transferable_secret_key(keypair, NULL, 0, false, create);
388 __ops_teardown_file_write(create, fd); 405 __ops_teardown_file_write(create, fd);
389 __ops_keyring_free(netpgp->secring); 406 __ops_keyring_free(netpgp->secring);
390 if (!__ops_keyring_read_from_file(netpgp->secring, false, netpgp->secringfile)) { 407 if (!__ops_keyring_read_from_file(netpgp->secring, false, netpgp->secringfile)) {
391 fprintf(stderr, "Cannot re-read keyring %s\n", netpgp->secringfile); 408 fprintf(stderr, "Cannot re-read keyring %s\n", netpgp->secringfile);
392 return 0; 409 return 0;
393 } 410 }
394 __ops_keydata_free(keypair); 411 __ops_keydata_free(keypair);
395 return 1; 412 return 1;
396} 413}
397 414
398/* encrypt a file */ 415/* encrypt a file */
399int 416int
400netpgp_encrypt_file(netpgp_t *netpgp, char *userid, char *f, char *out, int armored) 417netpgp_encrypt_file(netpgp_t *netpgp, char *userid, char *f, char *out, int armored)
401{ 418{
402 const __ops_keydata_t *keypair; 419 const __ops_keydata_t *keypair;
403 const char *suffix; 420 const char *suffix;
404 char outname[MAXPATHLEN]; 421 char outname[MAXPATHLEN];
405 422
406 if (userid == NULL) { 423 if (userid == NULL) {
407 userid = netpgp->userid; 424 userid = netpgp->userid;
408 } 425 }
409 suffix = (armored) ? ".asc" : ".gpg"; 426 suffix = (armored) ? ".asc" : ".gpg";
410 if ((keypair = __ops_keyring_find_key_by_userid(netpgp->pubring, userid)) == NULL) { 427 if ((keypair = __ops_keyring_find_key_by_userid(netpgp->pubring, userid)) == NULL) {
411 (void) fprintf(stderr, "Userid '%s' not found in keyring\n", userid); 428 (void) fprintf(stderr, "Userid '%s' not found in keyring\n", userid);
412 return 0; 429 return 0;
413 } 430 }
414 if (out == NULL) { 431 if (out == NULL) {
415 (void) snprintf(outname, sizeof(outname), "%s%s", f, suffix); 432 (void) snprintf(outname, sizeof(outname), "%s%s", f, suffix);
416 out = outname; 433 out = outname;
417 } 434 }
418 __ops_encrypt_file(f, out, keypair, armored, true); 435 __ops_encrypt_file(f, out, keypair, armored, true);
419 return 1; 436 return 1;
420} 437}
421 438
422/* decrypt a file */ 439/* decrypt a file */
423int 440int
424netpgp_decrypt_file(netpgp_t *netpgp, char *f, char *out, int armored) 441netpgp_decrypt_file(netpgp_t *netpgp, char *f, char *out, int armored)
425{ 442{
426 __ops_decrypt_file(f, out, netpgp->secring, armored, true, 443 __ops_decrypt_file(f, out, netpgp->secring, armored, true,
427 get_passphrase_cb); 444 get_passphrase_cb);
428 return 1; 445 return 1;
429} 446}
430 447
431/* sign a file */ 448/* sign a file */
432int 449int
433netpgp_sign_file(netpgp_t *netpgp, char *userid, char *f, char *out, 450netpgp_sign_file(netpgp_t *netpgp, char *userid, char *f, char *out,
434 int armored, int cleartext, int detached) 451 int armored, int cleartext, int detached)
435{ 452{
436 const __ops_keydata_t *keypair; 453 const __ops_keydata_t *keypair;
437 __ops_secret_key_t *seckey; 454 __ops_secret_key_t *seckey;
438 char passphrase[MAX_PASSPHRASE_LENGTH]; 455 char passphrase[MAX_PASSPHRASE_LENGTH];
439 456
440 if (userid == NULL) { 457 if (userid == NULL) {
441 userid = netpgp->userid; 458 userid = netpgp->userid;
442 } 459 }
443 /* get key with which to sign */ 460 /* get key with which to sign */
444 keypair = __ops_keyring_find_key_by_userid(netpgp->secring, userid); 461 keypair = __ops_keyring_find_key_by_userid(netpgp->secring, userid);
445 if (keypair == NULL) { 462 if (keypair == NULL) {
446 (void) fprintf(stderr, "Userid '%s' not found in keyring\n", 463 (void) fprintf(stderr, "Userid '%s' not found in keyring\n",
447 userid); 464 userid);
448 return 0; 465 return 0;
449 } 466 }
450 do { 467 do {
451 /* print out the user id */ 468 /* print out the user id */
452 __ops_print_public_keydata(keypair); 469 __ops_print_public_keydata(keypair);
453 /* get the passphrase */ 470 /* get the passphrase */
454 get_pass_phrase(passphrase, sizeof(passphrase)); 471 get_pass_phrase(passphrase, sizeof(passphrase));
455 /* now decrypt key */ 472 /* now decrypt key */
456 seckey = __ops_decrypt_secret_key_from_data(keypair, 473 seckey = __ops_decrypt_secret_key_from_data(keypair,
457 passphrase); 474 passphrase);
458 if (seckey == NULL) { 475 if (seckey == NULL) {
459 (void) fprintf(stderr, "Bad passphrase\n"); 476 (void) fprintf(stderr, "Bad passphrase\n");
460 } 477 }
461 } while (seckey == NULL); 478 } while (seckey == NULL);
462 /* sign file */ 479 /* sign file */
463 if (cleartext) { 480 if (cleartext) {
464 __ops_sign_file_as_cleartext(f, out, seckey, true); 481 __ops_sign_file_as_cleartext(f, out, seckey, true);
465 } else if (detached) { 482 } else if (detached) {
466 sign_detached(seckey, "SHA1", f, out); 483 sign_detached(f, out, seckey, "SHA1");
467 } else { 484 } else {
468 __ops_sign_file(f, out, seckey, armored, true); 485 __ops_sign_file(f, out, seckey, armored, true);
469 } 486 }
470 (void) memset(passphrase, 0x0, sizeof(passphrase)); 487 (void) memset(passphrase, 0x0, sizeof(passphrase));
471 return 1; 488 return 1;
472} 489}
473 490
474/* verify a file */ 491/* verify a file */
475int 492int
476netpgp_verify_file(netpgp_t *netpgp, char *f, int armored) 493netpgp_verify_file(netpgp_t *netpgp, char *f, int armored)
477{ 494{
478 __ops_validation_t result; 495 __ops_validation_t result;
479 496
480 (void) memset(&result, 0x0, sizeof(result)); 497 (void) memset(&result, 0x0, sizeof(result));
481 if (__ops_validate_file(&result, f, armored, netpgp->pubring)) { 498 if (__ops_validate_file(&result, f, armored, netpgp->pubring)) {
482 psuccess(f, &result, netpgp->pubring); 499 psuccess(f, &result, netpgp->pubring);
483 return 1; 500 return 1;
484 } 501 }
485 if (result.validc + result.invalidc + result.unknownc == 0) { 502 if (result.validc + result.invalidc + result.unknownc == 0) {
486 (void) fprintf(stderr, "\"%s\": No signatures found - is this a signed file?\n", f); 503 (void) fprintf(stderr, "\"%s\": No signatures found - is this a signed file?\n", f);
487 return 0; 504 return 0;
488 } 505 }
489 (void) fprintf(stderr, "\"%s\": verification failure: %d invalid signatures, %d unknown signatures\n", 506 (void) fprintf(stderr, "\"%s\": verification failure: %d invalid signatures, %d unknown signatures\n",
490 f, result.invalidc, result.unknownc); 507 f, result.invalidc, result.unknownc);
491 return 0; 508 return 0;
492} 509}
493 510
494/* wrappers for the ops_debug_level functions we added to openpgpsdk */ 511/* wrappers for the ops_debug_level functions we added to openpgpsdk */
495 512
496/* set the debugging level per filename */ 513/* set the debugging level per filename */
497int 514int
498netpgp_set_debug(const char *f) 515netpgp_set_debug(const char *f)
499{ 516{
500 return __ops_set_debug_level(f); 517 return __ops_set_debug_level(f);
501} 518}
502 519
503/* get the debugging level per filename */ 520/* get the debugging level per filename */
504int 521int
505netpgp_get_debug(const char *f) 522netpgp_get_debug(const char *f)
506{ 523{
507 return __ops_get_debug_level(f); 524 return __ops_get_debug_level(f);
508} 525}
509 526
510/* return the version for the library */ 527/* return the version for the library */
511const char * 528const char *
512netpgp_get_info(const char *type) 529netpgp_get_info(const char *type)
513{ 530{
514 return __ops_get_info(type); 531 return __ops_get_info(type);
515} 532}