~ubuntu-branches/ubuntu/karmic/nss/karmic-updates

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2010-03-31 02:23:43 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100331022343-ck07ylqk8q474x26
Tags: 3.12.6-0ubuntu0.9.10.1
* New upstream release 3.12.6 RTM (NSS_3_12_6_RTM)
  - fixes CVE-2009-3555 aka US-CERT VU#120541
* Adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
  - update debian/patches/38_mips64_build.patch
  - update debian/patches/85_security_load.patch
* Remove patches that are merged upstream
  - delete debian/patches/91_nonexec_stack.patch
  - update debian/patches/series
* Bump nspr dependency to 4.8
  - update debian/control
* Add new symbols for 3.12.6
  - update debian/libnss3-1d.symbols 
* Enable transitional scheme for SSL renegotiation
  - add 97_SSL_RENEGOTIATE_TRANSITIONAL.patch
  - update debian/patches/series

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
/* from libevent.h */
51
51
typedef void (*ETVoidPtrFunc) (void * data);
52
52
 
53
 
#ifdef MOZILLA_CLIENT_OLD
54
 
 
55
 
extern void ET_moz_CallFunction (ETVoidPtrFunc fn, void *data);
56
 
 
57
 
/* from proto.h */
58
 
/* extern MWContext *XP_FindSomeContext(void); */
59
 
extern void *XP_FindSomeContext(void);
60
 
 
61
 
#endif
62
 
 
63
53
/* key database wrapper */
64
 
 
65
54
/* static SECKEYKeyDBHandle *jar_open_key_database (void); */
66
 
 
67
55
/* CHUNQ is our bite size */
68
56
 
69
57
#define CHUNQ 64000
70
58
#define FILECHUNQ 32768
71
59
 
72
60
/*
73
 
 *  J A R _ c a l c u l a t e _ d i g e s t 
 
61
 *  J A R _ c a l c u l a t e _ d i g e s t
74
62
 *
75
63
 *  Quick calculation of a digest for
76
64
 *  the specified block of memory. Will calculate
77
65
 *  for all supported algorithms, now MD5.
78
66
 *
79
67
 *  This version supports huge pointers for WIN16.
80
 
 * 
 
68
 *
81
69
 */
82
 
 
83
 
JAR_Digest * PR_CALLBACK JAR_calculate_digest (void ZHUGEP *data, long length)
84
 
  {
85
 
  long chunq;
86
 
  JAR_Digest *dig;
87
 
 
88
 
  unsigned int md5_length, sha1_length;
89
 
 
90
 
  PK11Context *md5  = 0;
91
 
  PK11Context *sha1 = 0;
92
 
 
93
 
  dig = (JAR_Digest *) PORT_ZAlloc (sizeof (JAR_Digest));
94
 
 
95
 
  if (dig == NULL) 
96
 
    {
97
 
    /* out of memory allocating digest */
98
 
    return NULL;
99
 
    }
100
 
 
101
 
#if defined(XP_WIN16)
102
 
  PORT_Assert ( !IsBadHugeReadPtr(data, length) );
103
 
#endif
104
 
 
105
 
  md5  = PK11_CreateDigestContext (SEC_OID_MD5);
106
 
  sha1 = PK11_CreateDigestContext (SEC_OID_SHA1);
107
 
 
108
 
  if (length >= 0) 
109
 
    {
110
 
    PK11_DigestBegin (md5);
111
 
    PK11_DigestBegin (sha1);
112
 
 
113
 
    do {
114
 
       chunq = length;
115
 
 
116
 
#ifdef XP_WIN16
117
 
       if (length > CHUNQ) chunq = CHUNQ;
118
 
 
119
 
       /*
120
 
        *  If the block of data crosses one or more segment 
121
 
        *  boundaries then only pass the chunk of data in the 
122
 
        *  first segment.
123
 
        * 
124
 
        *  This allows the data to be treated as FAR by the
125
 
        *  PK11_DigestOp(...) routine.
126
 
        *
127
 
        */
128
 
 
129
 
       if (OFFSETOF(data) + chunq >= 0x10000) 
130
 
         chunq = 0x10000 - OFFSETOF(data);
131
 
#endif
132
 
 
133
 
       PK11_DigestOp (md5,  (unsigned char*)data, chunq);
134
 
       PK11_DigestOp (sha1, (unsigned char*)data, chunq);
135
 
 
136
 
       length -= chunq;
137
 
       data = ((char ZHUGEP *) data + chunq);
138
 
       } 
139
 
    while (length > 0);
140
 
 
141
 
    PK11_DigestFinal (md5,  dig->md5,  &md5_length,  MD5_LENGTH);
142
 
    PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
143
 
 
144
 
    PK11_DestroyContext (md5,  PR_TRUE);
145
 
    PK11_DestroyContext (sha1, PR_TRUE);
146
 
    }
147
 
 
148
 
  return dig;
149
 
  }
 
