[BACK]Return to verify.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / gzsig

Annotation of src/usr.bin/gzsig/verify.c, Revision 1.1.1.1

1.1       marius      1: /* $OpenBSD$ */
                      2:
                      3: /*
                      4:  * verify.c
                      5:  *
                      6:  * Copyright (c) 2001 Dug Song <dugsong@arbor.net>
                      7:  * Copyright (c) 2001 Arbor Networks, Inc.
                      8:  *
                      9:  *   Redistribution and use in source and binary forms, with or without
                     10:  *   modification, are permitted provided that the following conditions
                     11:  *   are met:
                     12:  *
                     13:  *   1. Redistributions of source code must retain the above copyright
                     14:  *      notice, this list of conditions and the following disclaimer.
                     15:  *   2. Redistributions in binary form must reproduce the above copyright
                     16:  *      notice, this list of conditions and the following disclaimer in the
                     17:  *      documentation and/or other materials provided with the distribution.
                     18:  *   3. The names of the copyright holders may not be used to endorse or
                     19:  *      promote products derived from this software without specific
                     20:  *      prior written permission.
                     21:  *
                     22:  *   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     23:  *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     24:  *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
                     25:  *   THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     26:  *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     27:  *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     28:  *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     29:  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     30:  *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     31:  *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  *
                     33:  * $Id: verify.c,v 1.3 2005/04/07 23:19:35 dugsong Exp $
                     34:  */
                     35:
                     36: #include <sys/types.h>
                     37:
                     38: #include <openssl/ssl.h>
                     39: #include <openssl/evp.h>
                     40: #include <openssl/sha.h>
                     41:
                     42: #include <errno.h>
                     43: #include <stdio.h>
                     44: #include <stdlib.h>
                     45: #include <string.h>
                     46: #include <unistd.h>
                     47:
                     48: #include "extern.h"
                     49: #include "gzip.h"
                     50: #include "key.h"
                     51: #include "util.h"
                     52:
                     53: static int
                     54: verify_signature(struct key *key, FILE *fin)
                     55: {
                     56:        struct gzip_header gh;
                     57:        struct gzip_xfield *gx;
                     58:        struct gzsig_data *gd;
                     59:        u_char *sig, digest[20], buf[8192], sbuf[4096];
                     60:        SHA_CTX ctx;
                     61:        int i, siglen;
                     62:
                     63:        /* Read gzip header. */
                     64:        if ((i = fread((u_char *)&gh, 1, sizeof(gh), fin)) != sizeof(gh)) {
                     65:                fprintf(stderr, "Error reading gzip header: %s\n",
                     66:                    strerror(errno));
                     67:                return (-1);
                     68:        }
                     69:        /* Verify gzip header. */
                     70:        if (memcmp(gh.magic, GZIP_MAGIC, sizeof(gh.magic)) != 0) {
                     71:                fprintf(stderr, "Invalid gzip file\n");
                     72:                return (-1);
                     73:        } else if (gh.flags & GZIP_FCONT){
                     74:                fprintf(stderr, "Multi-part gzip files not supported\n");
                     75:                return (-1);
                     76:        } else if ((gh.flags & GZIP_FEXTRA) == 0) {
                     77:                fprintf(stderr, "No gzip signature found\n");
                     78:                return (-1);
                     79:        }
                     80:        /* Read signature. */
                     81:        gx = (struct gzip_xfield *)buf;
                     82:
                     83:        if ((i = fread((u_char *)gx, 1, sizeof(*gx), fin)) != sizeof(*gx)) {
                     84:                fprintf(stderr, "Error reading extra field: %s\n",
                     85:                    strerror(errno));
                     86:                return (-1);
                     87:        }
                     88:        if (memcmp(gx->subfield.id, GZSIG_ID, sizeof(gx->subfield.id)) != 0) {
                     89:                fprintf(stderr, "Unknown extra field\n");
                     90:                return (-1);
                     91:        }
                     92:        gx->subfield.len = letoh16(gx->subfield.len);
                     93:
                     94:        if (gx->subfield.len <= 0 || gx->subfield.len > sizeof(sbuf)) {
                     95:                fprintf(stderr, "Invalid signature length\n");
                     96:                return (-1);
                     97:        }
                     98:        gd = (struct gzsig_data *)sbuf;
                     99:
                    100:        if ((i = fread((u_char *)gd, 1, gx->subfield.len, fin)) !=
                    101:            gx->subfield.len) {
                    102:                fprintf(stderr, "Error reading signature: %s\n",
                    103:                    strerror(errno));
                    104:                return (-1);
                    105:        }
                    106:        /* Skip over any options. */
                    107:        if (gh.flags & GZIP_FNAME) {
                    108:                while (getc(fin) != '\0')
                    109:                        ;
                    110:        }
                    111:        if (gh.flags & GZIP_FCOMMENT) {
                    112:                while (getc(fin) != '\0')
                    113:                        ;
                    114:        }
                    115:        if (gh.flags & GZIP_FENCRYPT &&
                    116:            fread(buf, 1, GZIP_FENCRYPT_LEN, fin) != GZIP_FENCRYPT_LEN)
                    117:                return (-1);
                    118:
                    119:        /* Check signature version. */
                    120:        if (gd->version != GZSIG_VERSION) {
                    121:                fprintf(stderr, "Unknown signature version: %d\n",
                    122:                    gd->version);
                    123:                return (-1);
                    124:        }
                    125:        /* Compute SHA1 checksum over compressed data and trailer. */
                    126:        sig = (u_char *)(gd + 1);
                    127:        siglen = gx->subfield.len - sizeof(*gd);
                    128:
                    129:        SHA1_Init(&ctx);
                    130:
                    131:        while ((i = fread(buf, 1, sizeof(buf), fin)) > 0) {
                    132:                SHA1_Update(&ctx, buf, i);
                    133:        }
                    134:        SHA1_Final(digest, &ctx);
                    135:
                    136:        /* Verify signature. */
                    137:        if (key_verify(key, digest, sizeof(digest), sig, siglen) < 0) {
                    138:                fprintf(stderr, "Error verifying signature\n");
                    139:                return (-1);
                    140:        }
                    141:        return (0);
                    142: }
                    143:
                    144: void
                    145: verify_usage(void)
                    146: {
                    147:        fprintf(stderr, "Usage: gzsig verify [-v] pubkey [file ...]\n");
                    148: }
                    149:
                    150: void
                    151: verify(int argc, char *argv[])
                    152: {
                    153:        struct key *key;
                    154:        char *gzipfile;
                    155:        FILE *fin;
                    156:        int i, error, vflag;
                    157:
                    158:        vflag = 0;
                    159:
                    160:        while ((i = getopt(argc, argv, "vh?")) != -1) {
                    161:                switch (i) {
                    162:                case 'v':
                    163:                        vflag = 1;
                    164:                        break;
                    165:                default:
                    166:                        verify_usage();
                    167:                        exit(1);
                    168:                }
                    169:        }
                    170:        argc -= optind;
                    171:        argv += optind;
                    172:
                    173:        if (argc < 1) {
                    174:                verify_usage();
                    175:                exit(1);
                    176:        }
                    177:        OpenSSL_add_all_algorithms();
                    178:
                    179:        if ((key = key_new()) == NULL)
                    180:                fatal(1, "Can't initialize public key");
                    181:
                    182:        if (key_load_public(key, argv[0]) < 0)
                    183:                fatal(1, "Can't load public key");
                    184:
                    185:        if (argc == 1 || *argv[1] == '-') {
                    186:                argc = 0;
                    187:
                    188:                if (verify_signature(key, stdin) == 0) {
                    189:                        if (vflag)
                    190:                                fprintf(stderr, "Verified input\n");
                    191:                } else
                    192:                        fatal(1, "Couldn't verify input");
                    193:        }
                    194:        for (i = 1; i < argc; i++) {
                    195:                gzipfile = argv[i];
                    196:
                    197:                if ((fin = fopen(gzipfile, "r")) < 0) {
                    198:                        fprintf(stderr,  "Couldn't open %s: %s\n",
                    199:                            gzipfile, strerror(errno));
                    200:                        continue;
                    201:                }
                    202:                error = verify_signature(key, fin);
                    203:                fclose(fin);
                    204:
                    205:                if (!error) {
                    206:                        if (vflag)
                    207:                                fprintf(stderr, "Verified %s\n", gzipfile);
                    208:                } else
                    209:                        fatal(1, "Couldn't verify %s", gzipfile);
                    210:        }
                    211:        key_free(key);
                    212: }