~ubuntu-branches/ubuntu/lucid/nss/lucid-security

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/jar/jarsign.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-11-15 08:08:08 UTC
  • mfrom: (1.2.7)
  • Revision ID: package-import@ubuntu.com-20131115080808-dba1asgnjl9tc66s
Tags: 3.15.3-0ubuntu0.10.04.1
* SECURITY UPDATE: New upstream release to fix multiple security issues
  and add TLSv1.2 support.
  - CVE-2013-1739
  - CVE-2013-1741
  - CVE-2013-5605
  - CVE-2013-5606
* Adjusted packaging for 3.15.3:
  - debian/patches/*: refreshed.
  - debian/patches/01_dont_build_nspr.patch: removed, changed build
    options in debian/rules instead.
  - debian/libnss3-1d.symbols: added new symbols.
  - debian/rules: updated for new source layout.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
 
 
5
 
/*
6
 
 *  JARSIGN
7
 
 *
8
 
 *  Routines used in signing archives.
9
 
 */
10
 
 
11
 
 
12
 
#include "jar.h"
13
 
#include "jarint.h"
14
 
#include "secpkcs7.h"
15
 
#include "pk11func.h"
16
 
#include "sechash.h"
17
 
 
18
 
/* from libevent.h */
19
 
typedef void (*ETVoidPtrFunc) (void * data);
20
 
 
21
 
/* key database wrapper */
22
 
/* static SECKEYKeyDBHandle *jar_open_key_database (void); */
23
 
/* CHUNQ is our bite size */
24
 
 
25
 
#define CHUNQ 64000
26
 
#define FILECHUNQ 32768
27
 
 
28
 
/*
29
 
 *  J A R _ c a l c u l a t e _ d i g e s t
30
 
 *
31
 
 *  Quick calculation of a digest for
32
 
 *  the specified block of memory. Will calculate
33
 
 *  for all supported algorithms, now MD5.
34
 
 *
35
 
 *  This version supports huge pointers for WIN16.
36
 
 *
37
 
 */
38
 
JAR_Digest * PR_CALLBACK 
39
 
JAR_calculate_digest(void *data, long length)
40
 
{
41
 
    PK11Context *md5  = 0;
42
 
    PK11Context *sha1 = 0;
43
 
    JAR_Digest *dig   = PORT_ZNew(JAR_Digest);
44
 
    long chunq;
45
 
    unsigned int md5_length, sha1_length;
46
 
 
47
 
    if (dig == NULL) {
48
 
        /* out of memory allocating digest */
49
 
        return NULL;
50
 
    }
51
 
 
52
 
    md5  = PK11_CreateDigestContext(SEC_OID_MD5);
53
 
    sha1 = PK11_CreateDigestContext(SEC_OID_SHA1);
54
 
 
55
 
    if (length >= 0) {
56
 
        PK11_DigestBegin (md5);
57
 
        PK11_DigestBegin (sha1);
58
 
 
59
 
        do {
60
 
            chunq = length;
61
 
 
62
 
            PK11_DigestOp(md5,  (unsigned char*)data, chunq);
63
 
            PK11_DigestOp(sha1, (unsigned char*)data, chunq);
64
 
            length -= chunq;
65
 
            data = ((char *) data + chunq);
66
 
        }
67
 
        while (length > 0);
68
 
 
69
 
        PK11_DigestFinal (md5,  dig->md5,  &md5_length,  MD5_LENGTH);
70
 
        PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
71
 
 
72
 
        PK11_DestroyContext (md5,  PR_TRUE);
73
 
        PK11_DestroyContext (sha1, PR_TRUE);
74
 
    }
75
 
    return dig;
76
 
}
77
 
 
78
 
/*
79
 
 *  J A R _ d i g e s t _ f i l e
80
 
 *
81
 
 *  Calculates the MD5 and SHA1 digests for a file
82
 
 *  present on disk, and returns these in JAR_Digest struct.
83
 
 *
84
 
 */
85
 
int 
86
 
JAR_digest_file (char *filename, JAR_Digest *dig)
87
 
{
88
 
    JAR_FILE fp;
89
 
    PK11Context *md5 = 0;
90
 
    PK11Context *sha1 = 0;
91
 
    unsigned char *buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ);
92
 
    int num;
93
 
    unsigned int md5_length, sha1_length;
94
 
 
95
 
    if (buf == NULL) {
96
 
        /* out of memory */
97
 
        return JAR_ERR_MEMORY;
98
 
    }
99
 
 
100
 
    if ((fp = JAR_FOPEN (filename, "rb")) == 0) {
101
 
        /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */
102
 
        PORT_Free (buf);
103
 
        return JAR_ERR_FNF;
104
 
    }
105
 
 
106
 
    md5 = PK11_CreateDigestContext (SEC_OID_MD5);
107
 
    sha1 = PK11_CreateDigestContext (SEC_OID_SHA1);
