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