Annotation of pgp/src/keymaint.c, revision 1.1.1.1

1.1       root        1: /*     keymaint.c  - Keyring maintenance pass routines for PGP.
                      2:        PGP: Pretty Good(tm) Privacy - public key cryptography for the masses.
                      3: 
                      4:        (c) Copyright 1990-1992 by Philip Zimmermann.  All rights reserved.
                      5:        The author assumes no liability for damages resulting from the use
                      6:        of this software, even if the damage results from defects in this
                      7:        software.  No warranty is expressed or implied.
                      8: 
                      9:        All the source code Philip Zimmermann wrote for PGP is available for
                     10:        free under the "Copyleft" General Public License from the Free
                     11:        Software Foundation.  A copy of that license agreement is included in
                     12:        the source release package of PGP.  Code developed by others for PGP
                     13:        is also freely available.  Other code that has been incorporated into
                     14:        PGP from other sources was either originally published in the public
                     15:        domain or was used with permission from the various authors.  See the
                     16:        PGP User's Guide for more complete information about licensing,
                     17:        patent restrictions on certain algorithms, trademarks, copyrights,
                     18:        and export controls.  
                     19: 
                     20:        keymaint.c implemented by Branko Lankester.
                     21: */
                     22: 
                     23: #include <stdio.h>
                     24: #include <time.h>
                     25: #include "mpilib.h"
                     26: #include "random.h"
                     27: #include "crypto.h"
                     28: #include "fileio.h"
                     29: #include "keymgmt.h"
                     30: #include "mpiio.h"
                     31: #include "language.h"
                     32: #include "pgp.h"
                     33: 
                     34: 
                     35: void setup_trust();
                     36: int maint_pass1(FILE *f);
                     37: int maint_trace_chain(FILE *f);
                     38: int maint_cmpfiles(FILE *f, FILE *g);
                     39: int trace_sig_chain(FILE *f, byte *fromID, int owner_trust, int depth);
                     40: int check_secretkey(FILE *f, long keypos);
                     41: int set_legit(FILE *f, long trustpos, int trust_count);
                     42: long lookup_by_keyID(FILE *f, byte *srch_keyID);
                     43: void show_userid(FILE *f, byte *keyID);
                     44: int show_trust(byte, byte);
                     45: int show_legit(byte, byte);
                     46: void write_trust_pos(FILE *f, byte keyctrl, long pos);
                     47: 
                     48: /* returned when trying to do a maintenance pass on a secret keyring or keyfile */
                     49: #define        ERR_NOTRUST             -7
                     50: 
                     51: #define TRUST_MASK             7       /* mask for userid/signature trust bytes */
                     52: #define SET_TRUST(b,v) (*(b) = (*(b) & ~TRUST_MASK) | (v))
                     53: #define TRUST_LEV(b)   ((b) & TRUST_MASK)
                     54: 
                     55: #define        TRUST_FAC(x)    (trust_tbl[TRUST_LEV(x)])
                     56: 
                     57: /*
                     58:  * table for tuning user paranoia index.
                     59:  * values represent contribution of one signature indexed by the
                     60:  * SIGTRUST of a signature
                     61:  */
                     62: int trust_tbl[8];
                     63: 
                     64: static int marginal_min;
                     65: static int complete_min;       /* total count needed for a fully legit key */
                     66: 
                     67: int marg_min = 2;              /* number of marginally trusted signatures needed for
                     68:                                                   a fully legit key (can be set in config.pgp). */
                     69: int compl_min = 1;             /* number of fully trusted signatures needed */
                     70: 
                     71: char trust_lst[8][16] = {
                     72:        "undefined",            /* PSTR("undefined") */
                     73:        "unknown",                      /* PSTR("unknown") */
                     74:        "untrusted",            /* PSTR("untrusted") */
                     75:        "<3>",                          /* unused */
                     76:        "<4>",                          /* unused */
                     77:        "marginal",                     /* PSTR("marginal") */
                     78:        "complete",                     /* PSTR("complete") */
                     79:        "ultimate",                     /* PSTR("ultimate") */
                     80: };
                     81: 
                     82: char legit_lst[4][16] = {
                     83:        "undefined",
                     84:        "untrusted",
                     85:        "marginal",
                     86:        "complete"
                     87: };
                     88: 
                     89: int trustlst_len = 9;  /* length of longest trust word */
                     90: int legitlst_len = 9;  /* length of longest legit word */
                     91: 
                     92: char floppyring[MAX_PATH] = "";
                     93: int max_cert_depth = 4;                /* maximum nesting of signatures */
                     94: 
                     95: static boolean check_only = FALSE;
                     96: static boolean mverbose;
                     97: static FILE *sec_fp;
                     98: static FILE *floppy_fp = NULL;
                     99: static int undefined_trust;    /* number of legit keys with undef. trust */
                    100:   
                    101: int
                    102: maintenance(char *ringfile, int options)
                    103: {
                    104:        FILE *f, *g;
                    105:        int status;
                    106:        char *tmpring;
                    107:        char secretkeyring[MAX_PATH];
                    108: 
                    109:        check_only = (options & MAINT_CHECK) != 0;
                    110:        mverbose = (options & MAINT_VERBOSE) != 0;
                    111:        undefined_trust = 0;
                    112: 
                    113:        if ((tmpring = tempfile(TMP_TMPDIR)) == NULL)
                    114:                return(-1);
                    115:        if ((g = fopenbin(tmpring, "w+")) == NULL)
                    116:                return(-1);
                    117: 
                    118:        if ((f = fopenbin(ringfile,"r")) == NULL)
                    119:        {       fprintf(pgpout,PSTR("\n\007Can't open key ring file '%s'\n"),ringfile);
                    120:                fclose(g);
                    121:                return(-1);
                    122:        }
                    123: 
                    124:        buildfilename(secretkeyring, SECRET_KEYRING_FILENAME);
                    125:        if ((sec_fp = fopenbin(secretkeyring, "r")) == NULL)
                    126:                fprintf(pgpout,PSTR("\nCan't open secret key ring file '%s'\n"),
                    127:                                secretkeyring);
                    128: 
                    129:        if (!(options & MAINT_SILENT) && *floppyring != '\0' &&
                    130:                (floppy_fp = fopenbin(floppyring, "r")) == NULL)
                    131:                fprintf(pgpout,PSTR("\nCan't open backup key ring file '%s'\n"),
                    132:                                floppyring);
                    133: 
                    134:        if ((status = copyfile(f, g, -1L)) < 0)
                    135:        {       fprintf(pgpout,PSTR("\n\007Could not read key from file '%s'.\n"), ringfile);
                    136:                goto failed;
                    137:        }
                    138: 
                    139:        setup_trust();
                    140:        if (mverbose)
                    141:                fprintf(pgpout, PSTR("\nPass 1: Looking for the \"ultimately-trusted\" keys...\n"));
                    142:        rewind(g);
                    143:        if ((status = maint_pass1(g)) < 0)
                    144:                goto failed;
                    145: 
                    146:        if (mverbose)
                    147:                fprintf(pgpout, PSTR("\nPass 2: Tracing signature chains...\n"));
                    148:        rewind(g);
                    149:        if ((status = maint_trace_chain(g)) < 0)
                    150:                goto failed;
                    151: 
                    152:        if (!(options & MAINT_SILENT))
                    153:        {       if (mverbose)
                    154:                        fprintf(pgpout, PSTR("\nPass 3: Comparing with original keyring...\n"));
                    155:                rewind(f);
                    156:                rewind(g);
                    157:                if ((status = maint_cmpfiles(f, g)) < 0)
                    158:                        goto failed;
                    159:        } else
                    160:                status = 1;
                    161: 
                    162:        fflush(g);
                    163:        if (ferror(g))
                    164:        {       status = -1;
                    165:                goto failed;
                    166:        }
                    167:        fclose(f);
                    168:        fclose(g);
                    169:        if (sec_fp)
                    170:                fclose(sec_fp);
                    171:        if (floppy_fp)
                    172:        {       fclose(floppy_fp);
                    173:                floppy_fp = NULL;
                    174:        }
                    175: 
                    176: #ifdef DEBUG
                    177:        if (check_only)
                    178:        {
                    179:                if (undefined_trust)
                    180:                        fprintf(pgpout, "\nKeyring contains %d fully validated key(s) with undefined trust.\n", undefined_trust);
                    181:                else
                    182:                        if (status == 0)
                    183:                                fprintf(pgpout, "\nMaintenance check OK.\n");
                    184:                rmtemp(tmpring);
                    185:                return(0);
                    186:        }
                    187: #endif
                    188: 
                    189:        if (status > 0)         /* keyring is changed */
                    190:        {
                    191:                if (options & MAINT_SILENT)
                    192:                {       /* implicit maintenance pass (after pgp -ka, -kr, -ks) */
                    193:                        remove(ringfile);
                    194:                        if (savetemp(tmpring, ringfile) == NULL)
                    195:                                return(-1);
                    196:                }
                    197:                else
                    198:                {       /* explicit maintenance pass */
                    199:                        fprintf(pgpout, PSTR("Update public keyring '%s' (Y/n)? "), ringfile);
                    200:                        if (!getyesno('y'))
                    201:                        {
                    202:                                rmtemp(tmpring);
                    203:                                return(0);
                    204:                        }
                    205:                        if (savetempbak(tmpring, ringfile))
                    206:                                return(-1);
                    207:                }
                    208:        }
                    209:        else
                    210:                rmtemp(tmpring);
                    211: 
                    212:        return(0);
                    213: 
                    214: failed:
                    215:        if (sec_fp)
                    216:                fclose(sec_fp);
                    217:        if (floppy_fp)
                    218:        {       fclose(floppy_fp);
                    219:                floppy_fp = NULL;
                    220:        }
                    221:        fclose(f);
                    222:        fclose(g);
                    223: #ifdef DEBUG
                    224:        savetempbak(tmpring, "tmpring.pub");
                    225: #else
                    226:        rmtemp(tmpring);
                    227: #endif
                    228:        return(status);
                    229: }
                    230: 
                    231: 
                    232: /*
                    233:  * check if axiomatic keys are present in the secret keyring and
                    234:  * clear userid and signature trust bytes
                    235:  */
                    236: int
                    237: maint_pass1(FILE *f)
                    238: {
                    239:        int status;
                    240:        char userid[256];
                    241:        byte keyID[KEYFRAGSIZE];
                    242:        byte ctb;
                    243:        byte keyctrl;
                    244:        boolean buckstop = FALSE, show_user = FALSE;
                    245:        boolean compromised = FALSE;
                    246:        int buckstopcount = 0;
                    247:        int usercount = 0;
                    248:        long keypos = 0;
                    249: 
                    250:        while ((status = readkpacket(f, &ctb, userid, keyID, NULL)) != -1)
                    251:        {
                    252:                if (status < 0)
                    253:                        return(status);
                    254: 
                    255:                if (is_ctb_type(ctb, CTB_COMMENT_TYPE))
                    256:                        continue;
                    257:                if (compromised && is_ctb_type(ctb, CTB_SKE_TYPE) && !usercount)
                    258:                        continue;       /* compromise certificate */
                    259: 
                    260:                /* other packets should have trust byte */
                    261:                if (read_trust(f, &keyctrl) < 0)
                    262:                        return(ERR_NOTRUST);            /* not a public keyring */
                    263: 
                    264:                if (is_ctb_type(ctb, CTB_CERT_PUBKEY_TYPE))
                    265:                {
                    266:                        if (compromised = is_compromised(f))
                    267:                                keyctrl = KC_OWNERTRUST_NEVER;
                    268:                        if ((keyctrl & KC_BUCKSTOP))
                    269:                        {
                    270:                                if (check_secretkey(f, keypos) == 0)
                    271:                                {
                    272:                                        ++buckstopcount;
                    273:                                        buckstop = TRUE;
                    274:                                        if (mverbose)
                    275:                                                fprintf(pgpout, "* %s",keyIDstring(keyID));
                    276:                                }
                    277:                                else
                    278:                                {       /* not in secret keyring */
                    279:                                        keyctrl &= ~KC_BUCKSTOP;
                    280:                                        if (TRUST_LEV(keyctrl) == KC_OWNERTRUST_ULTIMATE)
                    281:                                                keyctrl = KC_OWNERTRUST_ALWAYS;
                    282:                                        if (mverbose)
                    283:                                                fprintf(pgpout, ". %s",keyIDstring(keyID));
                    284:                                }
                    285:                                show_user = mverbose;
                    286:                        }
                    287:                        else
                    288:                        {
                    289:                                buckstop = FALSE;
                    290:                                show_user = FALSE;
                    291:                        }
                    292:                        usercount = 0;
                    293:                        keyctrl &= ~KC_VISITED;
                    294: 
                    295:                }
                    296:                else if (ctb == CTB_USERID)
                    297:                {
                    298:                        if (show_user)
                    299:                        {
                    300:                                if (usercount)          /* more than one user ID */
                    301:                                        fprintf(pgpout, "        ");
                    302:                                fprintf(pgpout, "  %s\n", EXTERNAL(userid));
                    303:                        }
                    304:                        if (buckstop)
                    305:                                keyctrl = KC_LEGIT_COMPLETE;
                    306:                        else
                    307:                                keyctrl = KC_LEGIT_UNKNOWN;
                    308:                        ++usercount;
                    309:                }
                    310:                else if (is_ctb_type(ctb, CTB_SKE_TYPE))
                    311:                {
                    312:                        keyctrl = KC_SIGTRUST_UNDEFINED;
                    313:                }
                    314:                fseek(f, -1L, SEEK_CUR);
                    315:                fwrite(&keyctrl, 1, 1, f);
                    316:                fseek(f, 0L, SEEK_CUR);
                    317:                keypos = ftell(f);
                    318:        }
                    319:        if (buckstopcount == 0 && mverbose)
                    320:        {
                    321:                fprintf(pgpout, PSTR("No ultimately-trusted keys.\n"));
                    322:        }
                    323:        return(0);
                    324: }
                    325: 
                    326: 
                    327: /*
                    328:  * scan keyring for buckstop keys and start the recursive trace_sig_chain()
                    329:  * on them
                    330:  */
                    331: int
                    332: maint_trace_chain(FILE *f)
                    333: {
                    334:        int status;
                    335:        char userid[256];
                    336:        byte keyID[KEYFRAGSIZE];
                    337:        long trustpos = 0;
                    338:        byte ctb;
                    339:        byte own_trust;
                    340:        boolean buckstop = FALSE;
                    341: 
                    342:        while ((status = readkpacket(f, &ctb, userid, keyID, NULL)) != -1)
                    343:        {
                    344:                if (status < 0)
                    345:                        return status;
                    346: 
                    347:                if (is_ctb_type(ctb, CTB_CERT_PUBKEY_TYPE))
                    348:                {
                    349:                        trustpos = ftell(f);
                    350:                        if ((status = read_trust(f, &own_trust)) < 0)
                    351:                                return(status);
                    352:                        buckstop = (own_trust & KC_BUCKSTOP) != 0;
                    353:                        userid[0] = '\0';
                    354:                }
                    355:                else if (ctb == CTB_USERID)
                    356:                {
                    357:                        if (buckstop)
                    358:                        {
                    359:                                buckstop = FALSE;       /* only for first user id */
                    360:                                if (mverbose)
                    361:                                        fprintf(pgpout, "* %s\n", EXTERNAL(userid));
                    362: 
                    363:                                if (TRUST_LEV(own_trust) == KC_OWNERTRUST_UNDEFINED)
                    364:                                {       SET_TRUST(&own_trust, ask_owntrust(userid, own_trust));
                    365:                                        write_trust_pos(f, own_trust, trustpos);
                    366:                                }
                    367:                                if (trace_sig_chain(f, keyID, TRUST_LEV(own_trust), 0) < 0)
                    368:                                        return(-1);
                    369:                        }
                    370:                }
                    371:        }
                    372:        return(0);
                    373: }
                    374: 
                    375: 
                    376: /* 
                    377:  * check if the maintenance pass changed anything
                    378:  * returns 0 if files f and g are equal.
                    379:  */
                    380: int
                    381: maint_cmpfiles(FILE *f, FILE *g)
                    382: {
                    383:        int status;
                    384:        char userid[256];
                    385:        byte keyID[KEYFRAGSIZE];
                    386:        byte sigkeyID[KEYFRAGSIZE];
                    387:        byte ctb;
                    388:        byte kc_orig, kc_new;
                    389:        int usercount = 0;
                    390:        int changed = 0;
                    391: 
                    392:        fprintf(pgpout, PSTR("  KeyID   Trust      Validity  User ID\n"));
                    393:        while ((status = readkpacket(f, &ctb, userid, keyID, sigkeyID)) == 0)
                    394:        {
                    395:                if (is_ctb_type(ctb, CTB_COMMENT_TYPE))
                    396:                        continue;
                    397:                /* other packets should have trust byte */
                    398: 
                    399:                fseek(g, ftell(f), SEEK_SET);
                    400:                if (read_trust(f, &kc_orig) < 0 || read_trust(g, &kc_new) < 0)
                    401:                {       status = ERR_NOTRUST;
                    402:                        break;
                    403:                }
                    404: 
                    405:                if (is_ctb_type(ctb, CTB_CERT_PUBKEY_TYPE))
                    406:                {
                    407:                        if (is_compromised(f))
                    408:                        {
                    409:                                fprintf(pgpout, "# ");
                    410:                                nextkeypacket(f, &ctb); /* skip compromise certificate */
                    411:                                nextkeypacket(g, &ctb);
                    412:                        }
                    413:                        else if ((kc_new & KC_BUCKSTOP))
                    414:                                fprintf(pgpout, "* ");
                    415:                        else
                    416:                                fprintf(pgpout, "  ");
                    417: 
                    418:                        fprintf(pgpout, "%s ",keyIDstring(keyID));
                    419:                        changed += show_trust(kc_new, kc_orig);
                    420:                        usercount = 0;
                    421:                        userid[0] = '\0';
                    422:                }
                    423:                else if (ctb == CTB_USERID)
                    424:                {
                    425:                        if (usercount)          /* more than one user ID */
                    426:                                fprintf(pgpout, "          %*s", trustlst_len, "");
                    427:                        ++usercount;
                    428:                        changed += show_legit(kc_new, kc_orig);
                    429:                        fprintf(pgpout, "%s\n", EXTERNAL(userid));
                    430:                }
                    431:                else if (is_ctb_type(ctb, CTB_SKE_TYPE))
                    432:                {
                    433:                        if (kc_new & KC_CONTIG)
                    434:                                fprintf(pgpout, "c        ");
                    435:                        else
                    436:                                fprintf(pgpout, "         ");
                    437:                        changed += show_trust(kc_new, kc_orig);
                    438:                        fprintf(pgpout, "  %*s", legitlst_len, "");
                    439:                        show_userid(f, sigkeyID);
                    440:                }
                    441:        }
                    442:        if (status >= -1 && changed)
                    443:                fprintf(pgpout, PSTR("\n%d \"trust byte(s)\" changed.\n"), changed);
                    444:        if (status < -1)        /* -1 is OK, EOF */
                    445:                return(status);
                    446:        return(changed);
                    447: }
                    448: 
                    449: 
                    450: void
                    451: init_trust_lst()
                    452: {
                    453:        static int initialized = 0;
                    454:        int i, len;
                    455:        char *s;
                    456: 
                    457:        if (initialized)
                    458:                return;
                    459:        for (i = 0; i < 8; ++i)
                    460:        {       if (trust_lst[i][0])
                    461:                {       s = PSTR (trust_lst[i]);
                    462:                        if (s != trust_lst[i])
                    463:                                strncpy(trust_lst[i], s, sizeof(trust_lst[0]) - 1);
                    464:                        len = strlen(s);
                    465:                        if (len > trustlst_len)
                    466:                                trustlst_len = len;
                    467:                }
                    468:        }
                    469:        for (i = 0; i < 4; ++i)
                    470:        {       s = PSTR (legit_lst[i]);
                    471:                if (s != legit_lst[i])
                    472:                        strncpy(legit_lst[i], s, sizeof(legit_lst[0]) - 1);
                    473:                len = strlen(s);
                    474:                if (len > legitlst_len)
                    475:                        legitlst_len = len;
                    476:        }
                    477:        ++trustlst_len;
                    478:        ++legitlst_len;
                    479:        initialized = 1;
                    480: }
                    481: 
                    482: int
                    483: show_trust(byte kc_new, byte kc_orig)
                    484: {
                    485: #ifdef DEBUG
                    486:        fprintf(pgpout, " %02x", kc_new);
                    487:        if (kc_new != kc_orig)
                    488:        {
                    489:                fprintf(pgpout, " (%02x)    ", kc_orig);
                    490:                return(1);
                    491:        }
                    492:        fprintf(pgpout, "        ");
                    493:        return(0);
                    494: #else
                    495:        init_trust_lst();
                    496:        fprintf(pgpout, "%c%-*s", (kc_new == kc_orig ? ' ' : '!'),
                    497:                        trustlst_len, trust_lst[TRUST_LEV(kc_new)]);
                    498:        return(kc_new != kc_orig);
                    499: #endif
                    500: }
                    501: 
                    502: int
                    503: show_legit(byte kc_new, byte kc_orig)
                    504: {
                    505: #ifdef DEBUG
                    506:        return(show_trust(kc_new, kc_orig));
                    507: #else
                    508:        init_trust_lst();
                    509:        kc_new &= KC_LEGIT_MASK;
                    510:        kc_orig &= KC_LEGIT_MASK;
                    511:        fprintf(pgpout, "%c%-*s", (kc_new == kc_orig ? ' ' : '!'),
                    512:                        legitlst_len, legit_lst[kc_new]);
                    513:        return(kc_new != kc_orig);
                    514: #endif
                    515: }
                    516: 
                    517: 
                    518: /*
                    519:  * Find all signatures made with a key, fromID is the keyID of this key
                    520:  * owner_trust is the trust level of this key.
                    521:  * If a trusted signature makes a key fully legit then signatures made
                    522:  * with this key are also recursively traced on down the tree.
                    523:  */
                    524: int
                    525: trace_sig_chain(FILE *f, byte *fromID, int owner_trust, int depth)
                    526: {
                    527:        long filepos;
                    528:        int status;
                    529:        int trust_count = 0;
                    530:        byte keyID[KEYFRAGSIZE];
                    531:        byte sigkeyID[KEYFRAGSIZE];
                    532:        byte ctb;
                    533:        byte own_trust, sig_trust;
                    534:        char userid[256];
                    535:        int sig_count = 0;
                    536:        int compromised = 0;
                    537:        long usertrustpos = 0;
                    538:        long ownt_pos = 0;
                    539: 
                    540:        if (max_cert_depth > 8)
                    541:                max_cert_depth = 8;
                    542:        if (depth > max_cert_depth)
                    543:                return(0);
                    544:        filepos = ftell(f);
                    545:        rewind(f);
                    546:        userid[0] = '\0';
                    547:        while ((status = readkpacket(f, &ctb, userid, keyID, sigkeyID)) != -1)
                    548:        {
                    549:                if (status < 0)
                    550:                        return status;
                    551: 
                    552:                if (is_ctb_type(ctb, CTB_CERT_PUBKEY_TYPE))
                    553:                {
                    554:                        compromised = is_compromised(f);
                    555:                        ownt_pos = ftell(f);
                    556:                        if (read_trust(f, &own_trust))
                    557:                                return(ERR_NOTRUST);
                    558:                        userid[0] = '\0';
                    559:                }
                    560:                else if (ctb == CTB_USERID)
                    561:                {
                    562:                        usertrustpos = ftell(f);
                    563:                        trust_count = 0;
                    564:                }
                    565:                else if (is_ctb_type(ctb, CTB_SKE_TYPE))
                    566:                {
                    567:                        if (compromised)
                    568:                                continue;
                    569:                        read_trust(f, &sig_trust);
                    570:                        if (memcmp(sigkeyID, fromID, sizeof(sigkeyID)) == 0)
                    571:                        {
                    572:                                ++sig_count;
                    573:                                if (mverbose)
                    574:                                        fprintf(pgpout, "%*s  > %s\n", 2*depth, "", EXTERNAL(userid));
                    575:                                if (TRUST_LEV(sig_trust) != owner_trust)
                    576:                                {
                    577:                                        SET_TRUST(&sig_trust, owner_trust);
                    578:                                }
                    579:                                sig_trust |= KC_CONTIG;
                    580:                                fseek(f, -1L, SEEK_CUR);
                    581:                                fwrite(&sig_trust, 1, 1, f);
                    582:                                fseek(f, 0L, SEEK_CUR);
                    583:                        }
                    584: 
                    585:                        if (sig_trust & KC_CONTIG)
                    586:                        {
                    587:                                trust_count += TRUST_FAC(sig_trust);
                    588: 
                    589:                                switch (set_legit(f, usertrustpos, trust_count))
                    590:                                {
                    591:                                        case -1: return(-1);
                    592:                                        case  1:
                    593:                                                if ((own_trust & (KC_BUCKSTOP|KC_VISITED)) == 0)
                    594:                                                {
                    595:                                                        if (TRUST_LEV(own_trust) == KC_OWNERTRUST_UNDEFINED)
                    596:                                                                SET_TRUST(&own_trust, ask_owntrust(userid, own_trust));
                    597:                                                        own_trust |= KC_VISITED;
                    598:                                                        write_trust_pos(f, own_trust, ownt_pos);
                    599:                                                        trace_sig_chain(f, keyID, TRUST_LEV(own_trust), depth+1);
                    600:                                                }
                    601:                                }
                    602:                        }
                    603:                }
                    604:        }
                    605:        if (mverbose && sig_count == 0) /* no signatures from this user */
                    606:                fprintf(pgpout, PSTR("%*s  (No signatures)\n"), 2*depth, "");
                    607:        fseek(f, filepos, SEEK_SET);
                    608:        return(0);
                    609: }
                    610: 
                    611: 
                    612: int
                    613: check_secretkey(FILE *f, long keypos)
                    614: {
                    615:        int status = -1;
                    616:        unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION];
                    617:        unit nsec[MAX_UNIT_PRECISION], esec[MAX_UNIT_PRECISION];
                    618:        char userid[256];
                    619:        byte keyID[KEYFRAGSIZE];
                    620:        long savepos, pktlen;
                    621:        byte ctb;
                    622: 
                    623:        if (sec_fp == NULL)
                    624:                return(-1);
                    625: 
                    626:        savepos = ftell(f);
                    627:        fseek(f, keypos, SEEK_SET);
                    628:        if (readkeypacket(f, FALSE, &ctb, NULL, NULL, n, e,
                    629:                                        NULL, NULL, NULL, NULL, NULL, NULL) < 0)
                    630:                goto ex;
                    631:        extract_keyID(keyID, n);
                    632: 
                    633:        do      /* get userid */
                    634:        {       if (readkpacket(f, &ctb, userid, NULL, NULL) < 0)
                    635:                        goto ex;
                    636:        } while (ctb != CTB_USERID);
                    637: 
                    638:        if (lookup_by_keyID(sec_fp, keyID) < 0)
                    639:        {
                    640: #if 0
                    641:                if (!check_only)
                    642:                {
                    643:                        fprintf(pgpout, PSTR (
                    644: "\nAn \"axiomatic\" key is one which does not need certifying by\n\
                    645: anyone else.  Usually this special status is reserved only for your\n\
                    646: own keys, which should also appear on your secret keyring.  The owner\n\
                    647: of an axiomatic key (who is typically yourself) is \"ultimately trusted\"\n\
                    648: by you to certify any or all other keys.\n"));
                    649:                        fprintf(pgpout, PSTR ("\nKey for user ID: \"%s\"\n\
                    650: is designated as an \"ultimately-trusted\" introducer, but the key\n\
                    651: does not appear in the secret keyring.\n\
                    652: Use this key as an ultimately-trusted introducer (y/N)? "), EXTERNAL(userid));
                    653:                        status = (getyesno('n') ? 0 : 1);
                    654:                }
                    655: #else
                    656:                status = 1;
                    657: #endif
                    658:        }
                    659:        else
                    660:        {
                    661:                long kpos = ftell(sec_fp);
                    662:                if (readkeypacket(sec_fp, FALSE, &ctb, NULL, NULL, nsec, esec,
                    663:                                                NULL, NULL, NULL, NULL, NULL, NULL) < 0)
                    664:                {
                    665:                        fprintf(pgpout, PSTR("\n\007Cannot read from secret keyring.\n"));
                    666:                        goto ex;
                    667:                }
                    668:                if (mp_compare(n, nsec) || mp_compare(e, esec))
                    669:                {       /* Red Alert! */
                    670:                        fprintf(pgpout, PSTR("\n\007WARNING: Public key for user ID: \"%s\"\n\
                    671: does not match the corresponding key in the secret keyring.\n"), EXTERNAL(userid));
                    672:                        fprintf(pgpout, PSTR("This is a serious condition, indicating possible keyring tampering.\n"));
                    673:                        status = -2;
                    674:                }
                    675:                else
                    676:                        status = 0;
                    677: 
                    678:                if (floppy_fp)
                    679:                {
                    680:                        if (lookup_by_keyID(floppy_fp, keyID) < 0)
                    681:                        {
                    682:                                fprintf(pgpout, PSTR("Public key for: \"%s\"\n\
                    683: is not present in the backup keyring '%s'.\n"),
                    684:                                                EXTERNAL(userid), floppyring);
                    685:                        }
                    686:                        else
                    687:                        {
                    688:                                pktlen = ftell(sec_fp) - kpos;
                    689:                                fseek(sec_fp, kpos, SEEK_SET);
                    690:                                while (--pktlen >= 0 && getc(sec_fp) == getc(floppy_fp)) ;
                    691:                                if (pktlen != -1)
                    692:                                {
                    693:                                        fprintf(pgpout, PSTR("\n\007WARNING: Secret key for: \"%s\"\n\
                    694: does not match the key in the backup keyring '%s'.\n"),
                    695:                                                        EXTERNAL(userid), floppyring);
                    696:                                        fprintf(pgpout, PSTR("This is a serious condition, indicating possible keyring tampering.\n"));
                    697:                                        status = -2;
                    698:                                }
                    699:                        }
                    700:                }
                    701:        }
                    702: ex:
                    703:        fseek(f, savepos, SEEK_SET);
                    704:        return(status);
                    705: }
                    706: 
                    707: 
                    708: void
                    709: setup_trust()
                    710: {      /* initialize trust table */
                    711:        if (marg_min == 0)      /* marginally trusted signatures are ignored */
                    712:        {
                    713:                trust_tbl[5] = 0;
                    714:                trust_tbl[6] = 1;
                    715:                complete_min = compl_min;
                    716:        }
                    717:        else
                    718:        {
                    719:                if (marg_min < compl_min)
                    720:                        marg_min = compl_min;
                    721:                trust_tbl[5] = compl_min;
                    722:                trust_tbl[6] = marg_min;
                    723:                complete_min = compl_min * marg_min;
                    724:        }
                    725:        trust_tbl[7] = complete_min;    /* ultimate trust */
                    726:        marginal_min = complete_min / 2;
                    727: }
                    728: 
                    729: 
                    730: /*
                    731:  * set legit level of a userid
                    732:  * returns 1 if the key/userid pair is fully legit.
                    733:  */
                    734: int
                    735: set_legit(FILE *f, long trustpos, int trust_count)
                    736: {
                    737:        long filepos;
                    738:        byte keyctrl;
                    739: 
                    740:        filepos = ftell(f);
                    741:        fseek(f, trustpos, SEEK_SET);   /* user id trust byte */
                    742:        if (read_trust(f, &keyctrl) < 0)
                    743:                return(-1);
                    744:        
                    745:        if (trust_count < marginal_min)
                    746:                keyctrl = KC_LEGIT_UNTRUSTED;
                    747:        else if (trust_count < complete_min)
                    748:                keyctrl = KC_LEGIT_MARGINAL;
                    749:        else
                    750:                keyctrl = KC_LEGIT_COMPLETE;
                    751:        
                    752:        fseek(f, trustpos, SEEK_SET);
                    753:        write_trust(f, keyctrl);
                    754: 
                    755:        fseek(f, filepos, SEEK_SET);
                    756: 
                    757:        if ((keyctrl & KC_LEGIT_MASK) == KC_LEGIT_COMPLETE)
                    758:                return(1);
                    759:        else
                    760:                return(0);
                    761: }
                    762: 
                    763: 
                    764: int ask_owntrust(char *userid, byte cur_trust)
                    765: /* Ask for a wetware decision from the human on how much to trust 
                    766: this key's owner to certify other keys.  Returns trust value. */
                    767: {
                    768:        char buf[8];
                    769: 
                    770:        if (check_only)
                    771:        {       ++undefined_trust;
                    772:                return(KC_OWNERTRUST_UNDEFINED);
                    773:        }
                    774: 
                    775:        fprintf(pgpout, 
                    776: PSTR("\nMake a determination in your own mind whether this key actually\n\
                    777: belongs to the person whom you think it belongs to, based on available\n\
                    778: evidence.  If you think it does, then based on your estimate of\n\
                    779: that person's integrity and competence in key management, answer\n\
                    780: the following question:\n"));  
                    781:        fprintf(pgpout, PSTR("\nWould you trust \"%s\"\n\
                    782: to act as an introducer and certify other people's public keys to you?\n\
                    783: (1=I don't know. 2=No. 3=Usually. 4=Yes, always.) ? "), EXTERNAL(userid));
                    784:        fflush(pgpout);
                    785:        getstring(buf, sizeof(buf)-1, TRUE);
                    786:        switch (buf[0])
                    787:        {       case '1': return KC_OWNERTRUST_UNKNOWN;
                    788:                case '2': return KC_OWNERTRUST_NEVER;
                    789:                case '3': return KC_OWNERTRUST_USUALLY;
                    790:                case '4': return KC_OWNERTRUST_ALWAYS;
                    791:                default: return(TRUST_LEV(cur_trust));
                    792:        }
                    793: }      /* ask_owntrust */
                    794: 
                    795: 
                    796: /* 
                    797:  * compare all key packets in keyring file f with file g
                    798:  * XXX: untested
                    799:  */
                    800: int
                    801: keyring_cmp(FILE *f, FILE *g)
                    802: {
                    803:        int status, error = 0, badkeys = 0;
                    804:        byte ctb;
                    805:        byte keyID[KEYFRAGSIZE];
                    806:        char userid[256];
                    807:        long pktlen, keypos = 0;
                    808: 
                    809:        rewind(f);
                    810:        while ((status = readkpacket(f, &ctb, userid, keyID, NULL)) == 0)
                    811:        {
                    812:                if (is_key_ctb(ctb))
                    813:                {
                    814:                        pktlen = ftell(f) - keypos;
                    815:                        fseek(f, keypos, SEEK_SET);
                    816:                        if (lookup_by_keyID(g, keyID) < 0)
                    817:                        {
                    818:                                error = 1;
                    819:                                continue;
                    820:                        }
                    821:                        while (--pktlen >= 0 && getc(f) == getc(g)) ;
                    822:                        if (pktlen != -1)
                    823:                        {
                    824:                                error = 2;
                    825:                                ++badkeys;
                    826:                        }
                    827: 
                    828:                }
                    829:                if (error && ctb == CTB_USERID)
                    830:                {
                    831:                        switch (error) {
                    832:                                case 1: fprintf(pgpout, PSTR("\n\007Key for user ID \"%s\"\n\
                    833: is not present in backup keyring\n"), EXTERNAL(userid));
                    834:                                case 2: fprintf(pgpout, PSTR("\n\007Key for user ID \"%s\"\n\
                    835: does not match key in backup keyring\n"), EXTERNAL(userid));
                    836:                        }
                    837:                        error = 0;
                    838:                }
                    839:                keypos = ftell(f);
                    840:        }
                    841:        if (error)
                    842:                status = -5;
                    843:        return(status < 0 ? status : badkeys);
                    844: }
                    845: 
                    846: 
                    847: int
                    848: readkpacket(FILE *f, byte *ctb, char *userid, byte *keyID, byte *sigkeyID)
                    849: {
                    850:        int status;
                    851:        unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION];
                    852: 
                    853:        status = readkeypacket(f, FALSE, ctb, NULL, userid, n, e,
                    854:                                        NULL, NULL, NULL, NULL, sigkeyID, NULL);
                    855: 
                    856:        if (status < 0)
                    857:        {
                    858: #ifdef DEBUG
                    859:                if (status < -1)
                    860:                        fprintf(stderr, "readkeypacket returned %d\n", status);
                    861: #endif
                    862:                return(status);
                    863:        }
                    864: 
                    865:        if (keyID && is_key_ctb(*ctb))
                    866:                extract_keyID(keyID, n);
                    867: 
                    868:        if (userid && *ctb == CTB_USERID)
                    869:                PascalToC(userid);
                    870: 
                    871:        return(0);
                    872: }
                    873: 
                    874: long
                    875: lookup_by_keyID(FILE *f, byte *srch_keyID)
                    876: {
                    877:        int status;
                    878:        long keypos = 0;
                    879:        byte keyID[KEYFRAGSIZE];
                    880:        byte ctb;
                    881: 
                    882:        rewind(f);
                    883:        while ((status = readkpacket(f, &ctb, NULL, keyID, NULL)) == 0)
                    884:        {
                    885:                if (is_key_ctb(ctb) && memcmp(keyID, srch_keyID, KEYFRAGSIZE) == 0)
                    886:                {
                    887:                        fseek(f, keypos, SEEK_SET);
                    888:                        return(keypos);
                    889:                }
                    890:                keypos = ftell(f);
                    891:        }
                    892:        return(status);
                    893: }
                    894: 
                    895: 
                    896: void
                    897: show_userid(FILE *f, byte *keyID)
                    898: {
                    899:        long filepos;
                    900:        char userid[256];
                    901:        byte ctb;
                    902: 
                    903:        filepos = ftell(f);
                    904:        if (lookup_by_keyID(f, keyID) >= 0)
                    905:                while (readkpacket(f, &ctb, userid, NULL, NULL) == 0)
                    906:                        if (ctb == CTB_USERID)
                    907:                        {
                    908:                                fprintf(pgpout, "%s\n", EXTERNAL(userid));
                    909:                                fseek(f, filepos, SEEK_SET);
                    910:                                return;
                    911:                        }
                    912: 
                    913:        fprintf(pgpout, "(KeyID: %s)\n",keyIDstring(keyID));
                    914:        fseek(f, filepos, SEEK_SET);
                    915: }
                    916: 
                    917: /*
                    918:  * show the key in file f at file position keypos.
                    919:  * 'what' controls the info that will be shown:
                    920:  *   SHOW_TRUST: show trust byte info
                    921:  *   SHOW_SIGS:  show signatures
                    922:  * these constants can be or'ed to get both
                    923:  */
                    924: int
                    925: show_key(FILE *f, long keypos, int what)
                    926: {
                    927:        int status;
                    928:        long filepos;
                    929:        char userid[256];
                    930:        unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION];
                    931:        byte sigkeyID[KEYFRAGSIZE];
                    932:        word32 timestamp;
                    933:        byte ctb, keyctrl;
                    934:        int userids = 0;
                    935:        boolean print_trust = FALSE;
                    936:        int precision = global_precision;
                    937: 
                    938:        filepos = ftell(f);
                    939:        fseek(f, keypos, SEEK_SET);
                    940:        while ((status = readkeypacket(f, FALSE, &ctb, (byte *)&timestamp, userid,
                    941:                                        n, e, NULL, NULL, NULL, NULL, sigkeyID, &keyctrl)) == 0)
                    942:        {
                    943:                if (is_key_ctb(ctb))
                    944:                {       if (userids)
                    945:                                break;
                    946:                }
                    947:                else if (ctb == CTB_KEYCTRL)  /* trust bytes only in public keyrings */
                    948:                {
                    949:                        if (what & SHOW_TRUST)
                    950:                                print_trust = TRUE;
                    951:                }
                    952:                else if (ctb == CTB_USERID)
                    953:                {       if (userids == 0)
                    954:                        {       PascalToC(userid);      /* for display */
                    955:                                fprintf(pgpout,PSTR("\nKey for user ID: %s\n"),EXTERNAL(userid));
                    956:                                fprintf(pgpout,PSTR("%d-bit key, Key ID %s, created %s\n"),
                    957:                                        countbits(n), key2IDstring(n), cdate(&timestamp) );
                    958:                                if (print_trust)
                    959:                                {
                    960:                                        switch (TRUST_LEV(keyctrl))
                    961:                                        {
                    962:                                                case KC_OWNERTRUST_UNDEFINED:
                    963:                                                case KC_OWNERTRUST_UNKNOWN:
                    964:                                                        /* Just don't say anything in this case */
                    965:                                                        break;
                    966:                                                case KC_OWNERTRUST_NEVER:       /* untrusted */
                    967:                                                        fprintf(pgpout, PSTR("This user is untrusted to certify other keys.\n"));
                    968:                                                        break;
                    969:                                                case KC_OWNERTRUST_USUALLY:     /* marginal trust */
                    970:                                                        fprintf(pgpout, PSTR("This user is generally trusted to certify other keys.\n"));
                    971:                                                        break;
                    972:                                                case KC_OWNERTRUST_ALWAYS:      /* complete trust */
                    973:                                                        fprintf(pgpout, PSTR("This user is completely trusted to certify other keys.\n"));
                    974:                                                        break;
                    975:                                                case KC_OWNERTRUST_ULTIMATE:    /* axiomatic, ultimate trust */
                    976:                                                        fprintf(pgpout, PSTR("This axiomatic key is ultimately trusted to certify other keys.\n"));
                    977:                                                        break;
                    978:                                                default:
                    979:                                                        break;
                    980:                                        }       /* switch */
                    981:                                }
                    982:                                ++userids;
                    983:                        }
                    984:                        else
                    985:                        {       PascalToC(userid);
                    986:                                if (what != 0)
                    987:                                        fprintf(pgpout, "\n");
                    988:                                fprintf(pgpout,PSTR("Also known as: %s\n"), EXTERNAL(userid));
                    989:                        }
                    990:                        if (print_trust)
                    991:                        {
                    992:                                read_trust(f, &keyctrl);
                    993:                                switch (keyctrl & KC_LEGIT_MASK)
                    994:                                {
                    995:                                        case 0:         /* undefined certification level */
                    996:                                        case 1:         /* uncertified */
                    997:                                                fprintf(pgpout, PSTR("This key/userID association is not certified.\n"));
                    998:                                                break;
                    999:                                        case 2:         /* marginal certification */
                   1000:                                                fprintf(pgpout, PSTR("This key/userID association is marginally certified.\n"));
                   1001:                                                break;
                   1002:                                        case 3:         /* complete certification */
                   1003:                                                fprintf(pgpout, PSTR("This key/userID association is fully certified.\n"));
                   1004:                                                break;
                   1005:                                        default:        /* can't get here, right? */
                   1006:                                                break;
                   1007:                                }       /* switch */
                   1008:                        }       /* print_trust */
                   1009:                }
                   1010:                else if ((what & SHOW_SIGS) && is_ctb_type(ctb, CTB_SKE_TYPE))
                   1011:                {
                   1012:                        if (print_trust)
                   1013:                        {
                   1014:                                read_trust(f, &keyctrl);
                   1015:                                switch (TRUST_LEV(keyctrl))
                   1016:                                {
                   1017:                                        case KC_SIGTRUST_UNDEFINED:     /* undefined trust level */
                   1018:                                        case KC_SIGTRUST_UNKNOWN:
                   1019:                                                /* Just don't say anything in this case */
                   1020:                                                fprintf(pgpout, PSTR("  Questionable certification from:\n  "));
                   1021:                                                break;
                   1022:                                        case KC_SIGTRUST_UNTRUSTED:     /* untrusted */
                   1023:                                                fprintf(pgpout, PSTR("  Untrusted certification from:\n  "));
                   1024:                                                break;
                   1025:                                        case KC_SIGTRUST_MARGINAL:      /* marginal trust */
                   1026:                                                fprintf(pgpout, PSTR("  Generally trusted certification from:\n  "));
                   1027:                                                break;
                   1028:                                        case KC_SIGTRUST_COMPLETE:      /* complete trust */
                   1029:                                                fprintf(pgpout, PSTR("  Completely trusted certification from:\n  "));
                   1030:                                                break;
                   1031:                                        case KC_SIGTRUST_ULTIMATE:      /* axiomatic, ultimate trust */
                   1032:                                                fprintf(pgpout, PSTR("  Axiomatically trusted certification from:\n  "));
                   1033:                                                break;
                   1034:                                        default:        /* can't get here, right? */
                   1035:                                                break;
                   1036:                                }       /* switch */
                   1037:                        }
                   1038:                        else
                   1039:                                fprintf(pgpout, PSTR("  Certified by: "));
                   1040:                        show_userid(f, sigkeyID);
                   1041:                }
                   1042:        }
                   1043:        if (status == -1 && userids)
                   1044:                status = 0;
                   1045:        set_precision(precision);
                   1046:        fseek(f, filepos, SEEK_SET);
                   1047:        return(status);
                   1048: }
                   1049: 
                   1050: 
                   1051: void
                   1052: write_trust_pos(FILE *f, byte keyctrl, long pos)
                   1053: {
                   1054:        long fpos;
                   1055: 
                   1056:        fpos = ftell(f);
                   1057:        fseek(f, pos, SEEK_SET);
                   1058:        write_trust(f, keyctrl);
                   1059:        fseek(f, fpos, SEEK_SET);
                   1060: }
                   1061: 
                   1062: int
                   1063: read_trust(FILE *f, byte *keyctrl)
                   1064: {
                   1065:        unsigned char buf[3];
                   1066: 
                   1067:        if (fread(buf, 1, 3, f) != 3)
                   1068:                return -1;
                   1069:        if (buf[0] != CTB_KEYCTRL)
                   1070:        {
                   1071:                if (is_ctb(buf[0]))
                   1072:                        return(ERR_NOTRUST);
                   1073:                 else
                   1074:                        return(-3);             /* bad data */
                   1075:        }
                   1076:        if (buf[1] != 1)                /* length must be 1 */
                   1077:                return(-3);
                   1078:        if (keyctrl)
                   1079:                *keyctrl = buf[2];
                   1080:        return(0);
                   1081: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.