[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.9

1.9     ! jmc         1: /* $OpenBSD: verify.c,v 1.8 2013/03/09 21:08:37 tobias Exp $ */
1.1       marius      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:  *
1.2       marius     33:  * $Vendor: verify.c,v 1.3 2005/04/07 23:19:35 dugsong Exp $
1.1       marius     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: {
1.9     ! jmc       147:        fprintf(stderr, "usage: %s verify [-q | -v] [-f secret_file] pubkey "
1.8       tobias    148:            "[file ...]\n", __progname);
1.1       marius    149: }
                    150:
                    151: void
                    152: verify(int argc, char *argv[])
                    153: {
                    154:        struct key *key;
                    155:        char *gzipfile;
                    156:        FILE *fin;
1.3       djm       157:        int i, error, qflag;
1.1       marius    158:
1.3       djm       159:        qflag = 0;
1.1       marius    160:
1.6       moritz    161:        while ((i = getopt(argc, argv, "qv")) != -1) {
1.1       marius    162:                switch (i) {
1.3       djm       163:                case 'q':
                    164:                        qflag = 1;
                    165:                        break;
1.1       marius    166:                case 'v':
1.3       djm       167:                        qflag = 0;
1.1       marius    168:                        break;
                    169:                default:
                    170:                        verify_usage();
                    171:                        exit(1);
                    172:                }
                    173:        }
                    174:        argc -= optind;
                    175:        argv += optind;
                    176:
                    177:        if (argc < 1) {
                    178:                verify_usage();
                    179:                exit(1);
                    180:        }
                    181:        OpenSSL_add_all_algorithms();
                    182:
                    183:        if ((key = key_new()) == NULL)
                    184:                fatal(1, "Can't initialize public key");
                    185:
                    186:        if (key_load_public(key, argv[0]) < 0)
                    187:                fatal(1, "Can't load public key");
                    188:
                    189:        if (argc == 1 || *argv[1] == '-') {
                    190:                argc = 0;
                    191:
                    192:                if (verify_signature(key, stdin) == 0) {
1.3       djm       193:                        if (!qflag)
1.1       marius    194:                                fprintf(stderr, "Verified input\n");
                    195:                } else
                    196:                        fatal(1, "Couldn't verify input");
                    197:        }
                    198:        for (i = 1; i < argc; i++) {
                    199:                gzipfile = argv[i];
                    200:
1.4       djm       201:                if ((fin = fopen(gzipfile, "r")) == NULL) {
1.1       marius    202:                        fprintf(stderr,  "Couldn't open %s: %s\n",
                    203:                            gzipfile, strerror(errno));
                    204:                        continue;
                    205:                }
                    206:                error = verify_signature(key, fin);
                    207:                fclose(fin);
                    208:
                    209:                if (!error) {
1.3       djm       210:                        if (!qflag)
1.1       marius    211:                                fprintf(stderr, "Verified %s\n", gzipfile);
                    212:                } else
                    213:                        fatal(1, "Couldn't verify %s", gzipfile);
                    214:        }
                    215:        key_free(key);
                    216: }