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