~ubuntu-branches/ubuntu/lucid/seamonkey/lucid-security

« back to all changes in this revision

Viewing changes to security/nss-fips/cmd/signtool/verify.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabien Tassin
  • Date: 2008-07-29 21:29:02 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080729212902-spm9kpvchp9udwbw
Tags: 1.1.11+nobinonly-0ubuntu1
* New security upstream release: 1.1.11 (LP: #218534)
  Fixes USN-602-1, USN-619-1, USN-623-1 and USN-629-1
* Refresh diverged patch:
  - update debian/patches/80_security_build.patch
* Fix FTBFS with missing -lfontconfig
  - add debian/patches/11_fix_ftbfs_with_fontconfig.patch
  - update debian/patches/series
* Build with default gcc (hardy: 4.2, intrepid: 4.3)
  - update debian/rules
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is the Netscape security libraries.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the MPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the MPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
 
 
37
#include "signtool.h"
 
38
 
 
39
 
 
40
static int      jar_cb(int status, JAR *jar, const char *metafile, 
 
41
char *pathname, char *errortext);
 
42
static int      verify_global (JAR *jar);
 
43
 
 
44
/*************************************************************************
 
45
 *
 
46
 * V e r i f y J a r
 
47
 */
 
48
int
 
49
VerifyJar(char *filename)
 
50
{
 
51
    FILE * fp;
 
52
 
 
53
    int ret;
 
54
    int status;
 
55
    int failed = 0;
 
56
    char        *err;
 
57
 
 
58
    JAR * jar;
 
59
    JAR_Context * ctx;
 
60
 
 
61
    JAR_Item * it;
 
62
 
 
63
    jar = JAR_new();
 
64
 
 
65
    if ((fp = fopen (filename, "r")) == NULL) {
 
66
        perror (filename);
 
67
        exit (ERRX);
 
68
    } else
 
69
        fclose (fp);
 
70
 
 
71
    JAR_set_callback (JAR_CB_SIGNAL, jar, jar_cb);
 
72
 
 
73
 
 
74
    status = JAR_pass_archive (jar, jarArchGuess, filename, "some-url");
 
75
 
 
76
    if (status < 0 || jar->valid < 0) {
 
77
        failed = 1;
 
78
        PR_fprintf(outputFD, 
 
79
            "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
 
80
             filename);
 
81
        if (status < 0) {
 
82
            char        *errtext;
 
83
 
 
84
            if (status >= JAR_BASE && status <= JAR_BASE_END) {
 
85
                errtext = JAR_get_error (status);
 
86
            } else {
 
87
                errtext = SECU_ErrorString ((int16) PORT_GetError());
 
88
            }
 
89
 
 
90
            PR_fprintf(outputFD, "  (reported reason: %s)\n\n",
 
91
                 errtext);
 
92
 
 
93
            /* corrupt files should not have their contents listed */
 
94
 
 
95
            if (status == JAR_ERR_CORRUPT)
 
96
                return - 1;
 
97
        }
 
98
        PR_fprintf(outputFD,
 
99
            "entries shown below will have their digests checked only.\n");
 
100
        jar->valid = 0;
 
101
    } else
 
102
        PR_fprintf(outputFD,
 
103
            "archive \"%s\" has passed crypto verification.\n", filename);
 
104
 
 
105
    if (verify_global (jar))
 
106
        failed = 1;
 
107
 
 
108
    PR_fprintf(outputFD, "\n");
 
109
    PR_fprintf(outputFD, "%16s   %s\n", "status", "path");
 
110
    PR_fprintf(outputFD, "%16s   %s\n", "------------", "-------------------");
 
111
 
 
112
    ctx = JAR_find (jar, NULL, jarTypeMF);
 
113
 
 
114
    while (JAR_find_next (ctx, &it) >= 0) {
 
115
        if (it && it->pathname) {
 
116
            rm_dash_r(TMP_OUTPUT);
 
117
            ret = JAR_verified_extract (jar, it->pathname, TMP_OUTPUT);
 
118
            /* if (ret < 0) printf ("error %d on %s\n", ret, it->pathname); */
 
119
            if (ret < 0) 
 
120
                failed = 1;
 
121
 
 
122
            if (ret == JAR_ERR_PNF)
 
123
                err = "NOT PRESENT";
 
124
            else if (ret == JAR_ERR_HASH)
 
125
                err = "HASH FAILED";
 
126
            else
 
127
                err = "NOT VERIFIED";
 
128
 
 
129
            PR_fprintf(outputFD, "%16s   %s\n", 
 
130
                ret >= 0 ? "verified" : err, it->pathname);
 
131
 
 
132
            if (ret != 0 && ret != JAR_ERR_PNF && ret != JAR_ERR_HASH)
 
133
                PR_fprintf(outputFD, "      (reason: %s)\n",
 
134
                     JAR_get_error (ret));
 
135
        }
 
136
    }
 
137
 
 
138
    JAR_find_end (ctx);
 
139
 
 
140
    if (status < 0 || jar->valid < 0) {
 
141
        failed = 1;
 
142
        PR_fprintf(outputFD,
 
143
            "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
 
144
             filename);
 
145
        give_help (status);
 
146
    }
 
147
 
 
148
    JAR_destroy (jar);
 
149
 
 
150
    if (failed)
 
151
        return - 1;
 
152
    return 0;
 
153
}
 
154
 
 
155
 
 
156
/***************************************************************************
 
157
 *
 
158
 * v e r i f y _ g l o b a l
 
159
 */
 
160
static int      
 
161
verify_global (JAR *jar)
 
162
{
 
163
    FILE        * fp;
 
164
    JAR_Context * ctx;
 
165
    JAR_Item    * it;
 
166
    JAR_Digest  * globaldig;
 
167
    char        * ext;
 
168
    unsigned char *md5_digest, *sha1_digest;
 
169
    unsigned int  sha1_length, md5_length;
 
170
    int           retval = 0;
 
171
    char          buf [BUFSIZ];
 
172
 
 
173
    ctx = JAR_find (jar, "*", jarTypePhy);
 
174
 
 
175
    while (JAR_find_next (ctx, &it) >= 0) {
 
176
        if (!PORT_Strncmp (it->pathname, "META-INF", 8)) {
 
177
            for (ext = it->pathname; *ext; ext++)
 
178
                ;
 
179
            while (ext > it->pathname && *ext != '.') 
 
180
                ext--;
 
181
 
 
182
            if (verbosity >= 0) {
 
183
                if (!PORT_Strcasecmp (ext, ".rsa")) {
 
184
                    PR_fprintf(outputFD, "found a RSA signature file: %s\n",
 
185
                                                          it->pathname);
 
186
                }
 
187
 
 
188
                if (!PORT_Strcasecmp (ext, ".dsa")) {
 
189
                    PR_fprintf(outputFD, "found a DSA signature file: %s\n",
 
190
                                                          it->pathname);
 
191
                }
 
192
 
 
193
                if (!PORT_Strcasecmp (ext, ".mf")) {
 
194
                    PR_fprintf(outputFD,
 
195
                        "found a MF master manifest file: %s\n",
 
196
                         it->pathname);
 
197
                }
 
198
            }
 
199
 
 
200
            if (!PORT_Strcasecmp (ext, ".sf")) {
 
201
                if (verbosity >= 0) {
 
202
                    PR_fprintf(outputFD,
 
203
                        "found a SF signature manifest file: %s\n",
 
204
                         it->pathname);
 
205
                }
 
206
 
 
207
                rm_dash_r(TMP_OUTPUT);
 
208
                if (JAR_extract (jar, it->pathname, TMP_OUTPUT) < 0) {
 
209
                    PR_fprintf(errorFD, "%s: error extracting %s\n",
 
210
                         PROGRAM_NAME, it->pathname);
 
211
                    errorCount++;
 
212
                    retval = -1;
 
213
                    continue;
 
214
                }
 
215
 
 
216
                md5_digest = NULL;
 
217
                sha1_digest = NULL;
 
218
 
 
219
                if ((fp = fopen (TMP_OUTPUT, "rb")) != NULL) {
 
220
                    while (fgets (buf, BUFSIZ, fp)) {
 
221
                        char    *s;
 
222
 
 
223
                        if (*buf == 0 || *buf == '\n' || *buf == '\r') 
 
224
                            break;
 
225
 
 
226
                        for (s = buf; *s && *s != '\n' && *s != '\r'; s++)
 
227
                            ;
 
228
                        *s = 0;
 
229
 
 
230
                        if (!PORT_Strncmp (buf, "MD5-Digest: ", 12)) {
 
231
                            md5_digest = 
 
232
                                ATOB_AsciiToData (buf + 12, &md5_length);
 
233
                        }
 
234
                        if (!PORT_Strncmp (buf, "SHA1-Digest: ", 13)) {
 
235
                            sha1_digest = 
 
236
                                ATOB_AsciiToData (buf + 13, &sha1_length);
 
237
                        }
 
238
                        if (!PORT_Strncmp (buf, "SHA-Digest: ", 12)) {
 
239
                            sha1_digest = 
 
240
                                ATOB_AsciiToData (buf + 12, &sha1_length);
 
241
                        }
 
242
                    }
 
243
 
 
244
                    globaldig = jar->globalmeta;
 
245
 
 
246
                    if (globaldig && md5_digest && verbosity >= 0) {
 
247
                        PR_fprintf(outputFD,
 
248
                           "  md5 digest on global metainfo: %s\n",
 
249
                            PORT_Memcmp(md5_digest, globaldig->md5, MD5_LENGTH)
 
250
                            ? "no match" : "match");
 
251
                    }
 
252
 
 
253
                    if (globaldig && sha1_digest && verbosity >= 0) {
 
254
                        PR_fprintf(outputFD,
 
255
                            "  sha digest on global metainfo: %s\n",
 
256
                            PORT_Memcmp(sha1_digest, globaldig->sha1, SHA1_LENGTH) 
 
257
                            ? "no match" : "match");
 
258
                    }
 
259
 
 
260
                    if (globaldig == NULL && verbosity >= 0) {
 
261
                        PR_fprintf(outputFD,
 
262
                             "global metadigest is not available, strange.\n");
 
263
                    }
 
264
 
 
265
                    fclose (fp);
 
266
                }
 
267
            }
 
268
        }
 
269
    }
 
270
 
 
271
    JAR_find_end (ctx);
 
272
 
 
273
    return retval;
 
274
}
 
275
 
 
276
 
 
277
/************************************************************************
 
278
 *
 
279
 * J a r W h o
 
280
 */
 
281
int
 
282
JarWho(char *filename)
 
283
{
 
284
    FILE * fp;
 
285
 
 
286
    JAR * jar;
 
287
    JAR_Context * ctx;
 
288
 
 
289
    int status;
 
290
    int retval = 0;
 
291
 
 
292
    JAR_Item * it;
 
293
    JAR_Cert * fing;
 
294
 
 
295
    CERTCertificate * cert, *prev = NULL;
 
296
 
 
297
    jar = JAR_new();
 
298
 
 
299
    if ((fp = fopen (filename, "r")) == NULL) {
 
300
        perror (filename);
 
301
        exit (ERRX);
 
302
    } 
 
303
    fclose (fp);
 
304
 
 
305
    status = JAR_pass_archive (jar, jarArchGuess, filename, "some-url");
 
306
 
 
307
    if (status < 0 || jar->valid < 0) {
 
308
        PR_fprintf(outputFD,
 
309
            "NOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
 
310
             filename);
 
311
        retval = -1;
 
312
        if (jar->valid < 0 || status != -1) {
 
313
            char        *errtext;
 
314
 
 
315
            if (status >= JAR_BASE && status <= JAR_BASE_END) {
 
316
                errtext = JAR_get_error (status);
 
317
            } else {
 
318
                errtext = SECU_ErrorString ((int16) PORT_GetError());
 
319
            }
 
320
 
 
321
            PR_fprintf(outputFD, "  (reported reason: %s)\n\n", errtext);
 
322
        }
 
323
    }
 
324
 
 
325
    PR_fprintf(outputFD, "\nSigner information:\n\n");
 
326
 
 
327
    ctx = JAR_find (jar, NULL, jarTypeSign);
 
328
 
 
329
    while (JAR_find_next (ctx, &it) >= 0) {
 
330
        fing = (JAR_Cert * ) it->data;
 
331
        cert = fing->cert;
 
332
 
 
333
        if (cert) {
 
334
            if (prev == cert)
 
335
                break;
 
336
 
 
337
            if (cert->nickname)
 
338
                PR_fprintf(outputFD, "nickname: %s\n", cert->nickname);
 
339
            if (cert->subjectName)
 
340
                PR_fprintf(outputFD, "subject name: %s\n",
 
341
                     cert->subjectName);
 
342
            if (cert->issuerName)
 
343
                PR_fprintf(outputFD, "issuer name: %s\n", cert->issuerName);
 
344
        } else {
 
345
            PR_fprintf(outputFD, "no certificate could be found\n");
 
346
            retval = -1;
 
347
        }
 
348
 
 
349
        prev = cert;
 
350
    }
 
351
 
 
352
    JAR_find_end (ctx);
 
353
 
 
354
    JAR_destroy (jar);
 
355
    return retval;
 
356
}
 
357
 
 
358
 
 
359
/************************************************************************
 
360
 * j a r _ c b
 
361
 */
 
362
static int      jar_cb(int status, JAR *jar, const char *metafile,
 
363
char *pathname, char *errortext)
 
364
{
 
365
    PR_fprintf(errorFD, "error %d: %s IN FILE %s\n", status, errortext,
 
366
         pathname);
 
367
    errorCount++;
 
368
    return 0;
 
369
}
 
370
 
 
371