1 /*- 2 * Copyright (c) 2009 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Alistair Crooks (agc@NetBSD.org) 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 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 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 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 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 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #include "config.h" 30 31 #ifdef HAVE_SYS_CDEFS_H 32 #include <sys/cdefs.h> 33 #endif 34 35 #if defined(__NetBSD__) 36 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 37 __RCSID("$NetBSD: netpgp.c,v 1.96 2012/02/22 06:58:54 agc Exp $"); 38 #endif 39 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 #include <sys/param.h> 43 #include <sys/mman.h> 44 45 #ifdef HAVE_SYS_RESOURCE_H 46 #include <sys/resource.h> 47 #endif 48 49 #ifdef HAVE_FCNTL_H 50 #include <fcntl.h> 51 #endif 52 53 #include <errno.h> 54 #include <regex.h> 55 #include <stdarg.h> 56 #include <stdlib.h> 57 #include <string.h> 58 #include <time.h> 59 60 #ifdef HAVE_UNISTD_H 61 #include <unistd.h> 62 #endif 63 64 #include <errno.h> 65 66 #ifdef HAVE_LIMITS_H 67 #include <limits.h> 68 #endif 69 70 #include <netpgp.h> 71 72 #include "packet.h" 73 #include "packet-parse.h" 74 #include "keyring.h" 75 #include "errors.h" 76 #include "packet-show.h" 77 #include "create.h" 78 #include "netpgpsdk.h" 79 #include "memory.h" 80 #include "validate.h" 81 #include "readerwriter.h" 82 #include "netpgpdefs.h" 83 #include "crypto.h" 84 #include "ssh2pgp.h" 85 #include "defs.h" 86 87 /* read any gpg config file */ 88 static int 89 conffile(netpgp_t *netpgp, char *homedir, char *userid, size_t length) 90 { 91 regmatch_t matchv[10]; 92 regex_t keyre; 93 char buf[BUFSIZ]; 94 FILE *fp; 95 96 __PGP_USED(netpgp); 97 (void) snprintf(buf, sizeof(buf), "%s/gpg.conf", homedir); 98 if ((fp = fopen(buf, "r")) == NULL) { 99 return 0; 100 } 101 (void) memset(&keyre, 0x0, sizeof(keyre)); 102 (void) regcomp(&keyre, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)", 103 REG_EXTENDED); 104 while (fgets(buf, (int)sizeof(buf), fp) != NULL) { 105 if (regexec(&keyre, buf, 10, matchv, 0) == 0) { 106 (void) memcpy(userid, &buf[(int)matchv[1].rm_so], 107 MIN((unsigned)(matchv[1].rm_eo - 108 matchv[1].rm_so), length)); 109 if (netpgp->passfp == NULL) { 110 (void) fprintf(stderr, 111 "netpgp: default key set to \"%.*s\"\n", 112 (int)(matchv[1].rm_eo - matchv[1].rm_so), 113 &buf[(int)matchv[1].rm_so]); 114 } 115 } 116 } 117 (void) fclose(fp); 118 regfree(&keyre); 119 return 1; 120 } 121 122 /* small function to pretty print an 8-character raw userid */ 123 static char * 124 userid_to_id(const uint8_t *userid, char *id) 125 { 126 static const char *hexes = "0123456789abcdef"; 127 int i; 128 129 for (i = 0; i < 8 ; i++) { 130 id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4]; 131 id[(i * 2) + 1] = hexes[userid[i] & 0xf]; 132 } 133 id[8 * 2] = 0x0; 134 return id; 135 } 136 137 /* print out the successful signature information */ 138 static void 139 resultp(pgp_io_t *io, 140 const char *f, 141 pgp_validation_t *res, 142 pgp_keyring_t *ring) 143 { 144 const pgp_key_t *key; 145 pgp_pubkey_t *sigkey; 146 unsigned from; 147 unsigned i; 148 time_t t; 149 char id[MAX_ID_LENGTH + 1]; 150 151 for (i = 0; i < res->validc; i++) { 152 (void) fprintf(io->res, 153 "Good signature for %s made %s", 154 (f) ? f : "<stdin>", 155 ctime(&res->valid_sigs[i].birthtime)); 156 if (res->duration > 0) { 157 t = res->birthtime + res->duration; 158 (void) fprintf(io->res, "Valid until %s", ctime(&t)); 159 } 160 (void) fprintf(io->res, 161 "using %s key %s\n", 162 pgp_show_pka(res->valid_sigs[i].key_alg), 163 userid_to_id(res->valid_sigs[i].signer_id, id)); 164 from = 0; 165 key = pgp_getkeybyid(io, ring, 166 (const uint8_t *) res->valid_sigs[i].signer_id, 167 &from, &sigkey); 168 if (sigkey == &key->enckey) { 169 (void) fprintf(io->res, 170 "WARNING: signature for %s made with encryption key\n", 171 (f) ? f : "<stdin>"); 172 } 173 pgp_print_keydata(io, ring, key, "signature ", &key->key.pubkey, 0); 174 } 175 } 176 177 /* check there's enough space in the arrays */ 178 static int 179 size_arrays(netpgp_t *netpgp, unsigned needed) 180 { 181 char **temp; 182 183 if (netpgp->size == 0) { 184 /* only get here first time around */ 185 netpgp->size = needed; 186 if ((netpgp->name = calloc(sizeof(char *), needed)) == NULL) { 187 (void) fprintf(stderr, "size_arrays: bad alloc\n"); 188 return 0; 189 } 190 if ((netpgp->value = calloc(sizeof(char *), needed)) == NULL) { 191 free(netpgp->name); 192 (void) fprintf(stderr, "size_arrays: bad alloc\n"); 193 return 0; 194 } 195 } else if (netpgp->c == netpgp->size) { 196 /* only uses 'needed' when filled array */ 197 netpgp->size += needed; 198 temp = realloc(netpgp->name, sizeof(char *) * needed); 199 if (temp == NULL) { 200 (void) fprintf(stderr, "size_arrays: bad alloc\n"); 201 return 0; 202 } 203 netpgp->name = temp; 204 temp = realloc(netpgp->value, sizeof(char *) * needed); 205 if (temp == NULL) { 206 (void) fprintf(stderr, "size_arrays: bad alloc\n"); 207 return 0; 208 } 209 netpgp->value = temp; 210 } 211 return 1; 212 } 213 214 /* find the name in the array */ 215 static int 216 findvar(netpgp_t *netpgp, const char *name) 217 { 218 unsigned i; 219 220 for (i = 0 ; i < netpgp->c && strcmp(netpgp->name[i], name) != 0; i++) { 221 } 222 return (i == netpgp->c) ? -1 : (int)i; 223 } 224 225 /* read a keyring and return it */ 226 static void * 227 readkeyring(netpgp_t *netpgp, const char *name) 228 { 229 pgp_keyring_t *keyring; 230 const unsigned noarmor = 0; 231 char f[MAXPATHLEN]; 232 char *filename; 233 char *homedir; 234 235 homedir = netpgp_getvar(netpgp, "homedir"); 236 if ((filename = netpgp_getvar(netpgp, name)) == NULL) { 237 (void) snprintf(f, sizeof(f), "%s/%s.gpg", homedir, name); 238 filename = f; 239 } 240 if ((keyring = calloc(1, sizeof(*keyring))) == NULL) { 241 (void) fprintf(stderr, "readkeyring: bad alloc\n"); 242 return NULL; 243 } 244 if (!pgp_keyring_fileread(keyring, noarmor, filename)) { 245 free(keyring); 246 (void) fprintf(stderr, "Can't read %s %s\n", name, filename); 247 return NULL; 248 } 249 netpgp_setvar(netpgp, name, filename); 250 return keyring; 251 } 252 253 /* read keys from ssh key files */ 254 static int 255 readsshkeys(netpgp_t *netpgp, char *homedir, const char *needseckey) 256 { 257 pgp_keyring_t *pubring; 258 pgp_keyring_t *secring; 259 struct stat st; 260 unsigned hashtype; 261 char *hash; 262 char f[MAXPATHLEN]; 263 char *filename; 264 265 if ((filename = netpgp_getvar(netpgp, "sshkeyfile")) == NULL) { 266 /* set reasonable default for RSA key */ 267 (void) snprintf(f, sizeof(f), "%s/id_rsa.pub", homedir); 268 filename = f; 269 } else if (strcmp(&filename[strlen(filename) - 4], ".pub") != 0) { 270 /* got ssh keys, check for pub file name */ 271 (void) snprintf(f, sizeof(f), "%s.pub", filename); 272 filename = f; 273 } 274 /* check the pub file exists */ 275 if (stat(filename, &st) != 0) { 276 (void) fprintf(stderr, "readsshkeys: bad pubkey filename '%s'\n", filename); 277 return 0; 278 } 279 if ((pubring = calloc(1, sizeof(*pubring))) == NULL) { 280 (void) fprintf(stderr, "readsshkeys: bad alloc\n"); 281 return 0; 282 } 283 /* openssh2 keys use md5 by default */ 284 hashtype = PGP_HASH_MD5; 285 if ((hash = netpgp_getvar(netpgp, "hash")) != NULL) { 286 /* openssh 2 hasn't really caught up to anything else yet */ 287 if (netpgp_strcasecmp(hash, "md5") == 0) { 288 hashtype = PGP_HASH_MD5; 289 } else if (netpgp_strcasecmp(hash, "sha1") == 0) { 290 hashtype = PGP_HASH_SHA1; 291 } else if (netpgp_strcasecmp(hash, "sha256") == 0) { 292 hashtype = PGP_HASH_SHA256; 293 } 294 } 295 if (!pgp_ssh2_readkeys(netpgp->io, pubring, NULL, filename, NULL, hashtype)) { 296 free(pubring); 297 (void) fprintf(stderr, "readsshkeys: can't read %s\n", 298 filename); 299 return 0; 300 } 301 if (netpgp->pubring == NULL) { 302 netpgp->pubring = pubring; 303 } else { 304 pgp_append_keyring(netpgp->pubring, pubring); 305 } 306 if (needseckey) { 307 netpgp_setvar(netpgp, "sshpubfile", filename); 308 /* try to take the ".pub" off the end */ 309 if (filename == f) { 310 f[strlen(f) - 4] = 0x0; 311 } else { 312 (void) snprintf(f, sizeof(f), "%.*s", 313 (int)strlen(filename) - 4, filename); 314 filename = f; 315 } 316 if ((secring = calloc(1, sizeof(*secring))) == NULL) { 317 free(pubring); 318 (void) fprintf(stderr, "readsshkeys: bad alloc\n"); 319 return 0; 320 } 321 if (!pgp_ssh2_readkeys(netpgp->io, pubring, secring, NULL, filename, hashtype)) { 322 free(pubring); 323 free(secring); 324 (void) fprintf(stderr, "readsshkeys: can't read sec %s\n", filename); 325 return 0; 326 } 327 netpgp->secring = secring; 328 netpgp_setvar(netpgp, "sshsecfile", filename); 329 } 330 return 1; 331 } 332 333 /* get the uid of the first key in the keyring */ 334 static int 335 get_first_ring(pgp_keyring_t *ring, char *id, size_t len, int last) 336 { 337 uint8_t *src; 338 int i; 339 int n; 340 341 if (ring == NULL) { 342 return 0; 343 } 344 (void) memset(id, 0x0, len); 345 src = ring->keys[(last) ? ring->keyc - 1 : 0].sigid; 346 for (i = 0, n = 0 ; i < PGP_KEY_ID_SIZE ; i += 2) { 347 n += snprintf(&id[n], len - n, "%02x%02x", src[i], src[i + 1]); 348 } 349 id[n] = 0x0; 350 return 1; 351 } 352 353 /* find the time - in a specific %Y-%m-%d format - using a regexp */ 354 static int 355 grabdate(char *s, int64_t *t) 356 { 357 static regex_t r; 358 static int compiled; 359 regmatch_t matches[10]; 360 struct tm tm; 361 362 if (!compiled) { 363 compiled = 1; 364 (void) regcomp(&r, "([0-9][0-9][0-9][0-9])[-/]([0-9][0-9])[-/]([0-9][0-9])", REG_EXTENDED); 365 } 366 if (regexec(&r, s, 10, matches, 0) == 0) { 367 (void) memset(&tm, 0x0, sizeof(tm)); 368 tm.tm_year = (int)strtol(&s[(int)matches[1].rm_so], NULL, 10); 369 tm.tm_mon = (int)strtol(&s[(int)matches[2].rm_so], NULL, 10) - 1; 370 tm.tm_mday = (int)strtol(&s[(int)matches[3].rm_so], NULL, 10); 371 *t = mktime(&tm); 372 return 1; 373 } 374 return 0; 375 } 376 377 /* get expiration in seconds */ 378 static uint64_t 379 get_duration(char *s) 380 { 381 uint64_t now; 382 int64_t t; 383 char *mult; 384 385 if (s == NULL) { 386 return 0; 387 } 388 now = (uint64_t)strtoull(s, NULL, 10); 389 if ((mult = strchr("hdwmy", s[strlen(s) - 1])) != NULL) { 390 switch(*mult) { 391 case 'h': 392 return now * 60 * 60; 393 case 'd': 394 return now * 60 * 60 * 24; 395 case 'w': 396 return now * 60 * 60 * 24 * 7; 397 case 'm': 398 return now * 60 * 60 * 24 * 31; 399 case 'y': 400 return now * 60 * 60 * 24 * 365; 401 } 402 } 403 if (grabdate(s, &t)) { 404 return t; 405 } 406 return (uint64_t)strtoll(s, NULL, 10); 407 } 408 409 /* get birthtime in seconds */ 410 static int64_t 411 get_birthtime(char *s) 412 { 413 int64_t t; 414 415 if (s == NULL) { 416 return time(NULL); 417 } 418 if (grabdate(s, &t)) { 419 return t; 420 } 421 return (uint64_t)strtoll(s, NULL, 10); 422 } 423 424 /* resolve the userid */ 425 static const pgp_key_t * 426 resolve_userid(netpgp_t *netpgp, const pgp_keyring_t *keyring, const char *userid) 427 { 428 const pgp_key_t *key; 429 pgp_io_t *io; 430 431 if (userid == NULL) { 432 userid = netpgp_getvar(netpgp, "userid"); 433 if (userid == NULL) 434 return NULL; 435 } else if (userid[0] == '0' && userid[1] == 'x') { 436 userid += 2; 437 } 438 io = netpgp->io; 439 if ((key = pgp_getkeybyname(io, keyring, userid)) == NULL) { 440 (void) fprintf(io->errs, "Can't find key '%s'\n", userid); 441 } 442 return key; 443 } 444 445 /* append a key to a keyring */ 446 static int 447 appendkey(pgp_io_t *io, pgp_key_t *key, char *ringfile) 448 { 449 pgp_output_t *create; 450 const unsigned noarmor = 0; 451 int fd; 452 453 if ((fd = pgp_setup_file_append(&create, ringfile)) < 0) { 454 fd = pgp_setup_file_write(&create, ringfile, 0); 455 } 456 if (fd < 0) { 457 (void) fprintf(io->errs, "can't open pubring '%s'\n", ringfile); 458 return 0; 459 } 460 if (!pgp_write_xfer_pubkey(create, key, noarmor)) { 461 (void) fprintf(io->errs, "Cannot write pubkey\n"); 462 return 0; 463 } 464 pgp_teardown_file_write(create, fd); 465 return 1; 466 } 467 468 /* return 1 if the file contains ascii-armoured text */ 469 static unsigned 470 isarmoured(pgp_io_t *io, const char *f, const void *memory, const char *text) 471 { 472 regmatch_t matches[10]; 473 unsigned armoured; 474 regex_t r; 475 FILE *fp; 476 char buf[BUFSIZ]; 477 478 armoured = 0; 479 (void) regcomp(&r, text, REG_EXTENDED); 480 if (f) { 481 if ((fp = fopen(f, "r")) == NULL) { 482 (void) fprintf(io->errs, "isarmoured: can't open '%s'\n", f); 483 regfree(&r); 484 return 0; 485 } 486 if (fgets(buf, (int)sizeof(buf), fp) != NULL) { 487 if (regexec(&r, buf, 10, matches, 0) == 0) { 488 armoured = 1; 489 } 490 } 491 (void) fclose(fp); 492 } else { 493 if (regexec(&r, memory, 10, matches, 0) == 0) { 494 armoured = 1; 495 } 496 } 497 regfree(&r); 498 return armoured; 499 } 500 501 /* vararg print function */ 502 static void 503 p(FILE *fp, const char *s, ...) 504 { 505 va_list args; 506 507 va_start(args, s); 508 while (s != NULL) { 509 (void) fprintf(fp, "%s", s); 510 s = va_arg(args, char *); 511 } 512 va_end(args); 513 } 514 515 /* print a JSON object to the FILE stream */ 516 static void 517 pobj(FILE *fp, mj_t *obj, int depth) 518 { 519 unsigned i; 520 char *s; 521 522 if (obj == NULL) { 523 (void) fprintf(stderr, "No object found\n"); 524 return; 525 } 526 for (i = 0 ; i < (unsigned)depth ; i++) { 527 p(fp, " ", NULL); 528 } 529 switch(obj->type) { 530 case MJ_NULL: 531 case MJ_FALSE: 532 case MJ_TRUE: 533 p(fp, (obj->type == MJ_NULL) ? "null" : (obj->type == MJ_FALSE) ? "false" : "true", NULL); 534 break; 535 case MJ_NUMBER: 536 p(fp, obj->value.s, NULL); 537 break; 538 case MJ_STRING: 539 if ((i = mj_asprint(&s, obj, MJ_HUMAN)) > 2) { 540 (void) fprintf(fp, "%.*s", (int)i - 2, &s[1]); 541 free(s); 542 } 543 break; 544 case MJ_ARRAY: 545 for (i = 0 ; i < obj->c ; i++) { 546 pobj(fp, &obj->value.v[i], depth + 1); 547 if (i < obj->c - 1) { 548 (void) fprintf(fp, ", "); 549 } 550 } 551 (void) fprintf(fp, "\n"); 552 break; 553 case MJ_OBJECT: 554 for (i = 0 ; i < obj->c ; i += 2) { 555 pobj(fp, &obj->value.v[i], depth + 1); 556 p(fp, ": ", NULL); 557 pobj(fp, &obj->value.v[i + 1], 0); 558 if (i < obj->c - 1) { 559 p(fp, ", ", NULL); 560 } 561 } 562 p(fp, "\n", NULL); 563 break; 564 default: 565 break; 566 } 567 } 568 569 /* return the time as a string */ 570 static char * 571 ptimestr(char *dest, size_t size, time_t t) 572 { 573 struct tm *tm; 574 575 tm = gmtime(&t); 576 (void) snprintf(dest, size, "%04d-%02d-%02d", 577 tm->tm_year + 1900, 578 tm->tm_mon + 1, 579 tm->tm_mday); 580 return dest; 581 } 582 583 /* format a JSON object */ 584 static void 585 format_json_key(FILE *fp, mj_t *obj, const int psigs) 586 { 587 int64_t birthtime; 588 int64_t duration; 589 time_t now; 590 char tbuf[32]; 591 char *s; 592 mj_t *sub; 593 int i; 594 595 if (pgp_get_debug_level(__FILE__)) { 596 mj_asprint(&s, obj, MJ_HUMAN); 597 (void) fprintf(stderr, "formatobj: json is '%s'\n", s); 598 free(s); 599 } 600 if (obj->c == 2 && obj->value.v[1].type == MJ_STRING && 601 strcmp(obj->value.v[1].value.s, "[REVOKED]") == 0) { 602 /* whole key has been rovoked - just return */ 603 return; 604 } 605 pobj(fp, &obj->value.v[mj_object_find(obj, "header", 0, 2) + 1], 0); 606 p(fp, " ", NULL); 607 pobj(fp, &obj->value.v[mj_object_find(obj, "key bits", 0, 2) + 1], 0); 608 p(fp, "/", NULL); 609 pobj(fp, &obj->value.v[mj_object_find(obj, "pka", 0, 2) + 1], 0); 610 p(fp, " ", NULL); 611 pobj(fp, &obj->value.v[mj_object_find(obj, "key id", 0, 2) + 1], 0); 612 birthtime = (int64_t)strtoll(obj->value.v[mj_object_find(obj, "birthtime", 0, 2) + 1].value.s, NULL, 10); 613 p(fp, " ", ptimestr(tbuf, sizeof(tbuf), birthtime), NULL); 614 duration = (int64_t)strtoll(obj->value.v[mj_object_find(obj, "duration", 0, 2) + 1].value.s, NULL, 10); 615 if (duration > 0) { 616 now = time(NULL); 617 p(fp, " ", (birthtime + duration < now) ? "[EXPIRED " : "[EXPIRES ", 618 ptimestr(tbuf, sizeof(tbuf), birthtime + duration), "]", NULL); 619 } 620 p(fp, "\n", "Key fingerprint: ", NULL); 621 pobj(fp, &obj->value.v[mj_object_find(obj, "fingerprint", 0, 2) + 1], 0); 622 p(fp, "\n", NULL); 623 /* go to field after \"duration\" */ 624 for (i = mj_object_find(obj, "duration", 0, 2) + 2; i < mj_arraycount(obj) ; i += 2) { 625 if (strcmp(obj->value.v[i].value.s, "uid") == 0) { 626 sub = &obj->value.v[i + 1]; 627 p(fp, "uid", NULL); 628 pobj(fp, &sub->value.v[0], (psigs) ? 4 : 14); /* human name */ 629 pobj(fp, &sub->value.v[1], 1); /* any revocation */ 630 p(fp, "\n", NULL); 631 } else if (strcmp(obj->value.v[i].value.s, "encryption") == 0) { 632 sub = &obj->value.v[i + 1]; 633 p(fp, "encryption", NULL); 634 pobj(fp, &sub->value.v[0], 1); /* size */ 635 p(fp, "/", NULL); 636 pobj(fp, &sub->value.v[1], 0); /* alg */ 637 p(fp, " ", NULL); 638 pobj(fp, &sub->value.v[2], 0); /* id */ 639 p(fp, " ", ptimestr(tbuf, sizeof(tbuf), 640 (time_t)strtoll(sub->value.v[3].value.s, NULL, 10)), 641 "\n", NULL); 642 } else if (strcmp(obj->value.v[i].value.s, "sig") == 0) { 643 sub = &obj->value.v[i + 1]; 644 p(fp, "sig", NULL); 645 pobj(fp, &sub->value.v[0], 8); /* size */ 646 p(fp, " ", ptimestr(tbuf, sizeof(tbuf), 647 (time_t)strtoll(sub->value.v[1].value.s, NULL, 10)), 648 " ", NULL); /* time */ 649 pobj(fp, &sub->value.v[2], 0); /* human name */ 650 p(fp, "\n", NULL); 651 } else { 652 fprintf(stderr, "weird '%s'\n", obj->value.v[i].value.s); 653 pobj(fp, &obj->value.v[i], 0); /* human name */ 654 } 655 } 656 p(fp, "\n", NULL); 657 } 658 659 /* save a pgp pubkey to a temp file */ 660 static int 661 savepubkey(char *res, char *f, size_t size) 662 { 663 size_t len; 664 int cc; 665 int wc; 666 int fd; 667 668 (void) snprintf(f, size, "/tmp/pgp2ssh.XXXXXXX"); 669 if ((fd = mkstemp(f)) < 0) { 670 (void) fprintf(stderr, "can't create temp file '%s'\n", f); 671 return 0; 672 } 673 len = strlen(res); 674 for (cc = 0 ; (wc = (int)write(fd, &res[cc], len - (size_t)cc)) > 0 ; cc += wc) { 675 } 676 (void) close(fd); 677 return 1; 678 } 679 680 /* format a uint32_t */ 681 static int 682 formatu32(uint8_t *buffer, uint32_t value) 683 { 684 buffer[0] = (uint8_t)(value >> 24) & 0xff; 685 buffer[1] = (uint8_t)(value >> 16) & 0xff; 686 buffer[2] = (uint8_t)(value >> 8) & 0xff; 687 buffer[3] = (uint8_t)value & 0xff; 688 return sizeof(uint32_t); 689 } 690 691 /* format a string as (len, string) */ 692 static int 693 formatstring(char *buffer, const uint8_t *s, size_t len) 694 { 695 int cc; 696 697 cc = formatu32((uint8_t *)buffer, (uint32_t)len); 698 (void) memcpy(&buffer[cc], s, len); 699 return cc + (int)len; 700 } 701 702 /* format a bignum, checking for "interesting" high bit values */ 703 static int 704 formatbignum(char *buffer, BIGNUM *bn) 705 { 706 size_t len; 707 uint8_t *cp; 708 int cc; 709 710 len = (size_t) BN_num_bytes(bn); 711 if ((cp = calloc(1, len + 1)) == NULL) { 712 (void) fprintf(stderr, "calloc failure in formatbignum\n"); 713 return 0; 714 } 715 (void) BN_bn2bin(bn, cp + 1); 716 cp[0] = 0x0; 717 cc = (cp[1] & 0x80) ? formatstring(buffer, cp, len + 1) : formatstring(buffer, &cp[1], len); 718 free(cp); 719 return cc; 720 } 721 722 #define MAX_PASSPHRASE_ATTEMPTS 3 723 #define INFINITE_ATTEMPTS -1 724 725 /* get the passphrase from the user */ 726 static int 727 find_passphrase(FILE *passfp, const char *id, char *passphrase, size_t size, int attempts) 728 { 729 char prompt[BUFSIZ]; 730 char buf[128]; 731 char *cp; 732 int cc; 733 int i; 734 735 if (passfp) { 736 if (fgets(passphrase, (int)size, passfp) == NULL) { 737 return 0; 738 } 739 return (int)strlen(passphrase); 740 } 741 for (i = 0 ; i < attempts ; i++) { 742 (void) snprintf(prompt, sizeof(prompt), "Enter passphrase for %.16s: ", id); 743 if ((cp = getpass(prompt)) == NULL) { 744 break; 745 } 746 cc = snprintf(buf, sizeof(buf), "%s", cp); 747 (void) snprintf(prompt, sizeof(prompt), "Repeat passphrase for %.16s: ", id); 748 if ((cp = getpass(prompt)) == NULL) { 749 break; 750 } 751 cc = snprintf(passphrase, size, "%s", cp); 752 if (strcmp(buf, passphrase) == 0) { 753 (void) memset(buf, 0x0, sizeof(buf)); 754 return cc; 755 } 756 } 757 (void) memset(buf, 0x0, sizeof(buf)); 758 (void) memset(passphrase, 0x0, size); 759 return 0; 760 } 761 762 /***************************************************************************/ 763 /* exported functions start here */ 764 /***************************************************************************/ 765 766 /* initialise a netpgp_t structure */ 767 int 768 netpgp_init(netpgp_t *netpgp) 769 { 770 pgp_io_t *io; 771 time_t t; 772 char id[MAX_ID_LENGTH]; 773 char *homedir; 774 char *userid; 775 char *stream; 776 char *passfd; 777 char *results; 778 int coredumps; 779 int last; 780 781 #ifdef HAVE_SYS_RESOURCE_H 782 struct rlimit limit; 783 784 coredumps = netpgp_getvar(netpgp, "coredumps") != NULL; 785 if (!coredumps) { 786 (void) memset(&limit, 0x0, sizeof(limit)); 787 if (setrlimit(RLIMIT_CORE, &limit) != 0) { 788 (void) fprintf(stderr, 789 "netpgp: warning - can't turn off core dumps\n"); 790 coredumps = 1; 791 } 792 } 793 #else 794 coredumps = 1; 795 #endif 796 if ((io = calloc(1, sizeof(*io))) == NULL) { 797 (void) fprintf(stderr, "netpgp_init: bad alloc\n"); 798 return 0; 799 } 800 io->outs = stdout; 801 if ((stream = netpgp_getvar(netpgp, "outs")) != NULL && 802 strcmp(stream, "<stderr>") == 0) { 803 io->outs = stderr; 804 } 805 io->errs = stderr; 806 if ((stream = netpgp_getvar(netpgp, "errs")) != NULL && 807 strcmp(stream, "<stdout>") == 0) { 808 io->errs = stdout; 809 } 810 if ((results = netpgp_getvar(netpgp, "res")) == NULL) { 811 io->res = io->errs; 812 } else if (strcmp(results, "<stdout>") == 0) { 813 io->res = stdout; 814 } else if (strcmp(results, "<stderr>") == 0) { 815 io->res = stderr; 816 } else { 817 if ((io->res = fopen(results, "w")) == NULL) { 818 (void) fprintf(io->errs, "Can't open results %s for writing\n", 819 results); 820 free(io); 821 return 0; 822 } 823 } 824 netpgp->io = io; 825 /* get passphrase from an fd */ 826 if ((passfd = netpgp_getvar(netpgp, "pass-fd")) != NULL && 827 (netpgp->passfp = fdopen(atoi(passfd), "r")) == NULL) { 828 (void) fprintf(io->errs, "Can't open fd %s for reading\n", 829 passfd); 830 return 0; 831 } 832 /* warn if core dumps are enabled */ 833 if (coredumps) { 834 (void) fprintf(io->errs, 835 "netpgp: warning: core dumps enabled\n"); 836 } 837 /* get home directory - where keyrings are in a subdir */ 838 if ((homedir = netpgp_getvar(netpgp, "homedir")) == NULL) { 839 (void) fprintf(io->errs, "netpgp: bad homedir\n"); 840 return 0; 841 } 842 if (netpgp_getvar(netpgp, "ssh keys") == NULL) { 843 /* read from ordinary pgp keyrings */ 844 netpgp->pubring = readkeyring(netpgp, "pubring"); 845 if (netpgp->pubring == NULL) { 846 (void) fprintf(io->errs, "Can't read pub keyring\n"); 847 return 0; 848 } 849 /* if a userid has been given, we'll use it */ 850 if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) { 851 /* also search in config file for default id */ 852 (void) memset(id, 0x0, sizeof(id)); 853 (void) conffile(netpgp, homedir, id, sizeof(id)); 854 if (id[0] != 0x0) { 855 netpgp_setvar(netpgp, "userid", userid = id); 856 } 857 } 858 /* only read secret keys if we need to */ 859 if (netpgp_getvar(netpgp, "need seckey")) { 860 /* read the secret ring */ 861 netpgp->secring = readkeyring(netpgp, "secring"); 862 if (netpgp->secring == NULL) { 863 (void) fprintf(io->errs, "Can't read sec keyring\n"); 864 return 0; 865 } 866 /* now, if we don't have a valid user, use the first in secring */ 867 if (!userid && netpgp_getvar(netpgp, "need userid") != NULL) { 868 /* signing - need userid and sec key */ 869 (void) memset(id, 0x0, sizeof(id)); 870 if (get_first_ring(netpgp->secring, id, sizeof(id), 0)) { 871 netpgp_setvar(netpgp, "userid", userid = id); 872 } 873 } 874 } else if (netpgp_getvar(netpgp, "need userid") != NULL) { 875 /* encrypting - get first in pubring */ 876 if (!userid && get_first_ring(netpgp->pubring, id, sizeof(id), 0)) { 877 (void) netpgp_setvar(netpgp, "userid", userid = id); 878 } 879 } 880 if (!userid && netpgp_getvar(netpgp, "need userid")) { 881 /* if we don't have a user id, and we need one, fail */ 882 (void) fprintf(io->errs, "Cannot find user id\n"); 883 return 0; 884 } 885 } else { 886 /* read from ssh keys */ 887 last = (netpgp->pubring != NULL); 888 if (!readsshkeys(netpgp, homedir, netpgp_getvar(netpgp, "need seckey"))) { 889 (void) fprintf(io->errs, "Can't read ssh keys\n"); 890 return 0; 891 } 892 if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) { 893 get_first_ring(netpgp->pubring, id, sizeof(id), last); 894 netpgp_setvar(netpgp, "userid", userid = id); 895 } 896 if (userid == NULL) { 897 if (netpgp_getvar(netpgp, "need userid") != NULL) { 898 (void) fprintf(io->errs, 899 "Cannot find user id\n"); 900 return 0; 901 } 902 } else { 903 (void) netpgp_setvar(netpgp, "userid", userid); 904 } 905 } 906 t = time(NULL); 907 netpgp_setvar(netpgp, "initialised", ctime(&t)); 908 return 1; 909 } 910 911 /* finish off with the netpgp_t struct */ 912 int 913 netpgp_end(netpgp_t *netpgp) 914 { 915 unsigned i; 916 917 for (i = 0 ; i < netpgp->c ; i++) { 918 if (netpgp->name[i] != NULL) { 919 free(netpgp->name[i]); 920 } 921 if (netpgp->value[i] != NULL) { 922 free(netpgp->value[i]); 923 } 924 } 925 if (netpgp->name != NULL) { 926 free(netpgp->name); 927 } 928 if (netpgp->value != NULL) { 929 free(netpgp->value); 930 } 931 if (netpgp->pubring != NULL) { 932 pgp_keyring_free(netpgp->pubring); 933 } 934 if (netpgp->secring != NULL) { 935 pgp_keyring_free(netpgp->secring); 936 } 937 free(netpgp->io); 938 return 1; 939 } 940 941 /* list the keys in a keyring */ 942 int 943 netpgp_list_keys(netpgp_t *netpgp, const int psigs) 944 { 945 if (netpgp->pubring == NULL) { 946 (void) fprintf(stderr, "No keyring\n"); 947 return 0; 948 } 949 return pgp_keyring_list(netpgp->io, netpgp->pubring, psigs); 950 } 951 952 /* list the keys in a keyring, returning a JSON encoded string */ 953 int 954 netpgp_list_keys_json(netpgp_t *netpgp, char **json, const int psigs) 955 { 956 mj_t obj; 957 int ret; 958 959 if (netpgp->pubring == NULL) { 960 (void) fprintf(stderr, "No keyring\n"); 961 return 0; 962 } 963 (void) memset(&obj, 0x0, sizeof(obj)); 964 if (!pgp_keyring_json(netpgp->io, netpgp->pubring, &obj, psigs)) { 965 (void) fprintf(stderr, "No keys in keyring\n"); 966 return 0; 967 } 968 ret = mj_asprint(json, &obj, MJ_JSON_ENCODE); 969 mj_delete(&obj); 970 return ret; 971 } 972 973 DEFINE_ARRAY(strings_t, char *); 974 975 #ifndef HKP_VERSION 976 #define HKP_VERSION 1 977 #endif 978 979 /* find and list some keys in a keyring */ 980 int 981 netpgp_match_keys(netpgp_t *netpgp, char *name, const char *fmt, void *vp, const int psigs) 982 { 983 const pgp_key_t *key; 984 unsigned k; 985 strings_t pubs; 986 FILE *fp = (FILE *)vp; 987 988 if (name[0] == '0' && name[1] == 'x') { 989 name += 2; 990 } 991 (void) memset(&pubs, 0x0, sizeof(pubs)); 992 k = 0; 993 do { 994 key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring, 995 name, &k); 996 if (key != NULL) { 997 ALLOC(char *, pubs.v, pubs.size, pubs.c, 10, 10, 998 "netpgp_match_keys", return 0); 999 if (strcmp(fmt, "mr") == 0) { 1000 pgp_hkp_sprint_keydata(netpgp->io, netpgp->pubring, 1001 key, &pubs.v[pubs.c], 1002 &key->key.pubkey, psigs); 1003 } else { 1004 pgp_sprint_keydata(netpgp->io, netpgp->pubring, 1005 key, &pubs.v[pubs.c], 1006 "signature ", 1007 &key->key.pubkey, psigs); 1008 } 1009 if (pubs.v[pubs.c] != NULL) { 1010 pubs.c += 1; 1011 } 1012 k += 1; 1013 } 1014 } while (key != NULL); 1015 if (strcmp(fmt, "mr") == 0) { 1016 (void) fprintf(fp, "info:%d:%d\n", HKP_VERSION, pubs.c); 1017 } else { 1018 (void) fprintf(fp, "%d key%s found\n", pubs.c, 1019 (pubs.c == 1) ? "" : "s"); 1020 } 1021 for (k = 0 ; k < pubs.c ; k++) { 1022 (void) fprintf(fp, "%s%s", pubs.v[k], (k < pubs.c - 1) ? "\n" : ""); 1023 free(pubs.v[k]); 1024 } 1025 free(pubs.v); 1026 return pubs.c; 1027 } 1028 1029 /* find and list some keys in a keyring - return JSON string */ 1030 int 1031 netpgp_match_keys_json(netpgp_t *netpgp, char **json, char *name, const char *fmt, const int psigs) 1032 { 1033 const pgp_key_t *key; 1034 unsigned k; 1035 mj_t id_array; 1036 char *newkey; 1037 int ret; 1038 1039 if (name[0] == '0' && name[1] == 'x') { 1040 name += 2; 1041 } 1042 (void) memset(&id_array, 0x0, sizeof(id_array)); 1043 k = 0; 1044 *json = NULL; 1045 mj_create(&id_array, "array"); 1046 do { 1047 key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring, 1048 name, &k); 1049 if (key != NULL) { 1050 if (strcmp(fmt, "mr") == 0) { 1051 pgp_hkp_sprint_keydata(netpgp->io, netpgp->pubring, 1052 key, &newkey, 1053 &key->key.pubkey, 0); 1054 if (newkey) { 1055 printf("%s\n", newkey); 1056 free(newkey); 1057 } 1058 } else { 1059 ALLOC(mj_t, id_array.value.v, id_array.size, 1060 id_array.c, 10, 10, "netpgp_match_keys_json", return 0); 1061 pgp_sprint_mj(netpgp->io, netpgp->pubring, 1062 key, &id_array.value.v[id_array.c++], 1063 "signature ", 1064 &key->key.pubkey, psigs); 1065 } 1066 k += 1; 1067 } 1068 } while (key != NULL); 1069 ret = mj_asprint(json, &id_array, MJ_JSON_ENCODE); 1070 mj_delete(&id_array); 1071 return ret; 1072 } 1073 1074 /* find and list some public keys in a keyring */ 1075 int 1076 netpgp_match_pubkeys(netpgp_t *netpgp, char *name, void *vp) 1077 { 1078 const pgp_key_t *key; 1079 unsigned k; 1080 ssize_t cc; 1081 char out[1024 * 64]; 1082 FILE *fp = (FILE *)vp; 1083 1084 k = 0; 1085 do { 1086 key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring, 1087 name, &k); 1088 if (key != NULL) { 1089 cc = pgp_sprint_pubkey(key, out, sizeof(out)); 1090 (void) fprintf(fp, "%.*s", (int)cc, out); 1091 k += 1; 1092 } 1093 } while (key != NULL); 1094 return k; 1095 } 1096 1097 /* find a key in a keyring */ 1098 int 1099 netpgp_find_key(netpgp_t *netpgp, char *id) 1100 { 1101 pgp_io_t *io; 1102 1103 io = netpgp->io; 1104 if (id == NULL) { 1105 (void) fprintf(io->errs, "NULL id to search for\n"); 1106 return 0; 1107 } 1108 return pgp_getkeybyname(netpgp->io, netpgp->pubring, id) != NULL; 1109 } 1110 1111 /* get a key in a keyring */ 1112 char * 1113 netpgp_get_key(netpgp_t *netpgp, const char *name, const char *fmt) 1114 { 1115 const pgp_key_t *key; 1116 char *newkey; 1117 1118 if ((key = resolve_userid(netpgp, netpgp->pubring, name)) == NULL) { 1119 return NULL; 1120 } 1121 if (strcmp(fmt, "mr") == 0) { 1122 return (pgp_hkp_sprint_keydata(netpgp->io, netpgp->pubring, 1123 key, &newkey, 1124 &key->key.pubkey, 1125 netpgp_getvar(netpgp, "subkey sigs") != NULL) > 0) ? newkey : NULL; 1126 } 1127 return (pgp_sprint_keydata(netpgp->io, netpgp->pubring, 1128 key, &newkey, "signature", 1129 &key->key.pubkey, 1130 netpgp_getvar(netpgp, "subkey sigs") != NULL) > 0) ? newkey : NULL; 1131 } 1132 1133 /* export a given key */ 1134 char * 1135 netpgp_export_key(netpgp_t *netpgp, char *name) 1136 { 1137 const pgp_key_t *key; 1138 pgp_io_t *io; 1139 1140 io = netpgp->io; 1141 if ((key = resolve_userid(netpgp, netpgp->pubring, name)) == NULL) { 1142 return NULL; 1143 } 1144 return pgp_export_key(io, key, NULL); 1145 } 1146 1147 #define IMPORT_ARMOR_HEAD "-----BEGIN PGP PUBLIC KEY BLOCK-----" 1148 1149 /* import a key into our keyring */ 1150 int 1151 netpgp_import_key(netpgp_t *netpgp, char *f) 1152 { 1153 pgp_io_t *io; 1154 unsigned realarmor; 1155 int done; 1156 1157 io = netpgp->io; 1158 realarmor = isarmoured(io, f, NULL, IMPORT_ARMOR_HEAD); 1159 done = pgp_keyring_fileread(netpgp->pubring, realarmor, f); 1160 if (!done) { 1161 (void) fprintf(io->errs, "Cannot import key from file %s\n", f); 1162 return 0; 1163 } 1164 return pgp_keyring_list(io, netpgp->pubring, 0); 1165 } 1166 1167 #define ID_OFFSET 38 1168 1169 /* generate a new key */ 1170 int 1171 netpgp_generate_key(netpgp_t *netpgp, char *id, int numbits) 1172 { 1173 pgp_output_t *create; 1174 const unsigned noarmor = 0; 1175 pgp_key_t *key; 1176 pgp_io_t *io; 1177 uint8_t *uid; 1178 char passphrase[128]; 1179 char newid[1024]; 1180 char filename[MAXPATHLEN]; 1181 char dir[MAXPATHLEN]; 1182 char *cp; 1183 char *ringfile; 1184 char *numtries; 1185 int attempts; 1186 int passc; 1187 int fd; 1188 int cc; 1189 1190 uid = NULL; 1191 io = netpgp->io; 1192 /* generate a new key */ 1193 if (id) { 1194 (void) snprintf(newid, sizeof(newid), "%s", id); 1195 } else { 1196 (void) snprintf(newid, sizeof(newid), 1197 "RSA %d-bit key <%s@localhost>", numbits, getenv("LOGNAME")); 1198 } 1199 uid = (uint8_t *)newid; 1200 key = pgp_rsa_new_selfsign_key(numbits, 65537UL, uid, 1201 netpgp_getvar(netpgp, "hash"), 1202 netpgp_getvar(netpgp, "cipher")); 1203 if (key == NULL) { 1204 (void) fprintf(io->errs, "Cannot generate key\n"); 1205 return 0; 1206 } 1207 cp = NULL; 1208 pgp_sprint_keydata(netpgp->io, NULL, key, &cp, "signature ", &key->key.seckey.pubkey, 0); 1209 (void) fprintf(stdout, "%s", cp); 1210 /* write public key */ 1211 cc = snprintf(dir, sizeof(dir), "%s/%.16s", netpgp_getvar(netpgp, "homedir"), &cp[ID_OFFSET]); 1212 netpgp_setvar(netpgp, "generated userid", &dir[cc - 16]); 1213 if (mkdir(dir, 0700) < 0) { 1214 (void) fprintf(io->errs, "can't mkdir '%s'\n", dir); 1215 return 0; 1216 } 1217 (void) fprintf(io->errs, "netpgp: generated keys in directory %s\n", dir); 1218 (void) snprintf(ringfile = filename, sizeof(filename), "%s/pubring.gpg", dir); 1219 if (!appendkey(io, key, ringfile)) { 1220 (void) fprintf(io->errs, "Cannot write pubkey to '%s'\n", ringfile); 1221 return 0; 1222 } 1223 if (netpgp->pubring != NULL) { 1224 pgp_keyring_free(netpgp->pubring); 1225 } 1226 /* write secret key */ 1227 (void) snprintf(ringfile = filename, sizeof(filename), "%s/secring.gpg", dir); 1228 if ((fd = pgp_setup_file_append(&create, ringfile)) < 0) { 1229 fd = pgp_setup_file_write(&create, ringfile, 0); 1230 } 1231 if (fd < 0) { 1232 (void) fprintf(io->errs, "can't append secring '%s'\n", ringfile); 1233 return 0; 1234 } 1235 /* get the passphrase */ 1236 if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL || 1237 (attempts = atoi(numtries)) <= 0) { 1238 attempts = MAX_PASSPHRASE_ATTEMPTS; 1239 } else if (strcmp(numtries, "unlimited") == 0) { 1240 attempts = INFINITE_ATTEMPTS; 1241 } 1242 passc = find_passphrase(netpgp->passfp, &cp[ID_OFFSET], passphrase, sizeof(passphrase), attempts); 1243 if (!pgp_write_xfer_seckey(create, key, (uint8_t *)passphrase, (const unsigned)passc, noarmor)) { 1244 (void) fprintf(io->errs, "Cannot write seckey\n"); 1245 return 0; 1246 } 1247 pgp_teardown_file_write(create, fd); 1248 if (netpgp->secring != NULL) { 1249 pgp_keyring_free(netpgp->secring); 1250 } 1251 pgp_keydata_free(key); 1252 free(cp); 1253 return 1; 1254 } 1255 1256 /* encrypt a file */ 1257 int 1258 netpgp_encrypt_file(netpgp_t *netpgp, 1259 const char *userid, 1260 const char *f, 1261 char *out, 1262 int armored) 1263 { 1264 const pgp_key_t *key; 1265 const unsigned overwrite = 1; 1266 const char *suffix; 1267 pgp_io_t *io; 1268 char outname[MAXPATHLEN]; 1269 1270 io = netpgp->io; 1271 if (f == NULL) { 1272 (void) fprintf(io->errs, 1273 "netpgp_encrypt_file: no filename specified\n"); 1274 return 0; 1275 } 1276 suffix = (armored) ? ".asc" : ".gpg"; 1277 /* get key with which to sign */ 1278 if ((key = resolve_userid(netpgp, netpgp->pubring, userid)) == NULL) { 1279 return 0; 1280 } 1281 if (out == NULL) { 1282 (void) snprintf(outname, sizeof(outname), "%s%s", f, suffix); 1283 out = outname; 1284 } 1285 return (int)pgp_encrypt_file(io, f, out, key, (unsigned)armored, 1286 overwrite, netpgp_getvar(netpgp, "cipher")); 1287 } 1288 1289 #define ARMOR_HEAD "-----BEGIN PGP MESSAGE-----" 1290 1291 /* decrypt a file */ 1292 int 1293 netpgp_decrypt_file(netpgp_t *netpgp, const char *f, char *out, int armored) 1294 { 1295 const unsigned overwrite = 1; 1296 pgp_io_t *io; 1297 unsigned realarmor; 1298 unsigned sshkeys; 1299 char *numtries; 1300 int attempts; 1301 1302 __PGP_USED(armored); 1303 io = netpgp->io; 1304 if (f == NULL) { 1305 (void) fprintf(io->errs, 1306 "netpgp_decrypt_file: no filename specified\n"); 1307 return 0; 1308 } 1309 realarmor = isarmoured(io, f, NULL, ARMOR_HEAD); 1310 sshkeys = (unsigned)(netpgp_getvar(netpgp, "ssh keys") != NULL); 1311 if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL || 1312 (attempts = atoi(numtries)) <= 0) { 1313 attempts = MAX_PASSPHRASE_ATTEMPTS; 1314 } else if (strcmp(numtries, "unlimited") == 0) { 1315 attempts = INFINITE_ATTEMPTS; 1316 } 1317 return pgp_decrypt_file(netpgp->io, f, out, netpgp->secring, 1318 netpgp->pubring, 1319 realarmor, overwrite, sshkeys, 1320 netpgp->passfp, attempts, get_passphrase_cb); 1321 } 1322 1323 /* sign a file */ 1324 int 1325 netpgp_sign_file(netpgp_t *netpgp, 1326 const char *userid, 1327 const char *f, 1328 char *out, 1329 int armored, 1330 int cleartext, 1331 int detached) 1332 { 1333 const pgp_key_t *keypair; 1334 const pgp_key_t *pubkey; 1335 const unsigned overwrite = 1; 1336 pgp_seckey_t *seckey; 1337 const char *hashalg; 1338 pgp_io_t *io; 1339 char *numtries; 1340 int attempts; 1341 int ret; 1342 int i; 1343 1344 io = netpgp->io; 1345 if (f == NULL) { 1346 (void) fprintf(io->errs, 1347 "netpgp_sign_file: no filename specified\n"); 1348 return 0; 1349 } 1350 /* get key with which to sign */ 1351 if ((keypair = resolve_userid(netpgp, netpgp->secring, userid)) == NULL) { 1352 return 0; 1353 } 1354 ret = 1; 1355 if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL || 1356 (attempts = atoi(numtries)) <= 0) { 1357 attempts = MAX_PASSPHRASE_ATTEMPTS; 1358 } else if (strcmp(numtries, "unlimited") == 0) { 1359 attempts = INFINITE_ATTEMPTS; 1360 } 1361 for (i = 0, seckey = NULL ; !seckey && (i < attempts || attempts == INFINITE_ATTEMPTS) ; i++) { 1362 if (netpgp->passfp == NULL) { 1363 /* print out the user id */ 1364 pubkey = pgp_getkeybyname(io, netpgp->pubring, userid); 1365 if (pubkey == NULL) { 1366 (void) fprintf(io->errs, 1367 "netpgp: warning - using pubkey from secring\n"); 1368 pgp_print_keydata(io, netpgp->pubring, keypair, "signature ", 1369 &keypair->key.seckey.pubkey, 0); 1370 } else { 1371 pgp_print_keydata(io, netpgp->pubring, pubkey, "signature ", 1372 &pubkey->key.pubkey, 0); 1373 } 1374 } 1375 if (netpgp_getvar(netpgp, "ssh keys") == NULL) { 1376 /* now decrypt key */ 1377 seckey = pgp_decrypt_seckey(keypair, netpgp->passfp); 1378 if (seckey == NULL) { 1379 (void) fprintf(io->errs, "Bad passphrase\n"); 1380 } 1381 } else { 1382 pgp_keyring_t *secring; 1383 1384 secring = netpgp->secring; 1385 seckey = &secring->keys[0].key.seckey; 1386 } 1387 } 1388 if (seckey == NULL) { 1389 (void) fprintf(io->errs, "Bad passphrase\n"); 1390 return 0; 1391 } 1392 /* sign file */ 1393 hashalg = netpgp_getvar(netpgp, "hash"); 1394 if (seckey->pubkey.alg == PGP_PKA_DSA) { 1395 hashalg = "sha1"; 1396 } 1397 if (detached) { 1398 ret = pgp_sign_detached(io, f, out, seckey, hashalg, 1399 get_birthtime(netpgp_getvar(netpgp, "birthtime")), 1400 get_duration(netpgp_getvar(netpgp, "duration")), 1401 (unsigned)armored, 1402 overwrite); 1403 } else { 1404 ret = pgp_sign_file(io, f, out, seckey, hashalg, 1405 get_birthtime(netpgp_getvar(netpgp, "birthtime")), 1406 get_duration(netpgp_getvar(netpgp, "duration")), 1407 (unsigned)armored, (unsigned)cleartext, 1408 overwrite); 1409 } 1410 pgp_forget(seckey, (unsigned)sizeof(*seckey)); 1411 return ret; 1412 } 1413 1414 #define ARMOR_SIG_HEAD "-----BEGIN PGP (SIGNATURE|SIGNED MESSAGE)-----" 1415 1416 /* verify a file */ 1417 int 1418 netpgp_verify_file(netpgp_t *netpgp, const char *in, const char *out, int armored) 1419 { 1420 pgp_validation_t result; 1421 pgp_io_t *io; 1422 unsigned realarmor; 1423 1424 __PGP_USED(armored); 1425 (void) memset(&result, 0x0, sizeof(result)); 1426 io = netpgp->io; 1427 if (in == NULL) { 1428 (void) fprintf(io->errs, 1429 "netpgp_verify_file: no filename specified\n"); 1430 return 0; 1431 } 1432 realarmor = isarmoured(io, in, NULL, ARMOR_SIG_HEAD); 1433 if (pgp_validate_file(io, &result, in, out, (const int)realarmor, netpgp->pubring)) { 1434 resultp(io, in, &result, netpgp->pubring); 1435 return 1; 1436 } 1437 if (result.validc + result.invalidc + result.unknownc == 0) { 1438 (void) fprintf(io->errs, 1439 "\"%s\": No signatures found - is this a signed file?\n", 1440 in); 1441 } else if (result.invalidc == 0 && result.unknownc == 0) { 1442 (void) fprintf(io->errs, 1443 "\"%s\": file verification failure: invalid signature time\n", in); 1444 } else { 1445 (void) fprintf(io->errs, 1446 "\"%s\": verification failure: %u invalid signatures, %u unknown signatures\n", 1447 in, result.invalidc, result.unknownc); 1448 } 1449 return 0; 1450 } 1451 1452 /* sign some memory */ 1453 int 1454 netpgp_sign_memory(netpgp_t *netpgp, 1455 const char *userid, 1456 char *mem, 1457 size_t size, 1458 char *out, 1459 size_t outsize, 1460 const unsigned armored, 1461 const unsigned cleartext) 1462 { 1463 const pgp_key_t *keypair; 1464 const pgp_key_t *pubkey; 1465 pgp_seckey_t *seckey; 1466 pgp_memory_t *signedmem; 1467 const char *hashalg; 1468 pgp_io_t *io; 1469 char *numtries; 1470 int attempts; 1471 int ret; 1472 int i; 1473 1474 io = netpgp->io; 1475 if (mem == NULL) { 1476 (void) fprintf(io->errs, 1477 "netpgp_sign_memory: no memory to sign\n"); 1478 return 0; 1479 } 1480 if ((keypair = resolve_userid(netpgp, netpgp->secring, userid)) == NULL) { 1481 return 0; 1482 } 1483 ret = 1; 1484 if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL || 1485 (attempts = atoi(numtries)) <= 0) { 1486 attempts = MAX_PASSPHRASE_ATTEMPTS; 1487 } else if (strcmp(numtries, "unlimited") == 0) { 1488 attempts = INFINITE_ATTEMPTS; 1489 } 1490 for (i = 0, seckey = NULL ; !seckey && (i < attempts || attempts == INFINITE_ATTEMPTS) ; i++) { 1491 if (netpgp->passfp == NULL) { 1492 /* print out the user id */ 1493 pubkey = pgp_getkeybyname(io, netpgp->pubring, userid); 1494 if (pubkey == NULL) { 1495 (void) fprintf(io->errs, 1496 "netpgp: warning - using pubkey from secring\n"); 1497 pgp_print_keydata(io, netpgp->pubring, keypair, "signature ", 1498 &keypair->key.seckey.pubkey, 0); 1499 } else { 1500 pgp_print_keydata(io, netpgp->pubring, pubkey, "signature ", 1501 &pubkey->key.pubkey, 0); 1502 } 1503 } 1504 /* now decrypt key */ 1505 seckey = pgp_decrypt_seckey(keypair, netpgp->passfp); 1506 if (seckey == NULL) { 1507 (void) fprintf(io->errs, "Bad passphrase\n"); 1508 } 1509 } 1510 if (seckey == NULL) { 1511 (void) fprintf(io->errs, "Bad passphrase\n"); 1512 return 0; 1513 } 1514 /* sign file */ 1515 (void) memset(out, 0x0, outsize); 1516 hashalg = netpgp_getvar(netpgp, "hash"); 1517 if (seckey->pubkey.alg == PGP_PKA_DSA) { 1518 hashalg = "sha1"; 1519 } 1520 signedmem = pgp_sign_buf(io, mem, size, seckey, 1521 get_birthtime(netpgp_getvar(netpgp, "birthtime")), 1522 get_duration(netpgp_getvar(netpgp, "duration")), 1523 hashalg, armored, cleartext); 1524 if (signedmem) { 1525 size_t m; 1526 1527 m = MIN(pgp_mem_len(signedmem), outsize); 1528 (void) memcpy(out, pgp_mem_data(signedmem), m); 1529 pgp_memory_free(signedmem); 1530 ret = (int)m; 1531 } else { 1532 ret = 0; 1533 } 1534 pgp_forget(seckey, (unsigned)sizeof(*seckey)); 1535 return ret; 1536 } 1537 1538 /* verify memory */ 1539 int 1540 netpgp_verify_memory(netpgp_t *netpgp, const void *in, const size_t size, 1541 void *out, size_t outsize, const int armored) 1542 { 1543 pgp_validation_t result; 1544 pgp_memory_t *signedmem; 1545 pgp_memory_t *cat; 1546 pgp_io_t *io; 1547 size_t m; 1548 int ret; 1549 1550 (void) memset(&result, 0x0, sizeof(result)); 1551 io = netpgp->io; 1552 if (in == NULL) { 1553 (void) fprintf(io->errs, 1554 "netpgp_verify_memory: no memory to verify\n"); 1555 return 0; 1556 } 1557 signedmem = pgp_memory_new(); 1558 pgp_memory_add(signedmem, in, size); 1559 if (out) { 1560 cat = pgp_memory_new(); 1561 } 1562 ret = pgp_validate_mem(io, &result, signedmem, 1563 (out) ? &cat : NULL, 1564 armored, netpgp->pubring); 1565 /* signedmem is freed from pgp_validate_mem */ 1566 if (ret) { 1567 resultp(io, "<stdin>", &result, netpgp->pubring); 1568 if (out) { 1569 m = MIN(pgp_mem_len(cat), outsize); 1570 (void) memcpy(out, pgp_mem_data(cat), m); 1571 pgp_memory_free(cat); 1572 } else { 1573 m = 1; 1574 } 1575 return (int)m; 1576 } 1577 if (result.validc + result.invalidc + result.unknownc == 0) { 1578 (void) fprintf(io->errs, 1579 "No signatures found - is this memory signed?\n"); 1580 } else if (result.invalidc == 0 && result.unknownc == 0) { 1581 (void) fprintf(io->errs, 1582 "memory verification failure: invalid signature time\n"); 1583 } else { 1584 (void) fprintf(io->errs, 1585 "memory verification failure: %u invalid signatures, %u unknown signatures\n", 1586 result.invalidc, result.unknownc); 1587 } 1588 return 0; 1589 } 1590 1591 /* encrypt some memory */ 1592 int 1593 netpgp_encrypt_memory(netpgp_t *netpgp, 1594 const char *userid, 1595 void *in, 1596 const size_t insize, 1597 char *out, 1598 size_t outsize, 1599 int armored) 1600 { 1601 const pgp_key_t *keypair; 1602 pgp_memory_t *enc; 1603 pgp_io_t *io; 1604 size_t m; 1605 1606 io = netpgp->io; 1607 if (in == NULL) { 1608 (void) fprintf(io->errs, 1609 "netpgp_encrypt_buf: no memory to encrypt\n"); 1610 return 0; 1611 } 1612 if ((keypair = resolve_userid(netpgp, netpgp->pubring, userid)) == NULL) { 1613 return 0; 1614 } 1615 if (in == out) { 1616 (void) fprintf(io->errs, 1617 "netpgp_encrypt_buf: input and output bufs need to be different\n"); 1618 return 0; 1619 } 1620 if (outsize < insize) { 1621 (void) fprintf(io->errs, 1622 "netpgp_encrypt_buf: input size is larger than output size\n"); 1623 return 0; 1624 } 1625 enc = pgp_encrypt_buf(io, in, insize, keypair, (unsigned)armored, 1626 netpgp_getvar(netpgp, "cipher")); 1627 m = MIN(pgp_mem_len(enc), outsize); 1628 (void) memcpy(out, pgp_mem_data(enc), m); 1629 pgp_memory_free(enc); 1630 return (int)m; 1631 } 1632 1633 /* decrypt a chunk of memory */ 1634 int 1635 netpgp_decrypt_memory(netpgp_t *netpgp, const void *input, const size_t insize, 1636 char *out, size_t outsize, const int armored) 1637 { 1638 pgp_memory_t *mem; 1639 pgp_io_t *io; 1640 unsigned realarmour; 1641 unsigned sshkeys; 1642 size_t m; 1643 char *numtries; 1644 int attempts; 1645 1646 __PGP_USED(armored); 1647 io = netpgp->io; 1648 if (input == NULL) { 1649 (void) fprintf(io->errs, 1650 "netpgp_decrypt_memory: no memory\n"); 1651 return 0; 1652 } 1653 realarmour = isarmoured(io, NULL, input, ARMOR_HEAD); 1654 sshkeys = (unsigned)(netpgp_getvar(netpgp, "ssh keys") != NULL); 1655 if ((numtries = netpgp_getvar(netpgp, "numtries")) == NULL || 1656 (attempts = atoi(numtries)) <= 0) { 1657 attempts = MAX_PASSPHRASE_ATTEMPTS; 1658 } else if (strcmp(numtries, "unlimited") == 0) { 1659 attempts = INFINITE_ATTEMPTS; 1660 } 1661 mem = pgp_decrypt_buf(netpgp->io, input, insize, netpgp->secring, 1662 netpgp->pubring, 1663 realarmour, sshkeys, 1664 netpgp->passfp, 1665 attempts, 1666 get_passphrase_cb); 1667 if (mem == NULL) { 1668 return -1; 1669 } 1670 m = MIN(pgp_mem_len(mem), outsize); 1671 (void) memcpy(out, pgp_mem_data(mem), m); 1672 pgp_memory_free(mem); 1673 return (int)m; 1674 } 1675 1676 /* wrappers for the ops_debug_level functions we added to openpgpsdk */ 1677 1678 /* set the debugging level per filename */ 1679 int 1680 netpgp_set_debug(const char *f) 1681 { 1682 return pgp_set_debug_level(f); 1683 } 1684 1685 /* get the debugging level per filename */ 1686 int 1687 netpgp_get_debug(const char *f) 1688 { 1689 return pgp_get_debug_level(f); 1690 } 1691 1692 /* return the version for the library */ 1693 const char * 1694 netpgp_get_info(const char *type) 1695 { 1696 return pgp_get_info(type); 1697 } 1698 1699 /* list all the packets in a file */ 1700 int 1701 netpgp_list_packets(netpgp_t *netpgp, char *f, int armor, char *pubringname) 1702 { 1703 pgp_keyring_t *keyring; 1704 const unsigned noarmor = 0; 1705 struct stat st; 1706 pgp_io_t *io; 1707 char ringname[MAXPATHLEN]; 1708 char *homedir; 1709 int ret; 1710 1711 io = netpgp->io; 1712 if (f == NULL) { 1713 (void) fprintf(io->errs, "No file containing packets\n"); 1714 return 0; 1715 } 1716 if (stat(f, &st) < 0) { 1717 (void) fprintf(io->errs, "No such file '%s'\n", f); 1718 return 0; 1719 } 1720 homedir = netpgp_getvar(netpgp, "homedir"); 1721 if (pubringname == NULL) { 1722 (void) snprintf(ringname, sizeof(ringname), 1723 "%s/pubring.gpg", homedir); 1724 pubringname = ringname; 1725 } 1726 if ((keyring = calloc(1, sizeof(*keyring))) == NULL) { 1727 (void) fprintf(io->errs, "netpgp_list_packets: bad alloc\n"); 1728 return 0; 1729 } 1730 if (!pgp_keyring_fileread(keyring, noarmor, pubringname)) { 1731 free(keyring); 1732 (void) fprintf(io->errs, "Cannot read pub keyring %s\n", 1733 pubringname); 1734 return 0; 1735 } 1736 netpgp->pubring = keyring; 1737 netpgp_setvar(netpgp, "pubring", pubringname); 1738 ret = pgp_list_packets(io, f, (unsigned)armor, 1739 netpgp->secring, 1740 netpgp->pubring, 1741 netpgp->passfp, 1742 get_passphrase_cb); 1743 free(keyring); 1744 return ret; 1745 } 1746 1747 /* set a variable */ 1748 int 1749 netpgp_setvar(netpgp_t *netpgp, const char *name, const char *value) 1750 { 1751 char *newval; 1752 int i; 1753 1754 /* protect against the case where 'value' is netpgp->value[i] */ 1755 newval = netpgp_strdup(value); 1756 if ((i = findvar(netpgp, name)) < 0) { 1757 /* add the element to the array */ 1758 if (size_arrays(netpgp, netpgp->size + 15)) { 1759 netpgp->name[i = netpgp->c++] = netpgp_strdup(name); 1760 } 1761 } else { 1762 /* replace the element in the array */ 1763 if (netpgp->value[i]) { 1764 free(netpgp->value[i]); 1765 netpgp->value[i] = NULL; 1766 } 1767 } 1768 /* sanity checks for range of values */ 1769 if (strcmp(name, "hash") == 0 || strcmp(name, "algorithm") == 0) { 1770 if (pgp_str_to_hash_alg(newval) == PGP_HASH_UNKNOWN) { 1771 free(newval); 1772 return 0; 1773 } 1774 } 1775 netpgp->value[i] = newval; 1776 return 1; 1777 } 1778 1779 /* unset a variable */ 1780 int 1781 netpgp_unsetvar(netpgp_t *netpgp, const char *name) 1782 { 1783 int i; 1784 1785 if ((i = findvar(netpgp, name)) >= 0) { 1786 if (netpgp->value[i]) { 1787 free(netpgp->value[i]); 1788 netpgp->value[i] = NULL; 1789 } 1790 netpgp->value[i] = NULL; 1791 return 1; 1792 } 1793 return 0; 1794 } 1795 1796 /* get a variable's value (NULL if not set) */ 1797 char * 1798 netpgp_getvar(netpgp_t *netpgp, const char *name) 1799 { 1800 int i; 1801 1802 return ((i = findvar(netpgp, name)) < 0) ? NULL : netpgp->value[i]; 1803 } 1804 1805 /* increment a value */ 1806 int 1807 netpgp_incvar(netpgp_t *netpgp, const char *name, const int delta) 1808 { 1809 char *cp; 1810 char num[16]; 1811 int val; 1812 1813 val = 0; 1814 if ((cp = netpgp_getvar(netpgp, name)) != NULL) { 1815 val = atoi(cp); 1816 } 1817 (void) snprintf(num, sizeof(num), "%d", val + delta); 1818 netpgp_setvar(netpgp, name, num); 1819 return 1; 1820 } 1821 1822 /* set the home directory value to "home/subdir" */ 1823 int 1824 netpgp_set_homedir(netpgp_t *netpgp, char *home, const char *subdir, const int quiet) 1825 { 1826 struct stat st; 1827 char d[MAXPATHLEN]; 1828 1829 if (home == NULL) { 1830 if (!quiet) { 1831 (void) fprintf(stderr, "NULL HOME directory\n"); 1832 } 1833 return 0; 1834 } 1835 (void) snprintf(d, sizeof(d), "%s%s", home, (subdir) ? subdir : ""); 1836 if (stat(d, &st) == 0) { 1837 if ((st.st_mode & S_IFMT) == S_IFDIR) { 1838 netpgp_setvar(netpgp, "homedir", d); 1839 return 1; 1840 } 1841 (void) fprintf(stderr, "netpgp: homedir \"%s\" is not a dir\n", 1842 d); 1843 return 0; 1844 } 1845 if (!quiet) { 1846 (void) fprintf(stderr, 1847 "netpgp: warning homedir \"%s\" not found\n", d); 1848 } 1849 netpgp_setvar(netpgp, "homedir", d); 1850 return 1; 1851 } 1852 1853 /* validate all sigs in the pub keyring */ 1854 int 1855 netpgp_validate_sigs(netpgp_t *netpgp) 1856 { 1857 pgp_validation_t result; 1858 1859 return (int)pgp_validate_all_sigs(&result, netpgp->pubring, NULL); 1860 } 1861 1862 /* print the json out on 'fp' */ 1863 int 1864 netpgp_format_json(void *vp, const char *json, const int psigs) 1865 { 1866 mj_t ids; 1867 FILE *fp; 1868 int from; 1869 int idc; 1870 int tok; 1871 int to; 1872 int i; 1873 1874 if ((fp = (FILE *)vp) == NULL || json == NULL) { 1875 return 0; 1876 } 1877 /* ids is an array of strings, each containing 1 entry */ 1878 (void) memset(&ids, 0x0, sizeof(ids)); 1879 from = to = tok = 0; 1880 /* convert from string into an mj structure */ 1881 (void) mj_parse(&ids, json, &from, &to, &tok); 1882 if ((idc = mj_arraycount(&ids)) == 1 && strchr(json, '{') == NULL) { 1883 idc = 0; 1884 } 1885 (void) fprintf(fp, "%d key%s found\n", idc, (idc == 1) ? "" : "s"); 1886 for (i = 0 ; i < idc ; i++) { 1887 format_json_key(fp, &ids.value.v[i], psigs); 1888 } 1889 /* clean up */ 1890 mj_delete(&ids); 1891 return idc; 1892 } 1893 1894 /* find a key in keyring, and write it in ssh format */ 1895 int 1896 netpgp_write_sshkey(netpgp_t *netpgp, char *s, const char *userid, char *out, size_t size) 1897 { 1898 const pgp_key_t *key; 1899 pgp_keyring_t *keyring; 1900 pgp_io_t *io; 1901 unsigned k; 1902 size_t cc; 1903 char f[MAXPATHLEN]; 1904 1905 keyring = NULL; 1906 io = NULL; 1907 cc = 0; 1908 if ((io = calloc(1, sizeof(pgp_io_t))) == NULL) { 1909 (void) fprintf(stderr, "netpgp_save_sshpub: bad alloc 1\n"); 1910 goto done; 1911 } 1912 io->outs = stdout; 1913 io->errs = stderr; 1914 io->res = stderr; 1915 netpgp->io = io; 1916 /* write new to temp file */ 1917 savepubkey(s, f, sizeof(f)); 1918 if ((keyring = calloc(1, sizeof(*keyring))) == NULL) { 1919 (void) fprintf(stderr, "netpgp_save_sshpub: bad alloc 2\n"); 1920 goto done; 1921 } 1922 if (!pgp_keyring_fileread(netpgp->pubring = keyring, 1, f)) { 1923 (void) fprintf(stderr, "can't import key\n"); 1924 goto done; 1925 } 1926 /* get rsa key */ 1927 k = 0; 1928 key = pgp_getnextkeybyname(netpgp->io, netpgp->pubring, userid, &k); 1929 if (key == NULL) { 1930 (void) fprintf(stderr, "no key found for '%s'\n", userid); 1931 goto done; 1932 } 1933 if (key->key.pubkey.alg != PGP_PKA_RSA) { 1934 /* we're not interested in supporting DSA either :-) */ 1935 (void) fprintf(stderr, "key not RSA '%s'\n", userid); 1936 goto done; 1937 } 1938 /* XXX - check trust sigs */ 1939 /* XXX - check expiry */ 1940 /* XXX - check start */ 1941 /* XXX - check not weak key */ 1942 /* get rsa e and n */ 1943 (void) memset(out, 0x0, size); 1944 cc = formatstring((char *)out, (const uint8_t *)"ssh-rsa", 7); 1945 cc += formatbignum((char *)&out[cc], key->key.pubkey.key.rsa.e); 1946 cc += formatbignum((char *)&out[cc], key->key.pubkey.key.rsa.n); 1947 done: 1948 if (io) { 1949 free(io); 1950 } 1951 if (keyring) { 1952 free(keyring); 1953 } 1954 return (int)cc; 1955 } 1956