70
JAR_Digest * PR_CALLBACK 
 
71
JAR_calculate_digest(void *data, long length)
 
72
{
 
73
    PK11Context *md5  = 0;
 
74
    PK11Context *sha1 = 0;
 
75
    JAR_Digest *dig   = PORT_ZNew(JAR_Digest);
 
76
    long chunq;
 
77
    unsigned int md5_length, sha1_length;
 
78
 
 
79
    if (dig == NULL) {
 
80
        /* out of memory allocating digest */
 
81
        return NULL;
 
82
    }
 
83
 
 
84
    md5  = PK11_CreateDigestContext(SEC_OID_MD5);
 
85
    sha1 = PK11_CreateDigestContext(SEC_OID_SHA1);
 
86
 
 
87
    if (length >= 0) {
 
88
        PK11_DigestBegin (md5);
 
89
        PK11_DigestBegin (sha1);
 
90
 
 
91
        do {
 
92
            chunq = length;
 
93
 
 
94
            PK11_DigestOp(md5,  (unsigned char*)data, chunq);
 
95
            PK11_DigestOp(sha1, (unsigned char*)data, chunq);
 
96
            length -= chunq;
 
97
            data = ((char *) data + chunq);
 
98
        }
 
99
        while (length > 0);
 
100
 
 
101
        PK11_DigestFinal (md5,  dig->md5,  &md5_length,  MD5_LENGTH);
 
102
        PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
 
103
 
 
104
        PK11_DestroyContext (md5,  PR_TRUE);
 
105
        PK11_DestroyContext (sha1, PR_TRUE);
 
106
    }
 
107
    return dig;
 
108
}
150
109
 
151
110
/*
152
111
 *  J A R _ d i g e s t _ f i l e
153
112
 *
154
 
 *  Calculates the MD5 and SHA1 digests for a file 
 
113
 *  Calculates the MD5 and SHA1 digests for a file
155
114
 *  present on disk, and returns these in JAR_Digest struct.
156
115
 *
157
116
 */
158
 
 
159
 
int JAR_digest_file (char *filename, JAR_Digest *dig)
160
 
    {
 
117
int 
 
118
JAR_digest_file (char *filename, JAR_Digest *dig)
 
119
{
161
120
    JAR_FILE fp;
162
 
 
 
121
    PK11Context *md5 = 0;
 
122
    PK11Context *sha1 = 0;
 
123
    unsigned char *buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ);
163
124
    int num;
164
 
    unsigned char *buf;
165
 
 
166
 
    PK11Context *md5 = 0;
167
 
    PK11Context *sha1 = 0;
168
 
 
169
125
    unsigned int md5_length, sha1_length;
170
126
 
171
 
    buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ);
172
 
    if (buf == NULL)
173
 
      {
174
 
      /* out of memory */
175
 
      return JAR_ERR_MEMORY;
176
 
      }
177
 
 
178
 
    if ((fp = JAR_FOPEN (filename, "rb")) == 0)
179
 
      {
180
 
      /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */
181
 
      PORT_Free (buf);
182
 
      return JAR_ERR_FNF;
183
 
      }
 
127
    if (buf == NULL) {
 
128
        /* out of memory */
 
129
        return JAR_ERR_MEMORY;
 
130
    }
 
131
 
 
132
    if ((fp = JAR_FOPEN (filename, "rb")) == 0) {
 
133
        /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */
 
134
        PORT_Free (buf);
 
135
        return JAR_ERR_FNF;
 
136
    }
184
137
 
185
138
    md5 = PK11_CreateDigestContext (SEC_OID_MD5);
186
139
    sha1 = PK11_CreateDigestContext (SEC_OID_SHA1);
187
140
 
188
 
    if (md5 == NULL || sha1 == NULL) 
189
 
      {
190
 
      /* can't generate digest contexts */
191
 
      PORT_Free (buf);
192
 
      JAR_FCLOSE (fp);
193
 
      return JAR_ERR_GENERAL;
194
 
      }
 
141
    if (md5 == NULL || sha1 == NULL) {
 
142
        /* can't generate digest contexts */
 
143
        PORT_Free (buf);
 
144
        JAR_FCLOSE (fp);
 
145
        return JAR_ERR_GENERAL;
 
146
    }
