Annotation of researchv10no/cmd/sign/verify.c, revision 1.1

1.1     ! root        1: #include "regexp.h"
        !             2: #include <stdio.h>
        !             3: #include <string.h>
        !             4: 
        !             5: /* version history of certificates
        !             6: version 0, installed  Jun 6 1991
        !             7:        Signed by name, ctime-date
        !             8:        sum=string, count=number
        !             9:        ------
        !            10:        message
        !            11:        ------
        !            12:        sum=string, count=number
        !            13:        End name, ctime-date
        !            14: version 1, installed  Jun 10 1991
        !            15:        Signed by name, ctime-date
        !            16:        sum=string, date=gmtime-hex, count=number, ver=1
        !            17:        ------
        !            18:        message with comma before each line, counted in sum
        !            19:        ------
        !            20:        sum=string, date=gmtime-hex, count=number, ver=1
        !            21:        End name, ctime-date
        !            22: */
        !            23: 
        !            24: extern char *malloc(), *realloc();
        !            25: extern long time();
        !            26: extern char *ctime();
        !            27: extern void exit();
        !            28: extern char *getline();
        !            29: 
        !            30: #define SIZEOF(a) (sizeof(a)/sizeof(*a))
        !            31: 
        !            32: int version = 0;
        !            33: 
        !            34: struct field {
        !            35:        char *name, *pat;
        !            36:        int len, seq;
        !            37:        char *val;
        !            38: };
        !            39: 
        !            40: struct field head[] = {
        !            41:        { "signer", "^..?.?.?.?.?.?.?$" },
        !            42:        { "ctime", "^... ... .. ..:..:.. ....$" }
        !            43: };
        !            44: enum { NAME, CTIME };
        !            45: 
        !            46: struct field data[] = { 
        !            47:        { "sum", "^[0-9a-f]+$" },
        !            48:        { "date", "^[0-9a-f]+$" },
        !            49:        { "count", "^[0-9]+$" },
        !            50:        { "ver", "^[0-9]+$" }
        !            51: };
        !            52: enum { SUM, DATE, COUNT, VERS };
        !            53: int ndata[] = { 2, 4 };        /* # of fields in version */
        !            54: 
        !            55: char occ[][SIZEOF(data)] = {   /* sequence of fields in version*/
        !            56:        { 1,0,2,0 },
        !            57:        { 1,2,3,4 }
        !            58: };
        !            59: 
        !            60: main(ac,av)
        !            61: char **av;
        !            62: {
        !            63:        regsubexp mv[10];
        !            64:        char *s, *body;
        !            65:        int headlen, len1;
        !            66:        long tloc;
        !            67:        char *now;
        !            68:        int i, lines;
        !            69:        char canon[50];
        !            70:        FILE *fil = stdin;
        !            71:        int sflag = 0;
        !            72:        regexp *l1= regcomp("Signed by (.+), (.+)$");
        !            73:        char *pat = "signer=\\1, ctime=\\2";
        !            74:        regexp *dashes = regcomp("------$");
        !            75:        regexp *l3 = regcomp("End (.+), (.+)$");
        !            76: 
        !            77:        if(ac>1 && strcmp(av[1],"-s")==0) {
        !            78:                sflag++;
        !            79:                av++;
        !            80:                ac--;
        !            81:        }
        !            82:        if(ac>1 && (fil=fopen(av[1],"r"))==0) {
        !            83:                write(2,"verify: ",8);
        !            84:                perror(av[1]);
        !            85:                exit(1);
        !            86:        }
        !            87:        
        !            88:        while(s=getline(fil)) {
        !            89:                if(regexec(l1,s,mv,3)==0) continue;
        !            90:                regsub(pat,canon,mv,3); /* make the non-u uniform */
        !            91:                if(parse(canon,head,SIZEOF(head))==2)
        !            92:                        break;
        !            93:                for(i=0; i<SIZEOF(head); i++)
        !            94:                        head[i].val = 0;
        !            95:        }
        !            96:        if(s==0) error("cannot find signature line");
        !            97: 
        !            98:        s = getline(fil);
        !            99:        if(s==0 || parse(s,data,SIZEOF(data))<2)
        !           100:                error("cannot identify checksum line");
        !           101:        version = data[VERS].val==0? 0: atoi(data[VERS].val);
        !           102:        if(version >= SIZEOF(ndata))
        !           103:                error("improper version number");
        !           104:        for(i=0; i<SIZEOF(data); i++)
        !           105:                if(data[i].seq != occ[version][i])
        !           106:                        error("incorrect field sequence");
        !           107:        
        !           108:        s = getline(fil);
        !           109:        if(s==0 || regexec(dashes,s,mv,0)==0)
        !           110:                error("cannot find beginning cut mark");
        !           111: 
        !           112:        len1 = atoi(data[COUNT].val);
        !           113:        headlen = head[CTIME].len;
        !           114:        if(version==1)
        !           115:                headlen += data[DATE].len+head[NAME].len;
        !           116:        body = malloc(len1+headlen+1);
        !           117:        if(body==0) overflow();
        !           118:        strcpy(body,head[CTIME].val);
        !           119:        if(version!=0)
        !           120:                strcat(strcat(body,data[DATE].val),head[NAME].val);
        !           121:        if(input(body+headlen,len1,fil)==0)
        !           122:                error("cannot read full signed text");
        !           123: 
        !           124:        s = getline(fil);
        !           125:        if(s==0 || regexec(dashes,s,mv,0)==0)
        !           126:                error("cannot find ending cut mark");
        !           127: 
        !           128:        s = getline(fil);
        !           129:        if(s==0 || parse(s,data,SIZEOF(data))!=ndata[version])
        !           130:                error("cannot find matching checksum line");
        !           131: 
        !           132:        s = getline(fil);
        !           133:        if(s==0 || regexec(l3,s,mv,3)==0)
        !           134:                error("cannot find matching signature line");
        !           135:        regsub(pat,canon,mv,3);
        !           136:        if(parse(canon,head,SIZEOF(head))!=2)
        !           137:                error("cannot find matching signature line");
        !           138: 
        !           139:        lines = 0;
        !           140:        if(version!=0) for(i=headlen+len1; --i>=headlen; )
        !           141:                if(body[i]=='\n') lines++;
        !           142: 
        !           143:        switch(verify(head[NAME].val, data[SUM].val, body, headlen+len1)){
        !           144:        case 1:
        !           145:                (void)time(&tloc);
        !           146:                now = ctime(&tloc);
        !           147:                printf("Signature by %s, %s\n",
        !           148:                        head[NAME].val, head[DATE].val);
        !           149:                printf("verified %.24s, count=%d\n",now, len1-lines);
        !           150:                if(sflag) exit(0);
        !           151:                printf("-----\n");
        !           152:                output(body+headlen,len1);
        !           153:                printf("-----\n");
        !           154:                printf("verified %.24s, count=%d\n",now, len1-lines);
        !           155:                printf("End %s, %s\n",
        !           156:                        head[NAME].val, head[DATE].val);
        !           157:                exit(0);
        !           158:        case 0:
        !           159:                fprintf(stderr,"verify: Bogus\n");
        !           160:                exit(1);
        !           161:        case -1:
        !           162:                fprintf(stderr,"verify: server unavailable; try later\n");
        !           163:                exit(2);
        !           164:        }
        !           165:        /*NOTREACHED*/
        !           166: }
        !           167: 
        !           168: error(err)
        !           169: char *err;
        !           170: {
        !           171:        fprintf(stderr,"verify: document format error: %s\n", err);
        !           172:        exit(1);
        !           173: }
        !           174: 
        !           175: overflow()
        !           176: {
        !           177:        fprintf(stderr,"verify: out of space\n");
        !           178:        exit(2);
        !           179: }
        !           180: 
        !           181: output(s, n)
        !           182: char *s;
        !           183: {
        !           184:        int d = version!=0;
        !           185: 
        !           186:        s += d;
        !           187:        n -= d;
        !           188:        while(--n >= 0) {
        !           189:                putchar(*s);
        !           190:                if(*s == '\n')
        !           191:                        s+=d, n-=d;
        !           192:                s++;
        !           193:        }
        !           194: }
        !           195: 
        !           196: input(s, n, fil)
        !           197: char *s;
        !           198: FILE *fil;
        !           199: {
        !           200:        int c, nl;
        !           201: 
        !           202:        nl = 1;
        !           203:        while(n>0) {
        !           204:                c = getc(fil);
        !           205:                if(c==EOF) break;
        !           206:                if(nl && version!=0 && c!=',')
        !           207:                        continue;
        !           208:                nl = 0;
        !           209:                *s++ = c;
        !           210:                n--;
        !           211:                if(c=='\n') nl++;
        !           212:        }
        !           213:        return n==0;
        !           214: }
        !           215: 
        !           216: parse(s,field,n)       /* extract name=val fields */
        !           217: char *s;
        !           218: struct field *field;
        !           219: {
        !           220:        regsubexp mv[3];
        !           221:        int c = ',';
        !           222:        regexp *nameval, *re;
        !           223:        int seq, len, i;
        !           224: 
        !           225:        nameval = regcomp("^ *([a-z]+)=([^,]+)");
        !           226:        if(nameval==0) overflow();
        !           227: 
        !           228:        for(seq=1; c==',' && regexec(nameval,s,mv,3); seq++) {
        !           229:                c = mv[0].ep[0];
        !           230:                s = mv[0].ep + 1;
        !           231:                for(i=0; i<n; i++) {
        !           232:                        mv[1].ep[0] = 0;
        !           233:                        if(strcmp(field[i].name,mv[1].sp)==0)
        !           234:                                break;
        !           235:                }
        !           236:                if(i >= n)
        !           237:                        return -1;
        !           238:                len = mv[2].ep - mv[2].sp;
        !           239:                if(field[i].val==0) {   /* 1st time make entry */
        !           240:                        field[i].len = len;
        !           241:                        field[i].seq = seq;
        !           242:                        mv[2].ep[0] = 0;
        !           243:                        field[i].val = strdup(mv[2].sp);
        !           244:                        if(field[i].val==0) overflow();
        !           245:                        re = regcomp(field[i].pat);
        !           246:                        if(re==0) overflow();
        !           247:                        if(regexec(re,field[i].val,mv,0)==0)
        !           248:                                return -1;
        !           249:                        free((char*)re);
        !           250:                }
        !           251:                else            /* 2nd time check entry (hack) */
        !           252:                        if(field[i].len!=len || field[i].seq!=seq ||
        !           253:                           strncmp(field[i].val,mv[2].sp,len)!=0)
        !           254:                                return -1;
        !           255:        }
        !           256:        free((char*)nameval);
        !           257:        return c!=0? -1: seq-1;
        !           258: }
        !           259: 
        !           260: char *
        !           261: getline(fil)
        !           262: FILE *fil;
        !           263: {
        !           264:        static char *s;
        !           265:        static len;
        !           266:        int n, c;
        !           267: 
        !           268:        if(s==0) {
        !           269:                len = BUFSIZ;
        !           270:                s = malloc(len);
        !           271:                if(s==0) overflow();
        !           272:        }
        !           273:        n = 0;
        !           274:        for(;;) {
        !           275:                if(n>=len) {
        !           276:                        len += BUFSIZ;
        !           277:                        s = realloc(s,len);
        !           278:                        if(s==0) overflow();
        !           279:                }
        !           280:                c = getc(fil);
        !           281:                switch(c) {
        !           282:                case EOF:
        !           283:                        return 0;
        !           284:                case '\n':
        !           285:                        s[n] = 0;
        !           286:                        return s;
        !           287:                default:
        !           288:                        s[n++] = c;
        !           289:                }
        !           290:        }
        !           291: }

unix.superglobalmegacorp.com

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