|
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 #ifndef __JAR_h_ |
|
6 #define __JAR_h_ |
|
7 |
|
8 /* |
|
9 * In general, any functions that return pointers |
|
10 * have memory owned by the caller. |
|
11 * |
|
12 */ |
|
13 |
|
14 /* security includes */ |
|
15 #include "cert.h" |
|
16 #include "hasht.h" |
|
17 |
|
18 /* nspr 2.0 includes */ |
|
19 #include "prio.h" |
|
20 |
|
21 #define ZHUGEP |
|
22 |
|
23 #include <stdio.h> |
|
24 |
|
25 /* various types */ |
|
26 |
|
27 typedef enum { |
|
28 jarTypeMF = 2, |
|
29 jarTypeSF = 3, |
|
30 jarTypeMeta = 6, |
|
31 jarTypePhy = 7, |
|
32 jarTypeSign = 10, |
|
33 jarTypeSect = 11, |
|
34 jarTypeOwner = 13 |
|
35 } jarType; |
|
36 |
|
37 /* void data in ZZList's contain JAR_Item type */ |
|
38 typedef struct JAR_Item_ { |
|
39 char *pathname; /* relative. inside zip file */ |
|
40 jarType type; /* various types */ |
|
41 size_t size; /* size of data below */ |
|
42 void *data; /* totally opaque */ |
|
43 } JAR_Item; |
|
44 |
|
45 /* hashes */ |
|
46 typedef enum { |
|
47 jarHashNone = 0, |
|
48 jarHashBad = 1, |
|
49 jarHashPresent = 2 |
|
50 } jarHash; |
|
51 |
|
52 typedef struct JAR_Digest_ { |
|
53 jarHash md5_status; |
|
54 unsigned char md5 [MD5_LENGTH]; |
|
55 jarHash sha1_status; |
|
56 unsigned char sha1 [SHA1_LENGTH]; |
|
57 } JAR_Digest; |
|
58 |
|
59 /* physical archive formats */ |
|
60 typedef enum { |
|
61 jarArchGuess = 0, |
|
62 jarArchNone = 1, |
|
63 jarArchZip = 2, |
|
64 jarArchTar = 3 |
|
65 } jarArch; |
|
66 |
|
67 #include "jar-ds.h" |
|
68 |
|
69 struct JAR_; |
|
70 |
|
71 typedef int jar_settable_callback_fn(int status, struct JAR_ *jar, |
|
72 const char *metafile, char *pathname, |
|
73 char *errortext); |
|
74 |
|
75 /* jar object */ |
|
76 typedef struct JAR_ { |
|
77 jarArch format; /* physical archive format */ |
|
78 |
|
79 char *url; /* Where it came from */ |
|
80 char *filename; /* Disk location */ |
|
81 FILE *fp; /* For multiple extractions */ |
|
82 /* JAR_FILE */ |
|
83 |
|
84 /* various linked lists */ |
|
85 ZZList *manifest; /* Digests of MF sections */ |
|
86 ZZList *hashes; /* Digests of actual signed files */ |
|
87 ZZList *phy; /* Physical layout of JAR file */ |
|
88 ZZList *metainfo; /* Global metainfo */ |
|
89 |
|
90 JAR_Digest *globalmeta; /* digest of .MF global portion */ |
|
91 |
|
92 /* Below will change to a linked list to support multiple sigs */ |
|
93 int pkcs7; /* Enforced opaqueness */ |
|
94 int valid; /* PKCS7 signature validated */ |
|
95 |
|
96 ZZList *signers; /* the above, per signer */ |
|
97 |
|
98 /* Window context, very necessary for PKCS11 now */ |
|
99 void *mw; /* MWContext window context */ |
|
100 |
|
101 /* Signal callback function */ |
|
102 jar_settable_callback_fn *signal; |
|
103 } JAR; |
|
104 |
|
105 /* |
|
106 * Iterator |
|
107 * |
|
108 * Context for iterative operations. Certain operations |
|
109 * require iterating multiple linked lists because of |
|
110 * multiple signers. "nextsign" is used for this purpose. |
|
111 * |
|
112 */ |
|
113 typedef struct JAR_Context_ { |
|
114 JAR *jar; /* Jar we are searching */ |
|
115 char *pattern; /* Regular expression */ |
|
116 jarType finding; /* Type of item to find */ |
|
117 ZZLink *next; /* Next item in find */ |
|
118 ZZLink *nextsign; /* Next signer, sometimes */ |
|
119 } JAR_Context; |
|
120 |
|
121 typedef struct JAR_Signer_ { |
|
122 int pkcs7; /* Enforced opaqueness */ |
|
123 int valid; /* PKCS7 signature validated */ |
|
124 char *owner; /* name of .RSA file */ |
|
125 JAR_Digest *digest; /* of .SF file */ |
|
126 ZZList *sf; /* Linked list of .SF file contents */ |
|
127 ZZList *certs; /* Signing information */ |
|
128 } JAR_Signer; |
|
129 |
|
130 /* Meta informaton, or "policy", from the manifest file. |
|
131 Right now just one tuple per JAR_Item. */ |
|
132 typedef struct JAR_Metainfo_ { |
|
133 char *header; |
|
134 char *info; |
|
135 } JAR_Metainfo; |
|
136 |
|
137 /* This should not be global */ |
|
138 typedef struct JAR_Physical_ { |
|
139 unsigned char compression; |
|
140 unsigned long offset; |
|
141 unsigned long length; |
|
142 unsigned long uncompressed_length; |
|
143 #if defined(XP_UNIX) || defined(XP_BEOS) |
|
144 PRUint16 mode; |
|
145 #endif |
|
146 } JAR_Physical; |
|
147 |
|
148 typedef struct JAR_Cert_ { |
|
149 size_t length; |
|
150 void *key; |
|
151 CERTCertificate *cert; |
|
152 } JAR_Cert; |
|
153 |
|
154 |
|
155 /* certificate stuff */ |
|
156 typedef enum { |
|
157 jarCertCompany = 1, |
|
158 jarCertCA = 2, |
|
159 jarCertSerial = 3, |
|
160 jarCertExpires = 4, |
|
161 jarCertNickname = 5, |
|
162 jarCertFinger = 6, |
|
163 jarCertJavaHack = 100 |
|
164 } jarCert; |
|
165 |
|
166 /* callback types */ |
|
167 #define JAR_CB_SIGNAL 1 |
|
168 |
|
169 /* |
|
170 * This is the base for the JAR error codes. It will |
|
171 * change when these are incorporated into allxpstr.c, |
|
172 * but right now they won't let me put them there. |
|
173 * |
|
174 */ |
|
175 #ifndef SEC_ERR_BASE |
|
176 #define SEC_ERR_BASE (-0x2000) |
|
177 #endif |
|
178 |
|
179 #define JAR_BASE SEC_ERR_BASE + 300 |
|
180 |
|
181 /* Jar specific error definitions */ |
|
182 |
|
183 #define JAR_ERR_GENERAL (JAR_BASE + 1) |
|
184 #define JAR_ERR_FNF (JAR_BASE + 2) |
|
185 #define JAR_ERR_CORRUPT (JAR_BASE + 3) |
|
186 #define JAR_ERR_MEMORY (JAR_BASE + 4) |
|
187 #define JAR_ERR_DISK (JAR_BASE + 5) |
|
188 #define JAR_ERR_ORDER (JAR_BASE + 6) |
|
189 #define JAR_ERR_SIG (JAR_BASE + 7) |
|
190 #define JAR_ERR_METADATA (JAR_BASE + 8) |
|
191 #define JAR_ERR_ENTRY (JAR_BASE + 9) |
|
192 #define JAR_ERR_HASH (JAR_BASE + 10) |
|
193 #define JAR_ERR_PK7 (JAR_BASE + 11) |
|
194 #define JAR_ERR_PNF (JAR_BASE + 12) |
|
195 |
|
196 /* Function declarations */ |
|
197 |
|
198 extern JAR *JAR_new (void); |
|
199 |
|
200 extern void PR_CALLBACK JAR_destroy (JAR *jar); |
|
201 |
|
202 extern char *JAR_get_error (int status); |
|
203 |
|
204 extern int JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn); |
|
205 |
|
206 extern void |
|
207 JAR_init_callbacks(char *(*string_cb)(int), |
|
208 void *(*find_cx)(void), |
|
209 void *(*init_cx)(void) ); |
|
210 |
|
211 /* |
|
212 * JAR_set_context |
|
213 * |
|
214 * PKCS11 may require a password to be entered by the user |
|
215 * before any crypto routines may be called. This will require |
|
216 * a window context if used from inside Mozilla. |
|
217 * |
|
218 * Call this routine with your context before calling |
|
219 * verifying or signing. If you have no context, call with NULL |
|
220 * and one will be chosen for you. |
|
221 * |
|
222 */ |
|
223 int JAR_set_context (JAR *jar, void /*MWContext*/ *mw); |
|
224 |
|
225 /* |
|
226 * Iterative operations |
|
227 * |
|
228 * JAR_find sets up for repeated calls with JAR_find_next. |
|
229 * I never liked findfirst and findnext, this is nicer. |
|
230 * |
|
231 * Pattern contains a relative pathname to match inside the |
|
232 * archive. It is currently assumed to be "*". |
|
233 * |
|
234 * To use: |
|
235 * |
|
236 * JAR_Item *item; |
|
237 * JAR_find (jar, "*.class", jarTypeMF); |
|
238 * while (JAR_find_next (jar, &item) >= 0) |
|
239 * { do stuff } |
|
240 * |
|
241 */ |
|
242 |
|
243 /* Replacement functions with an external context */ |
|
244 |
|
245 extern JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type); |
|
246 |
|
247 extern int JAR_find_next (JAR_Context *ctx, JAR_Item **it); |
|
248 |
|
249 extern void JAR_find_end (JAR_Context *ctx); |
|
250 |
|
251 /* |
|
252 * Function to parse manifest file: |
|
253 * |
|
254 * Many signatures may be attached to a single filename located |
|
255 * inside the zip file. We only support one. |
|
256 * |
|
257 * Several manifests may be included in the zip file. |
|
258 * |
|
259 * You must pass the MANIFEST.MF file before any .SF files. |
|
260 * |
|
261 * Right now this returns a big ole list, privately in the jar structure. |
|
262 * If you need to traverse it, use JAR_find if possible. |
|
263 * |
|
264 * The path is needed to determine what type of binary signature is |
|
265 * being passed, though it is technically not needed for manifest files. |
|
266 * |
|
267 * When parsing an ASCII file, null terminate the ASCII raw_manifest |
|
268 * prior to sending it, and indicate a length of 0. For binary digital |
|
269 * signatures only, indicate the true length of the signature. |
|
270 * (This is legacy behavior.) |
|
271 * |
|
272 * You may free the manifest after parsing it. |
|
273 * |
|
274 */ |
|
275 |
|
276 extern int |
|
277 JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path, |
|
278 const char *url); |
|
279 |
|
280 /* |
|
281 * Verify data (nonstreaming). The signature is actually |
|
282 * checked by JAR_parse_manifest or JAR_pass_archive. |
|
283 * |
|
284 */ |
|
285 |
|
286 extern JAR_Digest * PR_CALLBACK |
|
287 JAR_calculate_digest(void *data, long length); |
|
288 |
|
289 extern int PR_CALLBACK |
|
290 JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig); |
|
291 |
|
292 extern int |
|
293 JAR_digest_file(char *filename, JAR_Digest *dig); |
|
294 |
|
295 /* |
|
296 * Meta information |
|
297 * |
|
298 * Currently, since this call does not support passing of an owner |
|
299 * (certificate, or physical name of the .sf file), it is restricted to |
|
300 * returning information located in the manifest.mf file. |
|
301 * |
|
302 * Meta information is a name/value pair inside the archive file. Here, |
|
303 * the name is passed in *header and value returned in **info. |
|
304 * |
|
305 * Pass a NULL as the name to retrieve metainfo from the global section. |
|
306 * |
|
307 * Data is returned in **info, of size *length. The return value |
|
308 * will indicate if no data was found. |
|
309 * |
|
310 */ |
|
311 |
|
312 extern int |
|
313 JAR_get_metainfo(JAR *jar, char *name, char *header, void **info, |
|
314 unsigned long *length); |
|
315 |
|
316 extern char *JAR_get_filename (JAR *jar); |
|
317 |
|
318 extern char *JAR_get_url (JAR *jar); |
|
319 |
|
320 /* save the certificate with this fingerprint in persistent |
|
321 storage, somewhere, for retrieval in a future session when there |
|
322 is no corresponding JAR structure. */ |
|
323 extern int PR_CALLBACK |
|
324 JAR_stash_cert(JAR *jar, long keylen, void *key); |
|
325 |
|
326 /* retrieve a certificate presumably stashed with the above |
|
327 function, but may be any certificate. Type is &CERTCertificate */ |
|
328 CERTCertificate * |
|
329 JAR_fetch_cert(long length, void *key); |
|
330 |
|
331 /* |
|
332 * New functions to handle archives alone |
|
333 * (call JAR_new beforehand) |
|
334 * |
|
335 * JAR_pass_archive acts much like parse_manifest. Certificates |
|
336 * are returned in the JAR structure but as opaque data. When calling |
|
337 * JAR_verified_extract you still need to decide which of these |
|
338 * certificates to honor. |
|
339 * |
|
340 * Code to examine a JAR structure is in jarbert.c. You can obtain both |
|
341 * a list of filenames and certificates from traversing the linked list. |
|
342 * |
|
343 */ |
|
344 extern int |
|
345 JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url); |
|
346 |
|
347 /* |
|
348 * Same thing, but don't check signatures |
|
349 */ |
|
350 extern int |
|
351 JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename, |
|
352 const char *url); |
|
353 |
|
354 /* |
|
355 * Extracts a relative pathname from the archive and places it |
|
356 * in the filename specified. |
|
357 * |
|
358 * Call JAR_set_nailed if you want to keep the file descriptors |
|
359 * open between multiple calls to JAR_verify_extract. |
|
360 * |
|
361 */ |
|
362 extern int |
|
363 JAR_verified_extract(JAR *jar, char *path, char *outpath); |
|
364 |
|
365 /* |
|
366 * JAR_extract does no crypto checking. This can be used if you |
|
367 * need to extract a manifest file or signature, etc. |
|
368 * |
|
369 */ |
|
370 extern int |
|
371 JAR_extract(JAR *jar, char *path, char *outpath); |
|
372 |
|
373 #endif /* __JAR_h_ */ |