~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/freebl/shvfy.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Mozilla Public License Version
 
6
 * 1.1 (the "License"); you may not use this file except in compliance with
 
7
 * the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/MPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is the Netscape security libraries.
 
16
 *
 
17
 * The Initial Developer of the Original Code is
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 2003
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the MPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the MPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
/* $Id: shvfy.c,v 1.10 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
 
38
 
 
39
#include "shsign.h"
 
40
#include "prlink.h"
 
41
#include "prio.h"
 
42
#include "blapi.h"
 
43
#include "seccomon.h"
 
44
#include "stdio.h"
 
45
#include "prmem.h"
 
46
 
 
47
/* #define DEBUG_SHVERIFY 1 */
 
48
 
 
49
static char *
 
50
mkCheckFileName(const char *libName)
 
51
{
 
52
    int ln_len = PORT_Strlen(libName);
 
53
    char *output = PORT_Alloc(ln_len+sizeof(SGN_SUFFIX));
 
54
    int index = ln_len + 1 - sizeof("."SHLIB_SUFFIX);
 
55
 
 
56
    if ((index > 0) &&
 
57
        (PORT_Strncmp(&libName[index],
 
58
                        "."SHLIB_SUFFIX,sizeof("."SHLIB_SUFFIX)) == 0)) {
 
59
        ln_len = index;
 
60
    }
 
61
    PORT_Memcpy(output,libName,ln_len);
 
62
    PORT_Memcpy(&output[ln_len],SGN_SUFFIX,sizeof(SGN_SUFFIX));
 
63
    return output;
 
64
}
 
65
 
 
66
static int
 
67
decodeInt(unsigned char *buf)
 
68
{
 
69
    return (buf[3]) | (buf[2] << 8) | (buf[1] << 16) | (buf[0] << 24);
 
70
}
 
71
 
 
72
static SECStatus
 
73
readItem(PRFileDesc *fd, SECItem *item)
 
74
{
 
75
    unsigned char buf[4];
 
76
    int bytesRead;
 
77
 
 
78
 
 
79
    bytesRead = PR_Read(fd, buf, 4);
 
80
    if (bytesRead != 4) {
 
81
        return SECFailure;
 
82
    }
 
83
    item->len = decodeInt(buf);
 
84
 
 
85
    item->data = PORT_Alloc(item->len);
 
86
    if (item->data == NULL) {
 
87
        item->len = 0;
 
88
        return SECFailure;
 
89
    }
 
90
    bytesRead = PR_Read(fd, item->data, item->len);
 
91
    if (bytesRead != item->len) {
 
92
        PORT_Free(item->data);
 
93
        item->data = NULL;
 
94
        item->len = 0;
 
95
        return SECFailure;
 
96
    }
 
97
    return SECSuccess;
 
98
}
 
99
 
 
100
PRBool
 
101
BLAPI_SHVerify(const char *name, PRFuncPtr addr)
 
102
{
 
103
    /* find our shared library name */
 
104
    char *shName = PR_GetLibraryFilePathname(name, addr);
 
105
    char *checkName = NULL;
 
106
    PRFileDesc *checkFD = NULL;
 
107
    PRFileDesc *shFD = NULL;
 
108
    SHA1Context *hashcx = NULL;
 
109
    SECItem signature = { 0, NULL, 0 };
 
110
    SECItem hash;
 
111
    int bytesRead, offset;
 
112
    SECStatus rv;
 
113
    DSAPublicKey key;
 
114
    int count;
 
115
 
 
116
    PRBool result = PR_FALSE; /* if anything goes wrong,
 
117
                               * the signature does not verify */
 
118
    unsigned char buf[512];
 
119
    unsigned char hashBuf[SHA1_LENGTH];
 
120
 
 
121
    PORT_Memset(&key,0,sizeof(key));
 
122
    hash.data = hashBuf;
 
123
    hash.len = sizeof(hashBuf);
 
124
 
 
125
    if (!shName) {
 
126
        goto loser;
 
127
    }
 
128
 
 
129
    /* figure out the name of our check file */
 
130
    checkName = mkCheckFileName(shName);
 
131
    if (!checkName) {
 
132
        goto loser;
 
133
    }
 
134
 
 
135
    /* open the check File */
 
136
    checkFD = PR_Open(checkName, PR_RDONLY, 0);
 
137
    if (checkFD == NULL) {
 
138
#ifdef DEBUG_SHVERIFY
 
139
        fprintf(stderr, "Failed to open the check file %s: (%d, %d)\n",
 
140
                checkName, (int)PR_GetError(), (int)PR_GetOSError());
 
141
#endif /* DEBUG_SHVERIFY */
 
142
        goto loser;
 
143
    }
 
144
 
 
145
    /* read and Verify the headerthe header */
 
146
    bytesRead = PR_Read(checkFD, buf, 12);
 
147
    if (bytesRead != 12) {
 
148
        goto loser;
 
149
    }
 
150
    if ((buf[0] != NSS_SIGN_CHK_MAGIC1) || (buf[1] != NSS_SIGN_CHK_MAGIC2)) {
 
151
        goto loser;
 
152
    }
 
153
    if ((buf[2] != NSS_SIGN_CHK_MAJOR_VERSION) || 
 
154
                                (buf[3] < NSS_SIGN_CHK_MINOR_VERSION)) {
 
155
        goto loser;
 
156
    }
 
157
#ifdef notdef
 
158
    if (decodeInt(&buf[8]) != CKK_DSA) {
 
159
        goto loser;
 
160
    }
 
161
#endif
 
162
 
 
163
    /* seek past any future header extensions */
 
164
    offset = decodeInt(&buf[4]);
 
165
    PR_Seek(checkFD, offset, PR_SEEK_SET);
 
166
 
 
167
    /* read the key */
 
168
    rv = readItem(checkFD,&key.params.prime);
 
169
    if (rv != SECSuccess) {
 
170
        goto loser;
 
171
    }
 
172
    rv = readItem(checkFD,&key.params.subPrime);
 
173
    if (rv != SECSuccess) {
 
174
        goto loser;
 
175
    }
 
176
    rv = readItem(checkFD,&key.params.base);
 
177
    if (rv != SECSuccess) {
 
178
        goto loser;
 
179
    }
 
180
    rv = readItem(checkFD,&key.publicValue);
 
181
    if (rv != SECSuccess) {
 
182
        goto loser;
 
183
    }
 
184
    /* read the siganture */
 
185
    rv = readItem(checkFD,&signature);
 
186
    if (rv != SECSuccess) {
 
187
        goto loser;
 
188
    }
 
189
 
 
190
    /* done with the check file */
 
191
    PR_Close(checkFD);
 
192
    checkFD = NULL;
 
193
 
 
194
    /* open our library file */
 
195
    shFD = PR_Open(shName, PR_RDONLY, 0);
 
196
    if (shFD == NULL) {
 
197
#ifdef DEBUG_SHVERIFY
 
198
        fprintf(stderr, "Failed to open the library file %s: (%d, %d)\n",
 
199
                shName, (int)PR_GetError(), (int)PR_GetOSError());
 
200
#endif /* DEBUG_SHVERIFY */
 
201
        goto loser;
 
202
    }
 
203
 
 
204
    /* hash our library file with SHA1 */
 
205
    hashcx = SHA1_NewContext();
 
206
    if (hashcx == NULL) {
 
207
        goto loser;
 
208
    }
 
209
    SHA1_Begin(hashcx);
 
210
 
 
211
    count = 0;
 
212
    while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
 
213
        SHA1_Update(hashcx, buf, bytesRead);
 
214
        count += bytesRead;
 
215
    }
 
