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 /* certificate stuff */
155 typedef enum {
156     jarCertCompany = 1,
157     jarCertCA = 2,
158     jarCertSerial = 3,
159     jarCertExpires = 4,
160     jarCertNickname = 5,
161     jarCertFinger = 6,
162     jarCertJavaHack = 100
163 } jarCert;
164 
165 /* callback types */
166 #define JAR_CB_SIGNAL 1
167 
168 /*
169  *  This is the base for the JAR error codes. It will
170  *  change when these are incorporated into allxpstr.c,
171  *  but right now they won't let me put them there.
172  *
173  */
174 #ifndef SEC_ERR_BASE
175 #define SEC_ERR_BASE (-0x2000)
176 #endif
177 
178 #define JAR_BASE SEC_ERR_BASE + 300
179 
180 /* Jar specific error definitions */
181 
182 #define JAR_ERR_GENERAL (JAR_BASE + 1)
183 #define JAR_ERR_FNF (JAR_BASE + 2)
184 #define JAR_ERR_CORRUPT (JAR_BASE + 3)
185 #define JAR_ERR_MEMORY (JAR_BASE + 4)
186 #define JAR_ERR_DISK (JAR_BASE + 5)
187 #define JAR_ERR_ORDER (JAR_BASE + 6)
188 #define JAR_ERR_SIG (JAR_BASE + 7)
189 #define JAR_ERR_METADATA (JAR_BASE + 8)
190 #define JAR_ERR_ENTRY (JAR_BASE + 9)
191 #define JAR_ERR_HASH (JAR_BASE + 10)
192 #define JAR_ERR_PK7 (JAR_BASE + 11)
193 #define JAR_ERR_PNF (JAR_BASE + 12)
194 
195 /* Function declarations */
196 
197 extern JAR *JAR_new(void);
198 
199 extern void PR_CALLBACK JAR_destroy(JAR *jar);
200 
201 extern char *JAR_get_error(int status);
202 
203 extern int JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn);
204 
205 extern void
206 JAR_init_callbacks(char *(*string_cb)(int),
207                    void *(*find_cx)(void),
208                    void *(*init_cx)(void));
209 
210 /*
211  *  JAR_set_context
212  *
213  *  PKCS11 may require a password to be entered by the user
214  *  before any crypto routines may be called. This will require
215  *  a window context if used from inside Mozilla.
216  *
217  *  Call this routine with your context before calling
218  *  verifying or signing. If you have no context, call with NULL
219  *  and one will be chosen for you.
220  *
221  */
222 int JAR_set_context(JAR *jar, void /*MWContext*/ *mw);
223 
224 /*
225  *  Iterative operations
226  *
227  *  JAR_find sets up for repeated calls with JAR_find_next.
228  *  I never liked findfirst and findnext, this is nicer.
229  *
230  *  Pattern contains a relative pathname to match inside the
231  *  archive. It is currently assumed to be "*".
232  *
233  *  To use:
234  *
235  *     JAR_Item *item;
236  *     JAR_find (jar, "*.class", jarTypeMF);
237  *     while (JAR_find_next (jar, &item) >= 0)
238  *   { do stuff }
239  *
240  */
241 
242 /* Replacement functions with an external context */
243 
244 extern JAR_Context *JAR_find(JAR *jar, char *pattern, jarType type);
245 
246 extern int JAR_find_next(JAR_Context *ctx, JAR_Item **it);
247 
248 extern void JAR_find_end(JAR_Context *ctx);
249 
250 /*
251  *  Function to parse manifest file:
252  *
253  *  Many signatures may be attached to a single filename located
254  *  inside the zip file. We only support one.
255  *
256  *  Several manifests may be included in the zip file.
257  *
258  *  You must pass the MANIFEST.MF file before any .SF files.
259  *
260  *  Right now this returns a big ole list, privately in the jar structure.
261  *  If you need to traverse it, use JAR_find if possible.
262  *
263  *  The path is needed to determine what type of binary signature is
264  *  being passed, though it is technically not needed for manifest files.
265  *
266  *  When parsing an ASCII file, null terminate the ASCII raw_manifest
267  *  prior to sending it, and indicate a length of 0. For binary digital
268  *  signatures only, indicate the true length of the signature.
269  *  (This is legacy behavior.)
270  *
271  *  You may free the manifest after parsing it.
272  *
273  */
274 
275 extern int
276 JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path,
277                    const char *url);
278 
279 /*
280  *  Verify data (nonstreaming). The signature is actually
281  *  checked by JAR_parse_manifest or JAR_pass_archive.
282  *
283  */
284 
285 extern JAR_Digest *PR_CALLBACK
286 JAR_calculate_digest(void *data, long length);
287 
288 extern int PR_CALLBACK
289 JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig);
290 
291 extern int
292 JAR_digest_file(char *filename, JAR_Digest *dig);
293 
294 /*
295  *  Meta information
296  *
297  *  Currently, since this call does not support passing of an owner
298  *  (certificate, or physical name of the .sf file), it is restricted to
299  *  returning information located in the manifest.mf file.
300  *
301  *  Meta information is a name/value pair inside the archive file. Here,
302  *  the name is passed in *header and value returned in **info.
303  *
304  *  Pass a NULL as the name to retrieve metainfo from the global section.
305  *
306  *  Data is returned in **info, of size *length. The return value
307  *  will indicate if no data was found.
308  *
309  */
310 
311 extern int
312 JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
313                  unsigned long *length);
314 
315 extern char *JAR_get_filename(JAR *jar);
316 
317 extern char *JAR_get_url(JAR *jar);
318 
319 /* save the certificate with this fingerprint in persistent
320    storage, somewhere, for retrieval in a future session when there
321    is no corresponding JAR structure. */
322 extern int PR_CALLBACK
323 JAR_stash_cert(JAR *jar, long keylen, void *key);
324 
325 /* retrieve a certificate presumably stashed with the above
326    function, but may be any certificate. Type is &CERTCertificate */
327 CERTCertificate *
328 JAR_fetch_cert(long length, void *key);
329 
330 /*
331  *  New functions to handle archives alone
332  *    (call JAR_new beforehand)
333  *
334  *  JAR_pass_archive acts much like parse_manifest. Certificates
335  *  are returned in the JAR structure but as opaque data. When calling
336  *  JAR_verified_extract you still need to decide which of these
337  *  certificates to honor.
338  *
339  *  Code to examine a JAR structure is in jarbert.c. You can obtain both
340  *  a list of filenames and certificates from traversing the linked list.
341  *
342  */
343 extern int
344 JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url);
345 
346 /*
347  * Same thing, but don't check signatures
348  */
349 extern int
350 JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
351                             const char *url);
352 
353 /*
354  *  Extracts a relative pathname from the archive and places it
355  *  in the filename specified.
356  *
357  *  Call JAR_set_nailed if you want to keep the file descriptors
358  *  open between multiple calls to JAR_verify_extract.
359  *
360  */
361 extern int
362 JAR_verified_extract(JAR *jar, char *path, char *outpath);
363 
364 /*
365  *  JAR_extract does no crypto checking. This can be used if you
366  *  need to extract a manifest file or signature, etc.
367  *
368  */
369 extern int
370 JAR_extract(JAR *jar, char *path, char *outpath);
371 
372 #endif /* __JAR_h_ */
373