#ifndef __ZIG_h_
#define __ZIG_h_
/*
* ZIG.H
*
* Support code for Zignature signed
* object specification.
*
* tdell x3565 - 10/29/96
*
*/
/*
* In general, any functions that return pointers
* have memory owned by the caller.
*
*/
/*
* API CHANGES:
*
* parse_manifest new parameter for length. path.
* some void*'s changed to DIGEST*'s.
* new find and find_next functions for iteration.
* functions to get filename and URL from a zig.
* new set_nailed to keep fp open for multiple extracts.
*
* TO DO (in this file only):
*
* Support for multiple signatures (a bug)
* New function SOB_verified_extract equivalent
* except extracting to memory (future feature)
* Make parameter names more relevant and standard
* URL shouldn't be in SOBITEM structure.
* Make comments in this file represent reality.
* Some functions should be private.
*
*/
#include "xp_core.h"
#include "ntypes.h"
#include "sechash.h"
#include "cert.h"
#include "zig-ds.h"
/* #define ZIGBERT */
#ifdef ZIGBERT
/* These are hacky little things to help the cmd tool */
extern XP_File ZIG_XP_FileOpen
(const char* name, XP_FileType type, const XP_FilePerm permissions);
extern ZIG_XP_FileClose (XP_File fp);
extern int ZIG_XP_FileWrite
(const void* source, int32 count, XP_File file);
#define XP_FileOpen ZIG_XP_FileOpen
#define XP_FileClose ZIG_XP_FileClose
#define XP_FileWrite ZIG_XP_FileWrite
#endif
/* pass "token" as a pointer to a ZIG. The ZIG
contains parsed manifest information */
typedef struct ZIG_
{
int format; /* ZIG_F_something */
char *url; /* Where it came from */
char *filename; /* Disk location */
int nailed; /* For multiple extractions */
XP_File fp; /* For multiple extractions */
ZSList *list; /* ZIG linked list */
ZSList *cer; /* Signing information */
ZSList *manifest; /* Digest summary */
void *globalmeta; /* digest of .MF global portion */
/* Context for find, find_next */
char *pattern; /* Regular expression */
int finding; /* Type of item to find */
ZSLink *next; /* Next item in find */
/* Below will change to a linked list to support multiple sigs */
int pkcs7; /* Enforced opaqueness */
int valid; /* PKCS7 signature validated */
char *owner; /* name of .RSA file */
int digest_alg; /* of .SF file */
int digest_length; /* of .SF file */
void *digest; /* of .SF file */
/* Window context, very necessary for PKCS11 now */
int mwset; /* whether a context is set */
MWContext *mw; /* window context */
/* Signal callback function */
int (*signal) (int status, struct ZIG_ *zig,
const char *metafile, char *pathname, char *errorstring);
}
ZIG;
/* void data in ZSList's contain SOBITEM type */
typedef struct SOBITEM_
{
char *pathname; /* relative. inside zip file */
int type; /* cert or sig */
unsigned long size; /* size of data below */
void *data; /* totally opaque */
}
SOBITEM;
/* The length of this structure is unspecified, since
additional digests may be added at any given time.. */
/* This is the length of a hash that has failed */
#define ZIG_BAD_HASH 1
typedef struct DIGESTS_
{
unsigned int md5_length;
unsigned char md5 [16];
unsigned int sha1_length;
unsigned char sha1 [20];
}
DIGESTS;
/* Meta informaton, or "policy", from the manifest file.
Right now just one tuple per SOBITEM. */
typedef struct METAINFO_
{
char *header;
unsigned int length;
unsigned char *info;
}
METAINFO;
/* This should not be global */
typedef struct PHYZIG_
{
char *path;
unsigned char compression;
unsigned long offset;
unsigned long length;
}
PHYZIG;
typedef struct FINGERZIG_
{
unsigned char fingerprint [16];
int length;
void *key;
CERTCertificate *cert;
}
FINGERZIG;
/* for "type" in SOBITEM structure */
#define ZIG_INFO 1 /* from manifest header */
#define ZIG_MF 2 /* manifest hash entry */
#define ZIG_SF 3 /* signature hash entry */
#define ZIG_CERT 4 /* certificate */
#define ZIG_SIG 5 /* digital signature */
#define ZIG_META 6 /* meta info */
#define ZIG_PHY 7 /* physical zip offsets */
#define ZIG_ARCH 8 /* obsolete */
#define ZIG_FP 9 /* cert fingerprint */
#define ZIG_FP2 10 /* signer fingerprint */
#define ZIG_SIGN 10 /* same as FP2 */
#define ZIG_SECT 11 /* sectional mf digest */
#define ZIG_FP3 12 /* cert chain */
#define ZIG_WALK 12 /* same as FP3 */
/* archive formats */
#define ZIG_F_GUESS 0 /* do the right thing */
#define ZIG_F_NONE 1 /* weird */
#define ZIG_F_ZIP 2 /* normal default, ZIP */
#define ZIG_F_TAR 3 /* tar archive, we will support */
/* certificate stuff */
#define ZIG_C_COMPANY 1
#define ZIG_C_CA 2
#define ZIG_C_SERIAL 3
#define ZIG_C_EXPIRES 4
#define ZIG_C_NICKNAME 5
#define ZIG_C_FP 6
#define ZIG_C_JAVA 100
/* callback types */
#define ZIG_CB_SIGNAL 1
/*
* This is the base for the ZIG error codes. It will
* change when these are incorporated into allxpstr.c,
* but right now they won't let me put them there.
*
*/
#ifndef SEC_ERR_BASE
#define SEC_ERR_BASE (-0x2000)
#endif
#define ZIG_BASE SEC_ERR_BASE + 300
/* Jar specific error definitions */
#define ZIG_ERR_GENERAL (ZIG_BASE + 1)
#define ZIG_ERR_FNF (ZIG_BASE + 2)
#define ZIG_ERR_CORRUPT (ZIG_BASE + 3)
#define ZIG_ERR_MEMORY (ZIG_BASE + 4)
#define ZIG_ERR_DISK (ZIG_BASE + 5)
#define ZIG_ERR_ORDER (ZIG_BASE + 6)
#define ZIG_ERR_SIG (ZIG_BASE + 7)
#define ZIG_ERR_METADATA (ZIG_BASE + 8)
#define ZIG_ERR_ENTRY (ZIG_BASE + 9)
#define ZIG_ERR_HASH (ZIG_BASE + 10)
#define ZIG_ERR_PK7 (ZIG_BASE + 11)
#define ZIG_ERR_PNF (ZIG_BASE + 12)
XP_BEGIN_PROTOS
/*
* Birth and death
*
*/
extern ZIG *SOB_new (void);
extern int PR_CALLBACK SOB_destroy (ZIG **zig);
extern char *SOB_get_error (int status);
extern int SOB_set_callback (int type, ZIG *zig,
int (*fn) (int status, ZIG *zig,
const char *metafile, char *pathname, char *errortext));
/*
* SOB_set_context
*
* PKCS11 may require a password to be entered by the user
* before any crypto routines may be called. This will require
* a window context if used from inside Mozilla.
*
* Call this routine with your context before calling
* verifying or signing. If you have no context, call with NULL
* and one will be chosen for you.
*
*/
int SOB_set_context (ZIG *zig, MWContext *mw);
/*
* Iterative operations
*
* SOB_find sets up for repeated calls with SOB_find_next.
* I never liked findfirst and findnext, this is nicer.
*
* Pattern contains a relative pathname to match inside the
* archive. It is currently assumed to be "*".
*
* To use:
*
* SOBITEM *item;
* SOB_find (zig, "*.class", ZIG_MF);
* while (SOB_find_next (zig, &item) >= 0)
* { do stuff }
*
*/
extern int SOB_find (ZIG *zig, char *pattern, int type);
extern int SOB_find_next (ZIG *zig, SOBITEM **it);
/*
* Function to parse manifest file:
*
* Many signatures may be attached to a single filename located
* inside the zip file. We only support one.
*
* Several manifests may be included in the zip file.
*
* You must pass the MANIFEST.MF file before any .SF files.
*
* Right now this returns a big ole list, privately in the zig structure.
* If you need to traverse it, use SOB_find if possible.
*
* The path is needed to determine what type of binary signature is
* being passed, though it is technically not needed for manifest files.
*
* When parsing an ASCII file, null terminate the ASCII raw_manifest
* prior to sending it, and indicate a length of 0. For binary digital
* signatures only, indicate the true length of the signature.
* (This is legacy behavior.)
*
* You may free the manifest after parsing it.
*
*/
extern int SOB_parse_manifest
(char XP_HUGE *raw_manifest, long length,
const char *path, const char *url, ZIG *zig);
/*
* Verify data (nonstreaming). The signature is actually
* checked by SOB_parse_manifest or SOB_pass_archive.
*
*/
extern DIGESTS * PR_CALLBACK SOB_calculate_digest (void XP_HUGE *data, long length);
extern int PR_CALLBACK SOB_verify_digest
(int *result, ZIG *siglist, const char *name, DIGESTS *dig);
extern int SOB_digest_file (char *filename, DIGESTS *dig);
/*
* Get attribute from certificate:
*
* Returns any special signed attribute associated with this cert
* or signature (passed in "data"). Attributes ZIG_C_*. Most of the time
* this will return a zero terminated string.
*
*/
extern int PR_CALLBACK SOB_cert_attribute
(int attrib, ZIG *zig, long keylen, void *key,
void **result, unsigned long *length);
/*
* Meta information
*
* Currently, since this call does not support passing of an owner
* (certificate, or physical name of the .sf file), it is restricted to
* returning information located in the manifest.mf file.
*
* Meta information is a name/value pair inside the archive file. Here,
* the name is passed in *header and value returned in **info.
*
* Pass a NULL as the name to retrieve metainfo from the global section.
*
* Data is returned in **info, of size *length. The return value
* will indicate if no data was found.
*
*/
extern int SOB_get_metainfo
(ZIG *zig, char *name, char *header, void **info, unsigned long *length);
extern char *SOB_get_filename (ZIG *zig);
extern char *SOB_get_url (ZIG *zig);
/*
* Return an HTML mockup of a certificate or signature.
*
* Returns a zero terminated ascii string
* in raw HTML format.
*
*/
extern char *SOB_cert_html
(int style, ZIG *zig, long keylen, void *key, int *result);
/* save the certificate with this fingerprint in persistent
storage, somewhere, for retrieval in a future session when there
is no corresponding ZIG structure. */
extern int PR_CALLBACK SOB_stash_cert
(ZIG *zig, long keylen, void *key);
/* retrieve a certificate presumably stashed with the above
function, but may be any certificate. Type is &CERTCertificate */
void *SOB_fetch_cert (long length, void *key);
/*
* New functions to handle archives alone
* (call SOB_new beforehand)
*
* SOB_pass_archive acts much like parse_manifest. Certificates
* are returned in the ZIG structure but as opaque data. When calling
* SOB_verified_extract you still need to decide which of these
* certificates to honor.
*
* Code to examine a ZIG structure is in zigbert.c. You can obtain both
* a list of filenames and certificates from traversing the linked list.
*
*/
extern int SOB_pass_archive
(int format, char *filename, const char *url, ZIG *zig);
/*
* Extracts a relative pathname from the archive and places it
* in the filename specified.
*
* Call SOB_set_nailed if you want to keep the file descriptors
* open between multiple calls to SOB_verify_extract.
*
*/
extern int SOB_verified_extract
(ZIG *zig, char *path, char *outpath);
extern int SOB_set_nailed (ZIG *zig, int setting);
/*
* SOB_extract does no crypto checking. This can be used if you
* need to extract a manifest file or signature, etc.
*
*/
extern int SOB_extract
(ZIG *zig, char *path, char *outpath);
/*
* SOB_JAR_*
*
* Functions for the Jartool, which is written in Java and
* requires wrappers located elsewhere in Navigator.
*
* Do not call these unless you are the Jartool, no matter
* how convenient they may appear.
*
*/
/* return a list of certificate nicknames, separated by \n's */
extern char *SOB_JAR_list_certs (void);
/* validate archive, simple api */
extern int SOB_JAR_validate_archive (char *filename);
/* begin hash */
extern void *SOB_JAR_new_hash (int alg);
/* hash a streaming pile */
extern void *SOB_JAR_hash (int alg, void *cookie, int length, void *data);
/* end hash */
extern void *SOB_JAR_end_hash (int alg, void *cookie);
/* sign the archive (given an .SF file) with the given cert.
The password argument is a relic, PKCS11 now handles that. */
extern int SOB_JAR_sign_archive
(char *nickname, char *password, char *sf, char *outsig);
/* convert status to text */
extern char *SOB_JAR_get_error (int status);
XP_END_PROTOS
#endif /* __ZIG_h_ */