Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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/. */
5 #ifndef __JAR_h_
6 #define __JAR_h_
8 /*
9 * In general, any functions that return pointers
10 * have memory owned by the caller.
11 *
12 */
14 /* security includes */
15 #include "cert.h"
16 #include "hasht.h"
18 /* nspr 2.0 includes */
19 #include "prio.h"
21 #define ZHUGEP
23 #include <stdio.h>
25 /* various types */
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;
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;
45 /* hashes */
46 typedef enum {
47 jarHashNone = 0,
48 jarHashBad = 1,
49 jarHashPresent = 2
50 } jarHash;
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;
59 /* physical archive formats */
60 typedef enum {
61 jarArchGuess = 0,
62 jarArchNone = 1,
63 jarArchZip = 2,
64 jarArchTar = 3
65 } jarArch;
67 #include "jar-ds.h"
69 struct JAR_;
71 typedef int jar_settable_callback_fn(int status, struct JAR_ *jar,
72 const char *metafile, char *pathname,
73 char *errortext);
75 /* jar object */
76 typedef struct JAR_ {
77 jarArch format; /* physical archive format */
79 char *url; /* Where it came from */
80 char *filename; /* Disk location */
81 FILE *fp; /* For multiple extractions */
82 /* JAR_FILE */
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 */
90 JAR_Digest *globalmeta; /* digest of .MF global portion */
92 /* Below will change to a linked list to support multiple sigs */
93 int pkcs7; /* Enforced opaqueness */
94 int valid; /* PKCS7 signature validated */
96 ZZList *signers; /* the above, per signer */
98 /* Window context, very necessary for PKCS11 now */
99 void *mw; /* MWContext window context */
101 /* Signal callback function */
102 jar_settable_callback_fn *signal;
103 } JAR;
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;
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;
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;
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;
148 typedef struct JAR_Cert_ {
149 size_t length;
150 void *key;
151 CERTCertificate *cert;
152 } JAR_Cert;
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;
166 /* callback types */
167 #define JAR_CB_SIGNAL 1
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
179 #define JAR_BASE SEC_ERR_BASE + 300
181 /* Jar specific error definitions */
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)
196 /* Function declarations */
198 extern JAR *JAR_new (void);
200 extern void PR_CALLBACK JAR_destroy (JAR *jar);
202 extern char *JAR_get_error (int status);
204 extern int JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn);
206 extern void
207 JAR_init_callbacks(char *(*string_cb)(int),
208 void *(*find_cx)(void),
209 void *(*init_cx)(void) );
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);
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 */
243 /* Replacement functions with an external context */
245 extern JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type);
247 extern int JAR_find_next (JAR_Context *ctx, JAR_Item **it);
249 extern void JAR_find_end (JAR_Context *ctx);
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 */
276 extern int
277 JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path,
278 const char *url);
280 /*
281 * Verify data (nonstreaming). The signature is actually
282 * checked by JAR_parse_manifest or JAR_pass_archive.
283 *
284 */
286 extern JAR_Digest * PR_CALLBACK
287 JAR_calculate_digest(void *data, long length);
289 extern int PR_CALLBACK
290 JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig);
292 extern int
293 JAR_digest_file(char *filename, JAR_Digest *dig);
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 */
312 extern int
313 JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
314 unsigned long *length);
316 extern char *JAR_get_filename (JAR *jar);
318 extern char *JAR_get_url (JAR *jar);
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);
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);
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);
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);
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);
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);
373 #endif /* __JAR_h_ */