195
147
 
196
148
    PK11_DigestBegin (md5);
197
149
    PK11_DigestBegin (sha1);
198
150
 
199
 
    while (1)
200
 
      {
201
 
      if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0)
202
 
        break;
 
151
    while (1) {
 
152
        if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0)
 
153
            break;
203
154
 
204
 
      PK11_DigestOp (md5, buf, num);
205
 
      PK11_DigestOp (sha1, buf, num);
206
 
      }
 
155
        PK11_DigestOp (md5, buf, num);
 
156
        PK11_DigestOp (sha1, buf, num);
 
157
    }
207
158
 
208
159
    PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH);
209
160
    PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
215
166
    JAR_FCLOSE (fp);
216
167
 
217
168
    return 0;
218
 
    }
 
169
}
219
170
 
220
171
/*
221
172
 *  J A R _ o p e n _ k e y _ d a t a b a s e
222
173
 *
223
174
 */
224
175
 
225
 
void* jar_open_key_database (void)
226
 
  {
 
176
void* 
 
177
jar_open_key_database(void)
 
178
{
227
179
    return NULL;
228
 
  }
 
180
}
229
181
 
230
 
int jar_close_key_database (void *keydb)
231
 
  {
232
 
  /* We never do close it */
233
 
  return 0;
234
 
  }
 
182
int 
 
183
jar_close_key_database(void *keydb)
 
184
{
 
185
    /* We never do close it */
 
186
    return 0;
 
187
}
235
188
 
236
189
 
237
190
/*
240
193
 */
241
194
 
242
195
static void jar_pk7_out (void *arg, const char *buf, unsigned long len)
243
 
  {
244
 
  JAR_FWRITE ((JAR_FILE) arg, buf, len);
245
 
  }
246
 
 
247
 
int jar_create_pk7 
248
 
   (CERTCertDBHandle *certdb, void *keydb, 
249
 
       CERTCertificate *cert, char *password, JAR_FILE infp, JAR_FILE outfp)