108
 
 
109
 
    if (md5 == NULL || sha1 == NULL) {
110
 
        /* can't generate digest contexts */
111
 
        PORT_Free (buf);
112
 
        JAR_FCLOSE (fp);
113
 
        return JAR_ERR_GENERAL;
114
 
    }
115
 
 
116
 
    PK11_DigestBegin (md5);
117
 
    PK11_DigestBegin (sha1);
118
 
 
119
 
    while (1) {
120
 
        if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0)
121
 
            break;
122
 
 
123
 
        PK11_DigestOp (md5, buf, num);
124
 
        PK11_DigestOp (sha1, buf, num);
125
 
    }
126
 
 
127
 
    PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH);
128
 
    PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
129
 
 
130
 
    PK11_DestroyContext (md5, PR_TRUE);
131
 
    PK11_DestroyContext (sha1, PR_TRUE);
132
 
 
133
 
    PORT_Free (buf);
134
 
    JAR_FCLOSE (fp);
135
 
 
136
 
    return 0;
137
 
}
138
 
 
139
 
/*
140
 
 *  J A R _ o p e n _ k e y _ d a t a b a s e
141
 
 *
142
 
 */
143
 
 
144
 
void* 
145
 
jar_open_key_database(void)
146
 
{
147
 
    return NULL;
148
 
}
149
 
 
150
 
int 
151
 
jar_close_key_database(void *keydb)
152
 
{
153
 
    /* We never do close it */
154
 
    return 0;
155
 
}
156
 
 
157
 
 
158
 
/*
159
 
 *  j a r _ c r e a t e _ p k 7
160
 
 *
161
 
 */
162
 
 
163
 
static void jar_pk7_out (void *arg, const char *buf, unsigned long len)
164
 
{
165
 
    JAR_FWRITE ((JAR_FILE) arg, buf, len);
166
 
}
167
 
 
168
 
int 
169
 
jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert, 
170
 
               char *password, JAR_FILE infp, JAR_FILE outfp)
171
 
{
172
 
    SEC_PKCS7ContentInfo *cinfo;
173
 
    const SECHashObject *hashObj;
174
 
    char *errstring;
175
 
    void *mw = NULL;
176
 
    void *hashcx;
177
 
    unsigned int len;
178
 
    int status = 0;
179
 
    SECStatus rv;
180
 
    SECItem digest;
181
 
    unsigned char digestdata[32];
182
 
    unsigned char buffer[4096];
183
 
 
184
 
    if (outfp == NULL || infp == NULL || cert == NULL)
185
 
        return JAR_ERR_GENERAL;
186
 
 
187
 
    /* we sign with SHA */
188
 
    hashObj = HASH_GetHashObject(HASH_AlgSHA1);
189
 
 
190
 
    hashcx = (* hashObj->create)();
191
 
    if (hashcx == NULL)
192
 
        return JAR_ERR_GENERAL;
193
 
 
194
 
    (* hashObj->begin)(hashcx);
195
 
    while (1) {
196
 
        int nb = JAR_FREAD(infp, buffer, sizeof buffer);
197
 
        if (nb == 0) { /* eof */
198
 
            break;
199
 
        }
200
 
        (* hashObj->update) (hashcx, buffer, nb);
201
 
    }
202
 
    (* hashObj->end)(hashcx, digestdata, &len, 32);
203
 
    (* hashObj->destroy)(hashcx, PR_TRUE);
204
 
 
205
 
    digest.data = digestdata;
206
 
    digest.len = len;
207
 
 
208
 
    /* signtool must use any old context it can find since it's
209
 
         calling from inside javaland. */
210
 
    PORT_SetError (0);
211
 
    cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL,
212
 
                                      SEC_OID_SHA1, &digest, NULL, mw);
213
 
    if (cinfo == NULL)
214
 
        return JAR_ERR_PK7;
215
 
 
216
 
    rv = SEC_PKCS7IncludeCertChain(cinfo, NULL);
217
 
    if (rv != SECSuccess) {
218
 
        status = PORT_GetError();
219
 
        SEC_PKCS7DestroyContentInfo(cinfo);
220
 
        return status;
221
 
    }
222
 
 
223
 
    /* Having this here forces signtool to always include signing time. */
224
 
    rv = SEC_PKCS7AddSigningTime(cinfo);
225
 
    /* don't check error */
226
 
    PORT_SetError(0);
227
 
 
228
 
    /* if calling from mozilla thread*/
229
 
    rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw);
230
 
    if (rv != SECSuccess)
231
 
        status = PORT_GetError();
232
 
    SEC_PKCS7DestroyContentInfo (cinfo);
233
 
    if (rv != SECSuccess) {
234
 
        errstring = JAR_get_error (status);
235
 
        return ((status < 0) ? status : JAR_ERR_GENERAL);
236
 
    }
237
 
    return 0;
238
 
}