Back to index

lightning-sunbird  0.9+nobinonly
jar.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifndef __JAR_h_
00038 #define __JAR_h_
00039 
00040 /*
00041  *  In general, any functions that return pointers
00042  *  have memory owned by the caller.
00043  *
00044  */
00045 
00046 /* security includes */
00047 #include "cert.h"
00048 #include "hasht.h"
00049 
00050 /* nspr 2.0 includes */
00051 #include "prio.h"
00052 
00053 #ifndef ZHUGEP
00054 #ifdef XP_WIN16
00055 #define ZHUGEP __huge
00056 #else
00057 #define ZHUGEP
00058 #endif
00059 #endif
00060 
00061 #include <stdio.h>
00062 
00063 /* various types */
00064 
00065 typedef enum
00066   {
00067   jarTypeMF = 2,
00068   jarTypeSF = 3,
00069   jarTypeMeta = 6,
00070   jarTypePhy = 7,
00071   jarTypeSign = 10,
00072   jarTypeSect = 11,
00073   jarTypeOwner = 13
00074   }
00075 jarType;
00076 
00077 /* void data in ZZList's contain JAR_Item type */
00078 
00079 typedef struct JAR_Item_
00080   {
00081   char *pathname;        /* relative. inside zip file */
00082   jarType type;          /* various types */
00083   size_t size;           /* size of data below */
00084   void *data;            /* totally opaque */
00085   }
00086 JAR_Item;
00087 
00088 
00089 /* hashes */
00090 
00091 typedef enum
00092   {
00093   jarHashNone = 0,
00094   jarHashBad = 1,
00095   jarHashPresent = 2
00096   }
00097 jarHash;
00098 
00099 typedef struct JAR_Digest_
00100   {
00101   jarHash md5_status;
00102   unsigned char md5 [MD5_LENGTH];
00103   jarHash sha1_status;
00104   unsigned char sha1 [SHA1_LENGTH];
00105   }
00106 JAR_Digest;
00107 
00108 
00109 /* physical archive formats */
00110 
00111 typedef enum
00112   {
00113   jarArchGuess = 0,
00114   jarArchNone = 1,
00115   jarArchZip = 2,
00116   jarArchTar = 3
00117   }
00118 jarArch;
00119 
00120 
00121 #include "jar-ds.h"
00122 
00123 /* jar object */
00124 
00125 typedef struct JAR_
00126   {
00127   jarArch format;       /* physical archive format */ 
00128   char *url;            /* Where it came from */
00129   char *filename;       /* Disk location */
00130   FILE *fp;             /* For multiple extractions */    /* JAR_FILE */
00131 
00132   /* various linked lists */
00133 
00134   ZZList *manifest;     /* Digests of MF sections */
00135   ZZList *hashes;       /* Digests of actual signed files */
00136   ZZList *phy;          /* Physical layout of JAR file */
00137   ZZList *metainfo;     /* Global metainfo */
00138 
00139   JAR_Digest *globalmeta;  /* digest of .MF global portion */
00140 
00141   /* Below will change to a linked list to support multiple sigs */
00142 
00143   int pkcs7;            /* Enforced opaqueness */
00144   int valid;            /* PKCS7 signature validated */
00145 
00146   ZZList *signers;      /* the above, per signer */
00147 
00148   /* Window context, very necessary for PKCS11 now */
00149 
00150   void *mw;             /* MWContext window context */
00151 
00152   /* Signal callback function */
00153 
00154   int (*signal) (int status, struct JAR_ *jar, 
00155      const char *metafile, char *pathname, char *errorstring);
00156   }
00157 JAR;
00158 
00159 
00160 /*
00161  *  Iterator
00162  *
00163  *  Context for iterative operations. Certain operations
00164  *  require iterating multiple linked lists because of
00165  *  multiple signers. "nextsign" is used for this purpose.
00166  *
00167  */
00168 
00169 typedef struct JAR_Context_
00170   {
00171   JAR *jar;             /* Jar we are searching */
00172   char *pattern;        /* Regular expression */
00173   jarType finding;      /* Type of item to find */
00174   ZZLink *next;         /* Next item in find */
00175   ZZLink *nextsign;     /* Next signer, sometimes */
00176   }
00177 JAR_Context;
00178 
00179 typedef struct JAR_Signer_
00180   {
00181   int pkcs7;            /* Enforced opaqueness */
00182   int valid;            /* PKCS7 signature validated */
00183   char *owner;          /* name of .RSA file */
00184   JAR_Digest *digest;   /* of .SF file */
00185   ZZList *sf;           /* Linked list of .SF file contents */
00186   ZZList *certs;        /* Signing information */
00187   }
00188 JAR_Signer;
00189 
00190 
00191 /* Meta informaton, or "policy", from the manifest file.
00192    Right now just one tuple per JAR_Item. */
00193 
00194 typedef struct JAR_Metainfo_
00195   {
00196   char *header;
00197   char *info;
00198   }
00199 JAR_Metainfo;
00200 
00201 /* This should not be global */
00202 
00203 typedef struct JAR_Physical_
00204   {
00205   unsigned char compression;
00206   unsigned long offset;
00207   unsigned long length;
00208   unsigned long uncompressed_length;
00209 #if defined(XP_UNIX) || defined(XP_BEOS)
00210   uint16 mode;
00211 #endif
00212   }
00213 JAR_Physical;
00214 
00215 typedef struct JAR_Cert_
00216   {
00217   size_t length;
00218   void *key;
00219   CERTCertificate *cert;
00220   }
00221 JAR_Cert;
00222 
00223 
00224 /* certificate stuff */
00225 
00226 typedef enum
00227   {
00228   jarCertCompany = 1,
00229   jarCertCA = 2,
00230   jarCertSerial = 3,
00231   jarCertExpires = 4,
00232   jarCertNickname = 5,
00233   jarCertFinger = 6,
00234   jarCertJavaHack = 100
00235   }
00236 jarCert;
00237 
00238 /* callback types */
00239 
00240 #define JAR_CB_SIGNAL       1
00241 
00242 
00243 /* 
00244  *  This is the base for the JAR error codes. It will
00245  *  change when these are incorporated into allxpstr.c,
00246  *  but right now they won't let me put them there.
00247  *
00248  */
00249 
00250 #ifndef SEC_ERR_BASE
00251 #define SEC_ERR_BASE        (-0x2000)
00252 #endif
00253  
00254 #define JAR_BASE            SEC_ERR_BASE + 300
00255 
00256 /* Jar specific error definitions */
00257 
00258 #define JAR_ERR_GENERAL         (JAR_BASE + 1)
00259 #define JAR_ERR_FNF         (JAR_BASE + 2)
00260 #define JAR_ERR_CORRUPT            (JAR_BASE + 3)
00261 #define JAR_ERR_MEMORY             (JAR_BASE + 4)
00262 #define JAR_ERR_DISK        (JAR_BASE + 5)
00263 #define JAR_ERR_ORDER           (JAR_BASE + 6)
00264 #define JAR_ERR_SIG         (JAR_BASE + 7)
00265 #define JAR_ERR_METADATA        (JAR_BASE + 8)
00266 #define JAR_ERR_ENTRY              (JAR_BASE + 9)
00267 #define JAR_ERR_HASH        (JAR_BASE + 10)
00268 #define JAR_ERR_PK7         (JAR_BASE + 11)
00269 #define JAR_ERR_PNF         (JAR_BASE + 12)
00270 
00271 
00272 /*
00273  *  Birth and death 
00274  *
00275  */
00276 
00277 extern JAR *JAR_new (void);
00278 
00279 extern void PR_CALLBACK JAR_destroy (JAR *jar);
00280 
00281 extern char *JAR_get_error (int status);
00282 
00283 extern int JAR_set_callback (int type, JAR *jar, 
00284   int (*fn) (int status, JAR *jar, 
00285   const char *metafile, char *pathname, char *errortext));
00286 
00287 extern void JAR_init_callbacks
00288   ( char *(*string_cb)(int), void *(*find_cx)(void), void *(*init_cx)(void) );
00289 
00290 /*
00291  *  JAR_set_context
00292  *
00293  *  PKCS11 may require a password to be entered by the user
00294  *  before any crypto routines may be called. This will require
00295  *  a window context if used from inside Mozilla.
00296  *
00297  *  Call this routine with your context before calling 
00298  *  verifying or signing. If you have no context, call with NULL
00299  *  and one will be chosen for you.
00300  *
00301  */
00302 
00303 int JAR_set_context (JAR *jar, void /*MWContext*/ *mw);
00304 
00305 /*
00306  *  Iterative operations
00307  *
00308  *  JAR_find sets up for repeated calls with JAR_find_next.
00309  *  I never liked findfirst and findnext, this is nicer.
00310  *
00311  *  Pattern contains a relative pathname to match inside the
00312  *  archive. It is currently assumed to be "*".
00313  *
00314  *  To use:
00315  *
00316  *     JAR_Item *item;
00317  *     JAR_find (jar, "*.class", jarTypeMF);
00318  *     while (JAR_find_next (jar, &item) >= 0) 
00319  *       { do stuff }
00320  *
00321  */
00322 
00323 
00324 /* Replacement functions with an external context */
00325 
00326 extern JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type);
00327 
00328 extern int JAR_find_next (JAR_Context *ctx, JAR_Item **it);
00329 
00330 extern void JAR_find_end (JAR_Context *ctx);
00331 
00332 
00333 /*
00334  *  Function to parse manifest file:
00335  *
00336  *  Many signatures may be attached to a single filename located
00337  *  inside the zip file. We only support one.
00338  *
00339  *  Several manifests may be included in the zip file. 
00340  *
00341  *  You must pass the MANIFEST.MF file before any .SF files.
00342  *
00343  *  Right now this returns a big ole list, privately in the jar structure.
00344  *  If you need to traverse it, use JAR_find if possible.
00345  *
00346  *  The path is needed to determine what type of binary signature is
00347  *  being passed, though it is technically not needed for manifest files.
00348  *
00349  *  When parsing an ASCII file, null terminate the ASCII raw_manifest
00350  *  prior to sending it, and indicate a length of 0. For binary digital
00351  *  signatures only, indicate the true length of the signature.
00352  *  (This is legacy behavior.)
00353  *
00354  *  You may free the manifest after parsing it.
00355  *
00356  */
00357 
00358 extern int JAR_parse_manifest 
00359     (JAR *jar, char ZHUGEP *raw_manifest, 
00360        long length, const char *path, const char *url);
00361 
00362 /*
00363  *  Verify data (nonstreaming). The signature is actually
00364  *  checked by JAR_parse_manifest or JAR_pass_archive.
00365  *
00366  */
00367 
00368 extern JAR_Digest * PR_CALLBACK JAR_calculate_digest 
00369     (void ZHUGEP *data, long length);
00370 
00371 extern int PR_CALLBACK JAR_verify_digest
00372     (JAR *jar, const char *name, JAR_Digest *dig);
00373 
00374 extern int JAR_digest_file (char *filename, JAR_Digest *dig);
00375 
00376 /*
00377  *  Get attribute from certificate:
00378  *
00379  *  Returns any special signed attribute associated with this cert
00380  *  or signature (passed in "data"). Attributes jarCert*. Most of the time
00381  *  this will return a zero terminated string.
00382  *
00383  */
00384 
00385 extern int PR_CALLBACK JAR_cert_attribute
00386     (JAR *jar, jarCert attrib, long keylen, void *key, 
00387        void **result, unsigned long *length);
00388 
00389 /*
00390  *  Meta information
00391  *
00392  *  Currently, since this call does not support passing of an owner
00393  *  (certificate, or physical name of the .sf file), it is restricted to
00394  *  returning information located in the manifest.mf file. 
00395  *
00396  *  Meta information is a name/value pair inside the archive file. Here,
00397  *  the name is passed in *header and value returned in **info.
00398  *
00399  *  Pass a NULL as the name to retrieve metainfo from the global section.
00400  *
00401  *  Data is returned in **info, of size *length. The return value
00402  *  will indicate if no data was found.
00403  *
00404  */
00405 
00406 extern int JAR_get_metainfo
00407     (JAR *jar, char *name, char *header, void **info, unsigned long *length);
00408 
00409 extern char *JAR_get_filename (JAR *jar);
00410 
00411 extern char *JAR_get_url (JAR *jar);
00412 
00413 /*
00414  *  Return an HTML mockup of a certificate or signature.
00415  *
00416  *  Returns a zero terminated ascii string
00417  *  in raw HTML format.
00418  *
00419  */
00420 
00421 extern char *JAR_cert_html
00422     (JAR *jar, int style, long keylen, void *key, int *result);
00423 
00424 /* save the certificate with this fingerprint in persistent
00425    storage, somewhere, for retrieval in a future session when there 
00426    is no corresponding JAR structure. */
00427 
00428 extern int PR_CALLBACK JAR_stash_cert
00429         (JAR *jar, long keylen, void *key);
00430 
00431 /* retrieve a certificate presumably stashed with the above
00432    function, but may be any certificate. Type is &CERTCertificate */
00433 
00434 void *JAR_fetch_cert (long length, void *key);
00435 
00436 /*
00437  *  New functions to handle archives alone
00438  *    (call JAR_new beforehand)
00439  *
00440  *  JAR_pass_archive acts much like parse_manifest. Certificates
00441  *  are returned in the JAR structure but as opaque data. When calling 
00442  *  JAR_verified_extract you still need to decide which of these 
00443  *  certificates to honor. 
00444  *
00445  *  Code to examine a JAR structure is in jarbert.c. You can obtain both 
00446  *  a list of filenames and certificates from traversing the linked list.
00447  *
00448  */
00449 
00450 extern int JAR_pass_archive
00451     (JAR *jar, jarArch format, char *filename, const char *url);
00452 
00453 /*
00454  * Same thing, but don't check signatures
00455  */
00456 extern int JAR_pass_archive_unverified
00457     (JAR *jar, jarArch format, char *filename, const char *url);
00458 
00459 /*
00460  *  Extracts a relative pathname from the archive and places it
00461  *  in the filename specified. 
00462  * 
00463  *  Call JAR_set_nailed if you want to keep the file descriptors
00464  *  open between multiple calls to JAR_verify_extract.
00465  *
00466  */
00467 
00468 extern int JAR_verified_extract
00469     (JAR *jar, char *path, char *outpath);
00470 
00471 /*
00472  *  JAR_extract does no crypto checking. This can be used if you
00473  *  need to extract a manifest file or signature, etc.
00474  *
00475  */
00476 
00477 extern int JAR_extract
00478     (JAR *jar, char *path, char *outpath);
00479 
00480 
00481 #endif /* __JAR_h_ */