216
    PR_Close(shFD);
 
217
    shFD = NULL;
 
218
 
 
219
    SHA1_End(hashcx, hash.data, &hash.len, hash.len);
 
220
 
 
221
 
 
222
    /* verify the hash against the check file */
 
223
    if (DSA_VerifyDigest(&key, &signature, &hash) == SECSuccess) {
 
224
        result = PR_TRUE;
 
225
    }
 
226
#ifdef DEBUG_SHVERIFY
 
227
  {
 
228
        int i,j;
 
229
        fprintf(stderr,"File %s: %d bytes\n",shName, count);
 
230
        fprintf(stderr,"  hash: %d bytes\n", hash.len);
 
231
#define STEP 10
 
232
        for (i=0; i < hash.len; i += STEP) {
 
233
           fprintf(stderr,"   ");
 
234
           for (j=0; j < STEP && (i+j) < hash.len; j++) {
 
235
                fprintf(stderr," %02x", hash.data[i+j]);
 
236
           }
 
237
           fprintf(stderr,"\n");
 
238
        }
 
239
        fprintf(stderr,"  signature: %d bytes\n", signature.len);
 
240
        for (i=0; i < signature.len; i += STEP) {
 
241
           fprintf(stderr,"   ");
 
242
           for (j=0; j < STEP && (i+j) < signature.len; j++) {
 
243
                fprintf(stderr," %02x", signature.data[i+j]);
 
244
           }
 
245
           fprintf(stderr,"\n");
 
246
        }
 
247
        fprintf(stderr,"Verified : %s\n",result?"TRUE": "FALSE");
 
248
    }
 
249
#endif /* DEBUG_SHVERIFY */
 
250
 
 
251
 
 
252
loser:
 
253
    if (shName != NULL) {
 
254
        PR_Free(shName);
 
255
    }
 
256
    if (checkName != NULL) {
 
257
        PORT_Free(checkName);
 
258
    }
 
259
    if (checkFD != NULL) {
 
260
        PR_Close(checkFD);
 
261
    }
 
262
    if (shFD != NULL) {
 
263
        PR_Close(shFD);
 
264
    }
 
265
    if (hashcx != NULL) {
 
266
        SHA1_DestroyContext(hashcx,PR_TRUE);
 
267
    }
 
268
    if (signature.data != NULL) {
 
269
        PORT_Free(signature.data);
 
270
    }
 
271
    if (key.params.prime.data != NULL) {
 
272
        PORT_Free(key.params.prime.data);
 
273
    }
 
274
    if (key.params.subPrime.data != NULL) {
 
275
        PORT_Free(key.params.subPrime.data);
 
276
    }
 
277
    if (key.params.base.data != NULL) {
 
278
        PORT_Free(key.params.base.data);
 
279
    }
 
280
    if (key.publicValue.data != NULL) {
 
281
        PORT_Free(key.publicValue.data);
 
282
    }
 
283
 
 
284
    return result;
 
285
}
 
286
 
 
287
PRBool
 
288
BLAPI_VerifySelf(const char *name)
 
289
{
 
290
    /* to separate shlib to verify if name is NULL */
 
291
    if (name == NULL) {
 
292
        return PR_TRUE;
 
293
    }
 
294
    return BLAPI_SHVerify(name, (PRFuncPtr) decodeInt);
 
295
}