1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
14 * The Original Code is the Netscape security libraries.
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.
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.
35 * ***** END LICENSE BLOCK ***** */
40 * Routines used in signing archives.
51 typedef void (*ETVoidPtrFunc
) (void * data
);
53 #ifdef MOZILLA_CLIENT_OLD
55 extern void ET_moz_CallFunction (ETVoidPtrFunc fn
, void *data
);
58 /* extern MWContext *XP_FindSomeContext(void); */
59 extern void *XP_FindSomeContext(void);
63 /* key database wrapper */
65 /* static SECKEYKeyDBHandle *jar_open_key_database (void); */
67 /* CHUNQ is our bite size */
70 #define FILECHUNQ 32768
73 * J A R _ c a l c u l a t e _ d i g e s t
75 * Quick calculation of a digest for
76 * the specified block of memory. Will calculate
77 * for all supported algorithms, now MD5.
79 * This version supports huge pointers for WIN16.
83 JAR_Digest
* PR_CALLBACK
JAR_calculate_digest (void ZHUGEP
*data
, long length
)
88 unsigned int md5_length
, sha1_length
;
91 PK11Context
*sha1
= 0;
93 dig
= (JAR_Digest
*) PORT_ZAlloc (sizeof (JAR_Digest
));
97 /* out of memory allocating digest */
101 #if defined(XP_WIN16)
102 PORT_Assert ( !IsBadHugeReadPtr(data
, length
) );
105 md5
= PK11_CreateDigestContext (SEC_OID_MD5
);
106 sha1
= PK11_CreateDigestContext (SEC_OID_SHA1
);
110 PK11_DigestBegin (md5
);
111 PK11_DigestBegin (sha1
);
117 if (length
> CHUNQ
) chunq
= CHUNQ
;
120 * If the block of data crosses one or more segment
121 * boundaries then only pass the chunk of data in the
124 * This allows the data to be treated as FAR by the
125 * PK11_DigestOp(...) routine.
129 if (OFFSETOF(data
) + chunq
>= 0x10000)
130 chunq
= 0x10000 - OFFSETOF(data
);
133 PK11_DigestOp (md5
, (unsigned char*)data
, chunq
);
134 PK11_DigestOp (sha1
, (unsigned char*)data
, chunq
);
137 data
= ((char ZHUGEP
*) data
+ chunq
);
141 PK11_DigestFinal (md5
, dig
->md5
, &md5_length
, MD5_LENGTH
);
142 PK11_DigestFinal (sha1
, dig
->sha1
, &sha1_length
, SHA1_LENGTH
);
144 PK11_DestroyContext (md5
, PR_TRUE
);
145 PK11_DestroyContext (sha1
, PR_TRUE
);
152 * J A R _ d i g e s t _ f i l e
154 * Calculates the MD5 and SHA1 digests for a file
155 * present on disk, and returns these in JAR_Digest struct.
159 int JAR_digest_file (char *filename
, JAR_Digest
*dig
)
166 PK11Context
*md5
= 0;
167 PK11Context
*sha1
= 0;
169 unsigned int md5_length
, sha1_length
;
171 buf
= (unsigned char *) PORT_ZAlloc (FILECHUNQ
);
175 return JAR_ERR_MEMORY
;
178 if ((fp
= JAR_FOPEN (filename
, "rb")) == 0)
180 /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */
185 md5
= PK11_CreateDigestContext (SEC_OID_MD5
);
186 sha1
= PK11_CreateDigestContext (SEC_OID_SHA1
);
188 if (md5
== NULL
|| sha1
== NULL
)
190 /* can't generate digest contexts */
193 return JAR_ERR_GENERAL
;
196 PK11_DigestBegin (md5
);
197 PK11_DigestBegin (sha1
);
201 if ((num
= JAR_FREAD (fp
, buf
, FILECHUNQ
)) == 0)
204 PK11_DigestOp (md5
, buf
, num
);
205 PK11_DigestOp (sha1
, buf
, num
);
208 PK11_DigestFinal (md5
, dig
->md5
, &md5_length
, MD5_LENGTH
);
209 PK11_DigestFinal (sha1
, dig
->sha1
, &sha1_length
, SHA1_LENGTH
);
211 PK11_DestroyContext (md5
, PR_TRUE
);
212 PK11_DestroyContext (sha1
, PR_TRUE
);
221 * J A R _ o p e n _ k e y _ d a t a b a s e
225 void* jar_open_key_database (void)
230 int jar_close_key_database (void *keydb
)
232 /* We never do close it */
238 * j a r _ c r e a t e _ p k 7
242 static void jar_pk7_out (void *arg
, const char *buf
, unsigned long len
)
244 JAR_FWRITE ((JAR_FILE
) arg
, buf
, len
);
248 (CERTCertDBHandle
*certdb
, void *keydb
,
249 CERTCertificate
*cert
, char *password
, JAR_FILE infp
, JAR_FILE outfp
)
252 unsigned char buffer
[4096], digestdata
[32];
253 const SECHashObject
*hashObj
;
261 SEC_PKCS7ContentInfo
*cinfo
;
264 void /*MWContext*/ *mw
;
266 if (outfp
== NULL
|| infp
== NULL
|| cert
== NULL
)
267 return JAR_ERR_GENERAL
;
269 /* we sign with SHA */
270 hashObj
= HASH_GetHashObject(HASH_AlgSHA1
);
272 hashcx
= (* hashObj
->create
)();
274 return JAR_ERR_GENERAL
;
276 (* hashObj
->begin
)(hashcx
);
280 /* nspr2.0 doesn't support feof
281 if (feof (infp)) break; */
283 nb
= JAR_FREAD (infp
, buffer
, sizeof (buffer
));
289 (* hashObj
->update
) (hashcx
, buffer
, nb
);
292 (* hashObj
->end
) (hashcx
, digestdata
, &len
, 32);
293 (* hashObj
->destroy
) (hashcx
, PR_TRUE
);
295 digest
.data
= digestdata
;
298 /* signtool must use any old context it can find since it's
299 calling from inside javaland. */
301 #ifdef MOZILLA_CLIENT_OLD
302 mw
= XP_FindSomeContext();
309 cinfo
= SEC_PKCS7CreateSignedData
310 (cert
, certUsageObjectSigner
, NULL
,
311 SEC_OID_SHA1
, &digest
, NULL
, (void *) mw
);
316 rv
= SEC_PKCS7IncludeCertChain (cinfo
, NULL
);
317 if (rv
!= SECSuccess
)
319 status
= PORT_GetError();
320 SEC_PKCS7DestroyContentInfo (cinfo
);
324 /* Having this here forces signtool to always include
327 rv
= SEC_PKCS7AddSigningTime (cinfo
);
328 if (rv
!= SECSuccess
)
330 /* don't check error */
335 /* if calling from mozilla thread*/
337 (cinfo
, jar_pk7_out
, outfp
,
338 NULL
, /* pwfn */ NULL
, /* pwarg */ (void *) mw
);
340 if (rv
!= SECSuccess
)
341 status
= PORT_GetError();
343 SEC_PKCS7DestroyContentInfo (cinfo
);
345 if (rv
!= SECSuccess
)
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
;