250
 
  {
251
 
  int nb;
252
 
  unsigned char buffer [4096], digestdata[32];
253
 
  const SECHashObject *hashObj;
254
 
  void *hashcx;
255
 
  unsigned int len;
256
 
 
257
 
  int status = 0;
258
 
  char *errstring;
259
 
 
260
 
  SECItem digest;
261
 
  SEC_PKCS7ContentInfo *cinfo;
262
 
  SECStatus rv;
263
 
 
264
 
  void /*MWContext*/ *mw;
265
 
 
266
 
  if (outfp == NULL || infp == NULL || cert == NULL)
267
 
    return JAR_ERR_GENERAL;
268
 
 
269
 
  /* we sign with SHA */
270
 
  hashObj = HASH_GetHashObject(HASH_AlgSHA1);
271
 
 
272
 
  hashcx = (* hashObj->create)();
273
 
  if (hashcx == NULL)
274
 
    return JAR_ERR_GENERAL;
275
 
 
276
 
  (* hashObj->begin)(hashcx);
277
 
 
278
 
  while (1)
279
 
    {
280
 
    /* nspr2.0 doesn't support feof 
281
 
       if (feof (infp)) break; */
282
 
 
283
 
    nb = JAR_FREAD (infp, buffer, sizeof (buffer));
284
 
    if (nb == 0) 
285
 
      {
286
 
      /* eof */
287
 
      break;
288
 
      }
289
 
    (* hashObj->update) (hashcx, buffer, nb);
290
 
    }
291
 
 
292
 
  (* hashObj->end) (hashcx, digestdata, &len, 32);
293
 
  (* hashObj->destroy) (hashcx, PR_TRUE);
294
 
 
295
 
  digest.data = digestdata;
296
 
  digest.len = len;
297
 
 
298
 
  /* signtool must use any old context it can find since it's
299
 
     calling from inside javaland. */
300
 
 
301
 
#ifdef MOZILLA_CLIENT_OLD
302
 
  mw = XP_FindSomeContext();
303
 
#else
304
 
  mw = NULL;
305
 
#endif
306
 
 
307
 
  PORT_SetError (0);
308
 
 
309
 
  cinfo = SEC_PKCS7CreateSignedData 
310
 
             (cert, certUsageObjectSigner, NULL, 
311
 
                SEC_OID_SHA1, &digest, NULL, (void *) mw);
312
 
 
313
 
  if (cinfo == NULL)
314
 
    return JAR_ERR_PK7;
315
 
 
316
 
  rv = SEC_PKCS7IncludeCertChain (cinfo, NULL);
317
 
  if (rv != SECSuccess) 
318
 
    {
319
 
    status = PORT_GetError();
 
196
{
 
197
    JAR_FWRITE ((JAR_FILE) arg, buf, len);
 
198
}
 
199
 
 
200
int 
 
201
jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert, 
 
202
               char *password, JAR_FILE infp, JAR_FILE outfp)
 
203
{
 
204
    SEC_PKCS7ContentInfo *cinfo;
 
205
    const SECHashObject *hashObj;
 
206
    char *errstring;
 
207
    void *mw = NULL;
 
208
    void *hashcx;
 
209
    unsigned int len;
 
210
    int status = 0;
 
211
    SECStatus rv;
 
212
    SECItem digest;
 
213
    unsigned char digestdata[32];
 
214
    unsigned char buffer[4096];
 
215
 
 
216
    if (outfp == NULL || infp == NULL || cert == NULL)
 
217
        return JAR_ERR_GENERAL;
 
218
 
 
219
    /* we sign with SHA */
 
220
    hashObj = HASH_GetHashObject(HASH_AlgSHA1);
 
221
 
 
222
    hashcx = (* hashObj->create)();
 
223
    if (hashcx == NULL)
 
224
        return JAR_ERR_GENERAL;
 
225
 
 
226
    (* hashObj->begin)(hashcx);
 
227
    while (1) {
 
228
        int nb = JAR_FREAD(infp, buffer, sizeof buffer);
 
229
        if (nb == 0) { /* eof */
 
230
            break;
 
231
        }
 
232
        (* hashObj->update) (hashcx, buffer, nb);
 
233
    }
 
234
    (* hashObj->end)(hashcx, digestdata, &len, 32);
 
235
    (* hashObj->destroy)(hashcx, PR_TRUE);
 
236
 
 
237
    digest.data = digestdata;
 
238
    digest.len = len;
 
239
 
 
240
    /* signtool must use any old context it can find since it's
 
241
         calling from inside javaland. */
 
242
    PORT_SetError (0);
 
243
    cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL,
 
244
                                      SEC_OID_SHA1, &digest, NULL, mw);
 
245
    if (cinfo == NULL)
 
246
        return JAR_ERR_PK7;
 
247
 
 
248
    rv = SEC_PKCS7IncludeCertChain(cinfo, NULL);
 
249
    if (rv != SECSuccess) {
 
250
        status = PORT_GetError();
 
251
        SEC_PKCS7DestroyContentInfo(cinfo);
 
252
        return status;
 
253
    }
 
254
 
 
255
    /* Having this here forces signtool to always include signing time. */
 
256
    rv = SEC_PKCS7AddSigningTime(cinfo);
 
257
    /* don't check error */
 
258
    PORT_SetError(0);
 
259
 
 
260
    /* if calling from mozilla thread*/
 
261
    rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw);
 
262
    if (rv != SECSuccess)
 
263
        status = PORT_GetError();
320
264
    SEC_PKCS7DestroyContentInfo (cinfo);
321
 
    return status;
322
 
    }
323
 
 
324
 
  /* Having this here forces signtool to always include
325
 
     signing time. */
326
 
 
327
 
  rv = SEC_PKCS7AddSigningTime (cinfo);
328
 
  if (rv != SECSuccess)
329
 
    {
330
 
    /* don't check error */
331
 
    }
332
 
 
333
 
  PORT_SetError (0);
334
 
 
335
 
  /* if calling from mozilla thread*/
336
 
  rv = SEC_PKCS7Encode 
337
 
             (cinfo, jar_pk7_out, outfp, 
338
 
                 NULL,  /* pwfn */ NULL,  /* pwarg */ (void *) mw);
339
 
 
340
 
  if (rv != SECSuccess)
341
 
    status = PORT_GetError();
342
 
 
343
 
  SEC_PKCS7DestroyContentInfo (cinfo);
344
 
 
345
 
  if (rv != SECSuccess)
346
 
    {
347
 
    errstring = JAR_get_error (status);
348
 
    /*XP_TRACE (("Jar signing failed (reason %d = %s)", status, errstring));*/
349
 
    return status < 0 ? status : JAR_ERR_GENERAL;
350
 
    }
351
 
 
352
 
  return 0;
353
 
  }
 
265
    if (rv != SECSuccess) {
 
266
        errstring = JAR_get_error (status);
 
267
        return ((status < 0) ? status : JAR_ERR_GENERAL);
 
268
    }
 
269
    return 0;
 
270
}