[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     ! 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: }