diff options
Diffstat (limited to 'security/nss/lib/jar')
-rw-r--r-- | security/nss/lib/jar/jar-ds.c | 57 | ||||
-rw-r--r-- | security/nss/lib/jar/jar-ds.h | 61 | ||||
-rw-r--r-- | security/nss/lib/jar/jar.c | 1148 | ||||
-rw-r--r-- | security/nss/lib/jar/jar.h | 381 | ||||
-rw-r--r-- | security/nss/lib/jar/jarfile.c | 1611 | ||||
-rw-r--r-- | security/nss/lib/jar/jarfile.h | 123 | ||||
-rw-r--r-- | security/nss/lib/jar/jarint.c | 50 | ||||
-rw-r--r-- | security/nss/lib/jar/jarint.h | 26 | ||||
-rw-r--r-- | security/nss/lib/jar/jarnav.c | 62 | ||||
-rw-r--r-- | security/nss/lib/jar/jarsign.c | 363 | ||||
-rw-r--r-- | security/nss/lib/jar/jarver.c | 2534 |
11 files changed, 2828 insertions, 3588 deletions
diff --git a/security/nss/lib/jar/jar-ds.c b/security/nss/lib/jar/jar-ds.c index e913902a1..bfbc65d1b 100644 --- a/security/nss/lib/jar/jar-ds.c +++ b/security/nss/lib/jar/jar-ds.c @@ -37,37 +37,32 @@ #include "jar.h" /* These are old DS_* routines renamed to ZZ_* */ +ZZList * +ZZ_NewList(void) +{ + ZZList *list = (ZZList *) PORT_ZAlloc (sizeof (ZZList)); + if (list) + ZZ_InitList (list); + return list; +} -ZZList *ZZ_NewList() - { - ZZList *list; +ZZLink * +ZZ_NewLink(JAR_Item *thing) +{ + ZZLink *link = (ZZLink *) PORT_ZAlloc (sizeof (ZZLink)); + if (link) + link->thing = thing; + return link; +} - list = (ZZList *) PORT_ZAlloc (sizeof (ZZList)); +void +ZZ_DestroyLink(ZZLink *link) +{ + PORT_Free(link); +} - if (list) - ZZ_InitList (list); - - return list; - } - -ZZLink *ZZ_NewLink (JAR_Item *thing) - { - ZZLink *link; - - link = (ZZLink *) PORT_ZAlloc (sizeof (ZZLink)); - - if (link) - link->thing = thing; - - return link; - } - -void ZZ_DestroyLink (ZZLink *link) - { - PORT_Free (link); - } - -void ZZ_DestroyList (ZZList *list) - { - PORT_Free (list); - } +void +ZZ_DestroyList (ZZList *list) +{ + PORT_Free(list); +} diff --git a/security/nss/lib/jar/jar-ds.h b/security/nss/lib/jar/jar-ds.h index cfd73f69f..4422ce099 100644 --- a/security/nss/lib/jar/jar-ds.h +++ b/security/nss/lib/jar/jar-ds.h @@ -44,66 +44,67 @@ typedef struct ZZListStr ZZList; /* ** Circular linked list. Each link contains a pointer to the object that ** is actually in the list. -*/ -struct ZZLinkStr -{ +*/ +struct ZZLinkStr { ZZLink *next; ZZLink *prev; JAR_Item *thing; }; -struct ZZListStr -{ +struct ZZListStr { ZZLink link; }; -#define ZZ_InitList(lst) \ -{ \ +#define ZZ_InitList(lst) \ +{ \ (lst)->link.next = &(lst)->link; \ (lst)->link.prev = &(lst)->link; \ - (lst)->link.thing = 0; \ + (lst)->link.thing = 0; \ } -#define ZZ_ListEmpty(lst) \ - ((lst)->link.next == &(lst)->link) +#define ZZ_ListEmpty(lst) ((lst)->link.next == &(lst)->link) -#define ZZ_ListHead(lst) \ - ((lst)->link.next) +#define ZZ_ListHead(lst) ((lst)->link.next) -#define ZZ_ListTail(lst) \ - ((lst)->link.prev) +#define ZZ_ListTail(lst) ((lst)->link.prev) -#define ZZ_ListIterDone(lst,lnk) \ - ((lnk) == &(lst)->link) +#define ZZ_ListIterDone(lst,lnk) ((lnk) == &(lst)->link) #define ZZ_AppendLink(lst,lnk) \ -{ \ - (lnk)->next = &(lst)->link; \ +{ \ + (lnk)->next = &(lst)->link; \ (lnk)->prev = (lst)->link.prev; \ (lst)->link.prev->next = (lnk); \ - (lst)->link.prev = (lnk); \ + (lst)->link.prev = (lnk); \ } #define ZZ_InsertLink(lst,lnk) \ -{ \ +{ \ (lnk)->next = (lst)->link.next; \ - (lnk)->prev = &(lst)->link; \ + (lnk)->prev = &(lst)->link; \ (lst)->link.next->prev = (lnk); \ - (lst)->link.next = (lnk); \ + (lst)->link.next = (lnk); \ } -#define ZZ_RemoveLink(lnk) \ -{ \ +#define ZZ_RemoveLink(lnk) \ +{ \ (lnk)->next->prev = (lnk)->prev; \ (lnk)->prev->next = (lnk)->next; \ - (lnk)->next = 0; \ - (lnk)->prev = 0; \ + (lnk)->next = 0; \ + (lnk)->prev = 0; \ } -extern ZZLink *ZZ_NewLink (JAR_Item *thing); -extern void ZZ_DestroyLink (ZZLink *link); -extern ZZList *ZZ_NewList (void); -extern void ZZ_DestroyList (ZZList *list); +extern ZZLink * +ZZ_NewLink(JAR_Item *thing); + +extern void +ZZ_DestroyLink(ZZLink *link); + +extern ZZList * +ZZ_NewList(void); + +extern void +ZZ_DestroyList(ZZList *list); #endif /* __JAR_DS_h_ */ diff --git a/security/nss/lib/jar/jar.c b/security/nss/lib/jar/jar.c index 6d575a036..182f00a2d 100644 --- a/security/nss/lib/jar/jar.c +++ b/security/nss/lib/jar/jar.c @@ -45,200 +45,164 @@ #include "jar.h" #include "jarint.h" -static void jar_destroy_list (ZZList *list); +static void +jar_destroy_list (ZZList *list); -static int jar_find_first_cert - (JAR_Signer *signer, int type, JAR_Item **it); +static int +jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it); /* - * J A R _ n e w + * J A R _ n e w * * Create a new instantiation of a manifest representation. * Use this as a token to any calls to this API. * */ - -JAR *JAR_new (void) - { - JAR *jar; - - if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL) - goto loser; - - if ((jar->manifest = ZZ_NewList()) == NULL) - goto loser; - - if ((jar->hashes = ZZ_NewList()) == NULL) - goto loser; - - if ((jar->phy = ZZ_NewList()) == NULL) - goto loser; - - if ((jar->metainfo = ZZ_NewList()) == NULL) - goto loser; - - if ((jar->signers = ZZ_NewList()) == NULL) - goto loser; - - return jar; +JAR * +JAR_new(void) +{ + JAR *jar; + + if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL) + goto loser; + if ((jar->manifest = ZZ_NewList()) == NULL) + goto loser; + if ((jar->hashes = ZZ_NewList()) == NULL) + goto loser; + if ((jar->phy = ZZ_NewList()) == NULL) + goto loser; + if ((jar->metainfo = ZZ_NewList()) == NULL) + goto loser; + if ((jar->signers = ZZ_NewList()) == NULL) + goto loser; + return jar; loser: - - if (jar) - { - if (jar->manifest) - ZZ_DestroyList (jar->manifest); - - if (jar->hashes) - ZZ_DestroyList (jar->hashes); - - if (jar->phy) - ZZ_DestroyList (jar->phy); - - if (jar->metainfo) - ZZ_DestroyList (jar->metainfo); - - if (jar->signers) - ZZ_DestroyList (jar->signers); - - PORT_Free (jar); + if (jar) { + if (jar->manifest) + ZZ_DestroyList (jar->manifest); + if (jar->hashes) + ZZ_DestroyList (jar->hashes); + if (jar->phy) + ZZ_DestroyList (jar->phy); + if (jar->metainfo) + ZZ_DestroyList (jar->metainfo); + if (jar->signers) + ZZ_DestroyList (jar->signers); + PORT_Free (jar); } + return NULL; +} - return NULL; - } - -/* +/* * J A R _ d e s t r o y - * - * Godzilla. - * */ - -void PR_CALLBACK JAR_destroy (JAR *jar) - { - PORT_Assert( jar != NULL ); - - if (jar == NULL) - return; - - if (jar->fp) JAR_FCLOSE ((PRFileDesc*)jar->fp); - - if (jar->url) PORT_Free (jar->url); - if (jar->filename) PORT_Free (jar->filename); - - /* Free the linked list elements */ - - jar_destroy_list (jar->manifest); - ZZ_DestroyList (jar->manifest); - - jar_destroy_list (jar->hashes); - ZZ_DestroyList (jar->hashes); - - jar_destroy_list (jar->phy); - ZZ_DestroyList (jar->phy); - - jar_destroy_list (jar->metainfo); - ZZ_DestroyList (jar->metainfo); - - jar_destroy_list (jar->signers); - ZZ_DestroyList (jar->signers); - - PORT_Free (jar); - } - -static void jar_destroy_list (ZZList *list) - { - ZZLink *link, *oldlink; - - JAR_Item *it; - - JAR_Physical *phy; - JAR_Digest *dig; - JAR_Cert *fing; - JAR_Metainfo *met; - JAR_Signer *signer; - - if (list && !ZZ_ListEmpty (list)) - { - link = ZZ_ListHead (list); - - while (!ZZ_ListIterDone (list, link)) - { - it = link->thing; - if (!it) goto next; - - if (it->pathname) PORT_Free (it->pathname); - - switch (it->type) - { - case jarTypeMeta: - - met = (JAR_Metainfo *) it->data; - if (met) - { - if (met->header) PORT_Free (met->header); - if (met->info) PORT_Free (met->info); - PORT_Free (met); - } - break; - - case jarTypePhy: - - phy = (JAR_Physical *) it->data; - if (phy) - PORT_Free (phy); - break; - - case jarTypeSign: - - fing = (JAR_Cert *) it->data; - if (fing) - { - if (fing->cert) - CERT_DestroyCertificate (fing->cert); - if (fing->key) - PORT_Free (fing->key); - PORT_Free (fing); - } - break; - - case jarTypeSect: - case jarTypeMF: - case jarTypeSF: - - dig = (JAR_Digest *) it->data; - if (dig) - { - PORT_Free (dig); - } - break; - - case jarTypeOwner: - - signer = (JAR_Signer *) it->data; - - if (signer) - JAR_destroy_signer (signer); - - break; - - default: - - /* PORT_Assert( 1 != 2 ); */ - break; - } - - PORT_Free (it); - - next: - - oldlink = link; - link = link->next; - - ZZ_DestroyLink (oldlink); - } +void PR_CALLBACK +JAR_destroy(JAR *jar) +{ + PORT_Assert( jar != NULL ); + + if (jar == NULL) + return; + + if (jar->fp) + JAR_FCLOSE ((PRFileDesc*)jar->fp); + if (jar->url) + PORT_Free (jar->url); + if (jar->filename) + PORT_Free (jar->filename); + + /* Free the linked list elements */ + jar_destroy_list (jar->manifest); + ZZ_DestroyList (jar->manifest); + jar_destroy_list (jar->hashes); + ZZ_DestroyList (jar->hashes); + jar_destroy_list (jar->phy); + ZZ_DestroyList (jar->phy); + jar_destroy_list (jar->metainfo); + ZZ_DestroyList (jar->metainfo); + jar_destroy_list (jar->signers); + ZZ_DestroyList (jar->signers); + PORT_Free (jar); +} + +static void +jar_destroy_list(ZZList *list) +{ + ZZLink *link, *oldlink; + JAR_Item *it; + JAR_Physical *phy; + JAR_Digest *dig; + JAR_Cert *fing; + JAR_Metainfo *met; + JAR_Signer *signer; + + if (list && !ZZ_ListEmpty (list)) { + link = ZZ_ListHead (list); + while (!ZZ_ListIterDone (list, link)) { + it = link->thing; + if (!it) + goto next; + if (it->pathname) + PORT_Free (it->pathname); + + switch (it->type) { + case jarTypeMeta: + met = (JAR_Metainfo *) it->data; + if (met) { + if (met->header) + PORT_Free (met->header); + if (met->info) + PORT_Free (met->info); + PORT_Free (met); + } + break; + + case jarTypePhy: + phy = (JAR_Physical *) it->data; + if (phy) + PORT_Free (phy); + break; + + case jarTypeSign: + fing = (JAR_Cert *) it->data; + if (fing) { + if (fing->cert) + CERT_DestroyCertificate (fing->cert); + if (fing->key) + PORT_Free (fing->key); + PORT_Free (fing); + } + break; + + case jarTypeSect: + case jarTypeMF: + case jarTypeSF: + dig = (JAR_Digest *) it->data; + if (dig) { + PORT_Free (dig); + } + break; + + case jarTypeOwner: + signer = (JAR_Signer *) it->data; + if (signer) + JAR_destroy_signer (signer); + break; + + default: + /* PORT_Assert( 1 != 2 ); */ + break; + } + PORT_Free (it); + +next: + oldlink = link; + link = link->next; + ZZ_DestroyLink (oldlink); + } } - } +} /* * J A R _ g e t _ m e t a i n f o @@ -248,52 +212,45 @@ static void jar_destroy_list (ZZList *list) * */ -int JAR_get_metainfo - (JAR *jar, char *name, char *header, void **info, unsigned long *length) - { - JAR_Item *it; - - ZZLink *link; - ZZList *list; - - JAR_Metainfo *met; - - PORT_Assert( jar != NULL && header != NULL ); - - if (jar == NULL || header == NULL) - return JAR_ERR_PNF; - - list = jar->metainfo; - - if (ZZ_ListEmpty (list)) - return JAR_ERR_PNF; - - for (link = ZZ_ListHead (list); - !ZZ_ListIterDone (list, link); - link = link->next) - { - it = link->thing; - if (it->type == jarTypeMeta) - { - if ((name && !it->pathname) || (!name && it->pathname)) - continue; - - if (name && it->pathname && strcmp (it->pathname, name)) - continue; - - met = (JAR_Metainfo *) it->data; - - if (!PORT_Strcasecmp (met->header, header)) - { - *info = PORT_Strdup (met->info); - *length = PORT_Strlen (met->info); - return 0; - } - } +int +JAR_get_metainfo(JAR *jar, char *name, char *header, void **info, + unsigned long *length) +{ + JAR_Item *it; + ZZLink *link; + ZZList *list; + + PORT_Assert( jar != NULL && header != NULL ); + + if (jar == NULL || header == NULL) + return JAR_ERR_PNF; + + list = jar->metainfo; + + if (ZZ_ListEmpty (list)) + return JAR_ERR_PNF; + + for (link = ZZ_ListHead (list); + !ZZ_ListIterDone (list, link); + link = link->next) { + it = link->thing; + if (it->type == jarTypeMeta) { + JAR_Metainfo *met; + + if ((name && !it->pathname) || (!name && it->pathname)) + continue; + if (name && it->pathname && strcmp (it->pathname, name)) + continue; + met = (JAR_Metainfo *) it->data; + if (!PORT_Strcasecmp (met->header, header)) { + *info = PORT_Strdup (met->info); + *length = PORT_Strlen (met->info); + return 0; + } + } } - - return JAR_ERR_PNF; - } + return JAR_ERR_PNF; +} /* * J A R _ f i n d @@ -305,65 +262,65 @@ int JAR_get_metainfo * See jar.h for a description on how to use. * */ - -JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type) - { - JAR_Context *ctx; - - PORT_Assert( jar != NULL ); - - if (!jar) - return NULL; - - ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context)); - - if (ctx == NULL) - return NULL; - - ctx->jar = jar; - - if (pattern) - { - if ((ctx->pattern = PORT_Strdup (pattern)) == NULL) - { - PORT_Free (ctx); - return NULL; - } +JAR_Context * +JAR_find (JAR *jar, char *pattern, jarType type) +{ + JAR_Context *ctx; + + PORT_Assert( jar != NULL ); + + if (!jar) + return NULL; + + ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context)); + if (ctx == NULL) + return NULL; + + ctx->jar = jar; + if (pattern) { + if ((ctx->pattern = PORT_Strdup (pattern)) == NULL) { + PORT_Free (ctx); + return NULL; + } } + ctx->finding = type; - ctx->finding = type; - - switch (type) - { - case jarTypeMF: ctx->next = ZZ_ListHead (jar->hashes); - break; + switch (type) { + case jarTypeMF: + ctx->next = ZZ_ListHead (jar->hashes); + break; case jarTypeSF: - case jarTypeSign: ctx->next = NULL; - ctx->nextsign = ZZ_ListHead (jar->signers); - break; - - case jarTypeSect: ctx->next = ZZ_ListHead (jar->manifest); - break; - - case jarTypePhy: ctx->next = ZZ_ListHead (jar->phy); - break; + case jarTypeSign: + ctx->next = NULL; + ctx->nextsign = ZZ_ListHead (jar->signers); + break; + + case jarTypeSect: + ctx->next = ZZ_ListHead (jar->manifest); + break; + + case jarTypePhy: + ctx->next = ZZ_ListHead (jar->phy); + break; + + case jarTypeOwner: + if (jar->signers) + ctx->next = ZZ_ListHead (jar->signers); + else + ctx->next = NULL; + break; + + case jarTypeMeta: + ctx->next = ZZ_ListHead (jar->metainfo); + break; - case jarTypeOwner: if (jar->signers) - ctx->next = ZZ_ListHead (jar->signers); - else - ctx->next = NULL; - break; - - case jarTypeMeta: ctx->next = ZZ_ListHead (jar->metainfo); - break; - - default: PORT_Assert( 1 != 2); - break; + default: + PORT_Assert( 1 != 2); + break; } - - return ctx; - } + return ctx; +} /* * J A R _ f i n d _ e n d @@ -371,18 +328,16 @@ JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type) * Destroy the find iterator context. * */ - -void JAR_find_end (JAR_Context *ctx) - { - PORT_Assert( ctx != NULL ); - - if (ctx) - { - if (ctx->pattern) - PORT_Free (ctx->pattern); - PORT_Free (ctx); +void +JAR_find_end (JAR_Context *ctx) +{ + PORT_Assert( ctx != NULL ); + if (ctx) { + if (ctx->pattern) + PORT_Free (ctx->pattern); + PORT_Free (ctx); } - } +} /* * J A R _ f i n d _ n e x t @@ -393,281 +348,218 @@ void JAR_find_end (JAR_Context *ctx) */ int JAR_find_next (JAR_Context *ctx, JAR_Item **it) - { - JAR *jar; - ZZList *list = NULL; - - int finding; - - JAR_Signer *signer = NULL; - - PORT_Assert( ctx != NULL ); - PORT_Assert( ctx->jar != NULL ); - - jar = ctx->jar; - - /* Internally, convert jarTypeSign to jarTypeSF, and return - the actual attached certificate later */ - - finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding; - - if (ctx->nextsign) - { - if (ZZ_ListIterDone (jar->signers, ctx->nextsign)) - { - *it = NULL; - return -1; - } - PORT_Assert (ctx->nextsign->thing != NULL); - signer = (JAR_Signer*)ctx->nextsign->thing->data; +{ + JAR *jar; + ZZList *list = NULL; + int finding; + JAR_Signer *signer = NULL; + + PORT_Assert( ctx != NULL ); + PORT_Assert( ctx->jar != NULL ); + + jar = ctx->jar; + + /* Internally, convert jarTypeSign to jarTypeSF, and return + the actual attached certificate later */ + finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding; + if (ctx->nextsign) { + if (ZZ_ListIterDone (jar->signers, ctx->nextsign)) { + *it = NULL; + return -1; + } + PORT_Assert (ctx->nextsign->thing != NULL); + signer = (JAR_Signer*)ctx->nextsign->thing->data; } + /* Find out which linked list to traverse. Then if + necessary, advance to the next linked list. */ + while (1) { + switch (finding) { + case jarTypeSign: /* not any more */ + PORT_Assert( finding != jarTypeSign ); + list = signer->certs; + break; - /* Find out which linked list to traverse. Then if - necessary, advance to the next linked list. */ - - while (1) - { - switch (finding) - { - case jarTypeSign: /* not any more */ - PORT_Assert( finding != jarTypeSign ); - list = signer->certs; - break; - - case jarTypeSect: list = jar->manifest; - break; - - case jarTypePhy: list = jar->phy; - break; - - case jarTypeSF: /* signer, not jar */ - PORT_Assert( signer != NULL ); - list = signer->sf; - break; - - case jarTypeMF: list = jar->hashes; - break; - - case jarTypeOwner: list = jar->signers; - break; - - case jarTypeMeta: list = jar->metainfo; - break; - - default: PORT_Assert( 1 != 2 ); - break; - } - - if (list == NULL) - { - *it = NULL; - return -1; - } - - /* When looping over lists of lists, advance - to the next signer. This is done when multiple - signers are possible. */ - - if (ZZ_ListIterDone (list, ctx->next)) - { - if (ctx->nextsign && jar->signers) - { - ctx->nextsign = ctx->nextsign->next; - if (!ZZ_ListIterDone (jar->signers, ctx->nextsign)) - { - PORT_Assert (ctx->nextsign->thing != NULL); - - signer = (JAR_Signer*)ctx->nextsign->thing->data; - PORT_Assert( signer != NULL ); - - ctx->next = NULL; - continue; - } - } - *it = NULL; - return -1; - } - - /* if the signer changed, still need to fill - in the "next" link */ - - if (ctx->nextsign && ctx->next == NULL) - { - switch (finding) - { - case jarTypeSF: - - ctx->next = ZZ_ListHead (signer->sf); - break; - - case jarTypeSign: - - ctx->next = ZZ_ListHead (signer->certs); - break; - } - } - - PORT_Assert( ctx->next != NULL ); - - - while (!ZZ_ListIterDone (list, ctx->next)) - { - *it = ctx->next->thing; - ctx->next = ctx->next->next; - - if (!*it || (*it)->type != finding) - continue; - - if (ctx->pattern && *ctx->pattern) - { - if (PORT_Strcmp ((*it)->pathname, ctx->pattern)) - continue; - } - - /* We have a valid match. If this is a jarTypeSign - return the certificate instead.. */ - - if (ctx->finding == jarTypeSign) - { - JAR_Item *itt; - - /* just the first one for now */ - if (jar_find_first_cert (signer, jarTypeSign, &itt) >= 0) - { - *it = itt; - return 0; - } - - continue; - } - - return 0; - } + case jarTypeSect: + list = jar->manifest; + break; + case jarTypePhy: + list = jar->phy; + break; + + case jarTypeSF: /* signer, not jar */ + PORT_Assert( signer != NULL ); + list = signer->sf; + break; + + case jarTypeMF: + list = jar->hashes; + break; + + case jarTypeOwner: + list = jar->signers; + break; + + case jarTypeMeta: + list = jar->metainfo; + break; + + default: + PORT_Assert( 1 != 2 ); + break; + } + if (list == NULL) { + *it = NULL; + return -1; + } + /* When looping over lists of lists, advance to the next signer. + This is done when multiple signers are possible. */ + if (ZZ_ListIterDone (list, ctx->next)) { + if (ctx->nextsign && jar->signers) { + ctx->nextsign = ctx->nextsign->next; + if (!ZZ_ListIterDone (jar->signers, ctx->nextsign)) { + PORT_Assert (ctx->nextsign->thing != NULL); + signer = (JAR_Signer*)ctx->nextsign->thing->data; + PORT_Assert( signer != NULL ); + ctx->next = NULL; + continue; + } + } + *it = NULL; + return -1; + } + + /* if the signer changed, still need to fill in the "next" link */ + if (ctx->nextsign && ctx->next == NULL) { + switch (finding) { + case jarTypeSF: + ctx->next = ZZ_ListHead (signer->sf); + break; + + case jarTypeSign: + ctx->next = ZZ_ListHead (signer->certs); + break; + } + } + PORT_Assert( ctx->next != NULL ); + while (!ZZ_ListIterDone (list, ctx->next)) { + *it = ctx->next->thing; + ctx->next = ctx->next->next; + if (!*it || (*it)->type != finding) + continue; + if (ctx->pattern && *ctx->pattern) { + if (PORT_Strcmp ((*it)->pathname, ctx->pattern)) + continue; + } + /* We have a valid match. If this is a jarTypeSign + return the certificate instead.. */ + if (ctx->finding == jarTypeSign) { + JAR_Item *itt; + + /* just the first one for now */ + if (jar_find_first_cert (signer, jarTypeSign, &itt) >= 0) { + *it = itt; + return 0; + } + continue; + } + return 0; + } } /* end while */ - } - -static int jar_find_first_cert - (JAR_Signer *signer, int type, JAR_Item **it) - { - ZZLink *link; - ZZList *list; - - int status = JAR_ERR_PNF; - - list = signer->certs; - - *it = NULL; - - if (ZZ_ListEmpty (list)) - { - /* empty list */ - return JAR_ERR_PNF; +} + +static int +jar_find_first_cert (JAR_Signer *signer, int type, JAR_Item **it) +{ + ZZLink *link; + ZZList *list = signer->certs; + int status = JAR_ERR_PNF; + + *it = NULL; + if (ZZ_ListEmpty (list)) { + /* empty list */ + return JAR_ERR_PNF; } - for (link = ZZ_ListHead (list); - !ZZ_ListIterDone (list, link); - link = link->next) - { - if (link->thing->type == type) - { - *it = link->thing; - status = 0; - break; - } + for (link = ZZ_ListHead (list); + !ZZ_ListIterDone (list, link); + link = link->next) { + if (link->thing->type == type) { + *it = link->thing; + status = 0; + break; + } } - - return status; - } - -JAR_Signer *JAR_new_signer (void) - { - JAR_Signer *signer; - - signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer)); - - if (signer == NULL) - goto loser; - - - /* certs */ - signer->certs = ZZ_NewList(); - - if (signer->certs == NULL) - goto loser; - - - /* sf */ - signer->sf = ZZ_NewList(); - - if (signer->sf == NULL) - goto loser; - - - return signer; - + return status; +} + +JAR_Signer * +JAR_new_signer (void) +{ + JAR_Signer *signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer)); + if (signer == NULL) + goto loser; + + /* certs */ + signer->certs = ZZ_NewList(); + if (signer->certs == NULL) + goto loser; + + /* sf */ + signer->sf = ZZ_NewList(); + if (signer->sf == NULL) + goto loser; + return signer; loser: - - if (signer) - { - if (signer->certs) - ZZ_DestroyList (signer->certs); - - if (signer->sf) - ZZ_DestroyList (signer->sf); - - PORT_Free (signer); + if (signer) { + if (signer->certs) + ZZ_DestroyList (signer->certs); + if (signer->sf) + ZZ_DestroyList (signer->sf); + PORT_Free (signer); } - - return NULL; - } - -void JAR_destroy_signer (JAR_Signer *signer) - { - if (signer) - { - if (signer->owner) PORT_Free (signer->owner); - if (signer->digest) PORT_Free (signer->digest); - - jar_destroy_list (signer->sf); - ZZ_DestroyList (signer->sf); - - jar_destroy_list (signer->certs); - ZZ_DestroyList (signer->certs); - - PORT_Free (signer); - } - } - -JAR_Signer *jar_get_signer (JAR *jar, char *basename) - { - JAR_Item *it; - JAR_Context *ctx; - - JAR_Signer *candidate; - JAR_Signer *signer = NULL; - - ctx = JAR_find (jar, NULL, jarTypeOwner); - - if (ctx == NULL) return NULL; - - while (JAR_find_next (ctx, &it) >= 0) - { - candidate = (JAR_Signer *) it->data; - if (*basename == '*' || !PORT_Strcmp (candidate->owner, basename)) - { - signer = candidate; - break; - } +} + +void +JAR_destroy_signer(JAR_Signer *signer) +{ + if (signer) { + if (signer->owner) + PORT_Free (signer->owner); + if (signer->digest) + PORT_Free (signer->digest); + jar_destroy_list (signer->sf); + ZZ_DestroyList (signer->sf); + jar_destroy_list (signer->certs); + ZZ_DestroyList (signer->certs); + PORT_Free (signer); } - - JAR_find_end (ctx); - - return signer; - } +} + +JAR_Signer * +jar_get_signer(JAR *jar, char *basename) +{ + JAR_Item *it; + JAR_Context *ctx = JAR_find (jar, NULL, jarTypeOwner); + JAR_Signer *candidate; + JAR_Signer *signer = NULL; + + if (ctx == NULL) + return NULL; + + while (JAR_find_next (ctx, &it) >= 0) { + candidate = (JAR_Signer *) it->data; + if (*basename == '*' || !PORT_Strcmp (candidate->owner, basename)) { + signer = candidate; + break; + } + } + JAR_find_end (ctx); + return signer; +} /* * J A R _ g e t _ f i l e n a m e @@ -676,11 +568,11 @@ JAR_Signer *jar_get_signer (JAR *jar, char *basename) * a JAR structure. * */ - -char *JAR_get_filename (JAR *jar) - { - return jar->filename; - } +char * +JAR_get_filename(JAR *jar) +{ + return jar->filename; +} /* * J A R _ g e t _ u r l @@ -689,31 +581,27 @@ char *JAR_get_filename (JAR *jar) * a JAR structure. Nobody really uses this now. * */ - -char *JAR_get_url (JAR *jar) - { - return jar->url; - } +char * +JAR_get_url(JAR *jar) +{ + return jar->url; +} /* * J A R _ s e t _ c a l l b a c k * - * Register some manner of callback function for this jar. + * Register some manner of callback function for this jar. * */ - -int JAR_set_callback (int type, JAR *jar, - int (*fn) (int status, JAR *jar, - const char *metafile, char *pathname, char *errortext)) - { - if (type == JAR_CB_SIGNAL) - { - jar->signal = fn; - return 0; +int +JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn) +{ + if (type == JAR_CB_SIGNAL) { + jar->signal = fn; + return 0; } - else return -1; - } +} /* * Callbacks @@ -730,17 +618,14 @@ void *(*jar_fn_FindSomeContext) (void) = NULL; void *(*jar_fn_GetInitContext) (void) = NULL; void -JAR_init_callbacks - ( - char *(*string_cb)(int), - void *(*find_cx)(void), - void *(*init_cx)(void) - ) - { - jar_fn_GetString = string_cb; - jar_fn_FindSomeContext = find_cx; - jar_fn_GetInitContext = init_cx; - } +JAR_init_callbacks(char *(*string_cb)(int), + void *(*find_cx)(void), + void *(*init_cx)(void)) +{ + jar_fn_GetString = string_cb; + jar_fn_FindSomeContext = find_cx; + jar_fn_GetInitContext = init_cx; +} /* * J A R _ g e t _ e r r o r @@ -752,83 +637,74 @@ JAR_init_callbacks * These strings aren't UI, since they are Java console only. * */ +char * +JAR_get_error(int status) +{ + char *errstring = NULL; -char *JAR_get_error (int status) - { - char *errstring = NULL; - - switch (status) - { + switch (status) { case JAR_ERR_GENERAL: - errstring = "General JAR file error"; - break; + errstring = "General JAR file error"; + break; case JAR_ERR_FNF: - errstring = "JAR file not found"; - break; + errstring = "JAR file not found"; + break; case JAR_ERR_CORRUPT: - errstring = "Corrupt JAR file"; - break; + errstring = "Corrupt JAR file"; + break; case JAR_ERR_MEMORY: - errstring = "Out of memory"; - break; + errstring = "Out of memory"; + break; case JAR_ERR_DISK: - errstring = "Disk error (perhaps out of space)"; - break; + errstring = "Disk error (perhaps out of space)"; + break; case JAR_ERR_ORDER: - errstring = "Inconsistent files in META-INF directory"; - break; + errstring = "Inconsistent files in META-INF directory"; + break; case JAR_ERR_SIG: - errstring = "Invalid digital signature file"; - break; + errstring = "Invalid digital signature file"; + break; case JAR_ERR_METADATA: - errstring = "JAR metadata failed verification"; - break; + errstring = "JAR metadata failed verification"; + break; case JAR_ERR_ENTRY: - errstring = "No Manifest entry for this JAR entry"; - break; + errstring = "No Manifest entry for this JAR entry"; + break; case JAR_ERR_HASH: - errstring = "Invalid Hash of this JAR entry"; - break; + errstring = "Invalid Hash of this JAR entry"; + break; case JAR_ERR_PK7: - errstring = "Strange PKCS7 or RSA failure"; - break; + errstring = "Strange PKCS7 or RSA failure"; + break; case JAR_ERR_PNF: - errstring = "Path not found inside JAR file"; - break; + errstring = "Path not found inside JAR file"; + break; default: - if (jar_fn_GetString) - { - errstring = jar_fn_GetString (status); - } - else - { - /* this is not a normal situation, and would only be - called in cases of improper initialization */ - - char *err; - - err = (char*)PORT_Alloc (40); - if (err) - PR_snprintf (err, 39, "Error %d\n", status); - else - err = "Error! Bad! Out of memory!"; - - return err; - } - break; + if (jar_fn_GetString) { + errstring = jar_fn_GetString (status); + } else { + /* this is not a normal situation, and would only be + called in cases of improper initialization */ + char *err = (char*)PORT_Alloc (40); + if (err) + PR_snprintf (err, 39, "Error %d\n", status); /* leak me! */ + else + err = "Error! Bad! Out of memory!"; + return err; + } + break; } - - return errstring; - } + return errstring; +} diff --git a/security/nss/lib/jar/jar.h b/security/nss/lib/jar/jar.h index 23b76b9cf..81516bf21 100644 --- a/security/nss/lib/jar/jar.h +++ b/security/nss/lib/jar/jar.h @@ -50,112 +50,89 @@ /* nspr 2.0 includes */ #include "prio.h" -#ifndef ZHUGEP -#ifdef XP_WIN16 -#define ZHUGEP __huge -#else #define ZHUGEP -#endif -#endif #include <stdio.h> /* various types */ -typedef enum - { - jarTypeMF = 2, - jarTypeSF = 3, - jarTypeMeta = 6, - jarTypePhy = 7, - jarTypeSign = 10, - jarTypeSect = 11, - jarTypeOwner = 13 - } -jarType; +typedef enum { + jarTypeMF = 2, + jarTypeSF = 3, + jarTypeMeta = 6, + jarTypePhy = 7, + jarTypeSign = 10, + jarTypeSect = 11, + jarTypeOwner = 13 +} jarType; /* void data in ZZList's contain JAR_Item type */ - -typedef struct JAR_Item_ - { - char *pathname; /* relative. inside zip file */ - jarType type; /* various types */ - size_t size; /* size of data below */ - void *data; /* totally opaque */ - } -JAR_Item; - +typedef struct JAR_Item_ { + char *pathname; /* relative. inside zip file */ + jarType type; /* various types */ + size_t size; /* size of data below */ + void *data; /* totally opaque */ +} JAR_Item; /* hashes */ - -typedef enum - { - jarHashNone = 0, - jarHashBad = 1, - jarHashPresent = 2 - } -jarHash; - -typedef struct JAR_Digest_ - { - jarHash md5_status; - unsigned char md5 [MD5_LENGTH]; - jarHash sha1_status; - unsigned char sha1 [SHA1_LENGTH]; - } -JAR_Digest; - +typedef enum { + jarHashNone = 0, + jarHashBad = 1, + jarHashPresent = 2 +} jarHash; + +typedef struct JAR_Digest_ { + jarHash md5_status; + unsigned char md5 [MD5_LENGTH]; + jarHash sha1_status; + unsigned char sha1 [SHA1_LENGTH]; +} JAR_Digest; /* physical archive formats */ - -typedef enum - { - jarArchGuess = 0, - jarArchNone = 1, - jarArchZip = 2, - jarArchTar = 3 - } -jarArch; - +typedef enum { + jarArchGuess = 0, + jarArchNone = 1, + jarArchZip = 2, + jarArchTar = 3 +} jarArch; #include "jar-ds.h" -/* jar object */ - -typedef struct JAR_ - { - jarArch format; /* physical archive format */ - char *url; /* Where it came from */ - char *filename; /* Disk location */ - FILE *fp; /* For multiple extractions */ /* JAR_FILE */ +struct JAR_; - /* various linked lists */ +typedef int jar_settable_callback_fn(int status, struct JAR_ *jar, + const char *metafile, char *pathname, + char *errortext); - ZZList *manifest; /* Digests of MF sections */ - ZZList *hashes; /* Digests of actual signed files */ - ZZList *phy; /* Physical layout of JAR file */ - ZZList *metainfo; /* Global metainfo */ - - JAR_Digest *globalmeta; /* digest of .MF global portion */ - - /* Below will change to a linked list to support multiple sigs */ +/* jar object */ +typedef struct JAR_ { + jarArch format; /* physical archive format */ - int pkcs7; /* Enforced opaqueness */ - int valid; /* PKCS7 signature validated */ + char *url; /* Where it came from */ + char *filename; /* Disk location */ + FILE *fp; /* For multiple extractions */ + /* JAR_FILE */ - ZZList *signers; /* the above, per signer */ + /* various linked lists */ + ZZList *manifest; /* Digests of MF sections */ + ZZList *hashes; /* Digests of actual signed files */ + ZZList *phy; /* Physical layout of JAR file */ + ZZList *metainfo; /* Global metainfo */ - /* Window context, very necessary for PKCS11 now */ + JAR_Digest *globalmeta; /* digest of .MF global portion */ - void *mw; /* MWContext window context */ + /* Below will change to a linked list to support multiple sigs */ + int pkcs7; /* Enforced opaqueness */ + int valid; /* PKCS7 signature validated */ - /* Signal callback function */ + ZZList *signers; /* the above, per signer */ - int (*signal) (int status, struct JAR_ *jar, - const char *metafile, char *pathname, char *errorstring); - } -JAR; + /* Window context, very necessary for PKCS11 now */ + void *mw; /* MWContext window context */ + /* Signal callback function */ + jar_settable_callback_fn *signal; +} JAR; /* * Iterator @@ -165,114 +142,90 @@ JAR; * multiple signers. "nextsign" is used for this purpose. * */ - -typedef struct JAR_Context_ - { - JAR *jar; /* Jar we are searching */ - char *pattern; /* Regular expression */ - jarType finding; /* Type of item to find */ - ZZLink *next; /* Next item in find */ - ZZLink *nextsign; /* Next signer, sometimes */ - } -JAR_Context; - -typedef struct JAR_Signer_ - { - int pkcs7; /* Enforced opaqueness */ - int valid; /* PKCS7 signature validated */ - char *owner; /* name of .RSA file */ - JAR_Digest *digest; /* of .SF file */ - ZZList *sf; /* Linked list of .SF file contents */ - ZZList *certs; /* Signing information */ - } -JAR_Signer; - +typedef struct JAR_Context_ { + JAR *jar; /* Jar we are searching */ + char *pattern; /* Regular expression */ + jarType finding; /* Type of item to find */ + ZZLink *next; /* Next item in find */ + ZZLink *nextsign; /* Next signer, sometimes */ +} JAR_Context; + +typedef struct JAR_Signer_ { + int pkcs7; /* Enforced opaqueness */ + int valid; /* PKCS7 signature validated */ + char *owner; /* name of .RSA file */ + JAR_Digest *digest; /* of .SF file */ + ZZList *sf; /* Linked list of .SF file contents */ + ZZList *certs; /* Signing information */ +} JAR_Signer; /* Meta informaton, or "policy", from the manifest file. Right now just one tuple per JAR_Item. */ - -typedef struct JAR_Metainfo_ - { - char *header; - char *info; - } -JAR_Metainfo; +typedef struct JAR_Metainfo_ { + char *header; + char *info; +} JAR_Metainfo; /* This should not be global */ - -typedef struct JAR_Physical_ - { - unsigned char compression; - unsigned long offset; - unsigned long length; - unsigned long uncompressed_length; +typedef struct JAR_Physical_ { + unsigned char compression; + unsigned long offset; + unsigned long length; + unsigned long uncompressed_length; #if defined(XP_UNIX) || defined(XP_BEOS) - uint16 mode; + uint16 mode; #endif - } -JAR_Physical; +} JAR_Physical; -typedef struct JAR_Cert_ - { - size_t length; - void *key; - CERTCertificate *cert; - } -JAR_Cert; +typedef struct JAR_Cert_ { + size_t length; + void *key; + CERTCertificate *cert; +} JAR_Cert; /* certificate stuff */ - -typedef enum - { - jarCertCompany = 1, - jarCertCA = 2, - jarCertSerial = 3, - jarCertExpires = 4, - jarCertNickname = 5, - jarCertFinger = 6, - jarCertJavaHack = 100 - } -jarCert; +typedef enum { + jarCertCompany = 1, + jarCertCA = 2, + jarCertSerial = 3, + jarCertExpires = 4, + jarCertNickname = 5, + jarCertFinger = 6, + jarCertJavaHack = 100 +} jarCert; /* callback types */ - #define JAR_CB_SIGNAL 1 - -/* +/* * This is the base for the JAR 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) +#define SEC_ERR_BASE (-0x2000) #endif - -#define JAR_BASE SEC_ERR_BASE + 300 + +#define JAR_BASE SEC_ERR_BASE + 300 /* Jar specific error definitions */ -#define JAR_ERR_GENERAL (JAR_BASE + 1) +#define JAR_ERR_GENERAL (JAR_BASE + 1) #define JAR_ERR_FNF (JAR_BASE + 2) -#define JAR_ERR_CORRUPT (JAR_BASE + 3) -#define JAR_ERR_MEMORY (JAR_BASE + 4) -#define JAR_ERR_DISK (JAR_BASE + 5) -#define JAR_ERR_ORDER (JAR_BASE + 6) +#define JAR_ERR_CORRUPT (JAR_BASE + 3) +#define JAR_ERR_MEMORY (JAR_BASE + 4) +#define JAR_ERR_DISK (JAR_BASE + 5) +#define JAR_ERR_ORDER (JAR_BASE + 6) #define JAR_ERR_SIG (JAR_BASE + 7) -#define JAR_ERR_METADATA (JAR_BASE + 8) -#define JAR_ERR_ENTRY (JAR_BASE + 9) -#define JAR_ERR_HASH (JAR_BASE + 10) +#define JAR_ERR_METADATA (JAR_BASE + 8) +#define JAR_ERR_ENTRY (JAR_BASE + 9) +#define JAR_ERR_HASH (JAR_BASE + 10) #define JAR_ERR_PK7 (JAR_BASE + 11) #define JAR_ERR_PNF (JAR_BASE + 12) - -/* - * Birth and death - * - */ +/* Function declarations */ extern JAR *JAR_new (void); @@ -280,12 +233,12 @@ extern void PR_CALLBACK JAR_destroy (JAR *jar); extern char *JAR_get_error (int status); -extern int JAR_set_callback (int type, JAR *jar, - int (*fn) (int status, JAR *jar, - const char *metafile, char *pathname, char *errortext)); +extern int JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn); -extern void JAR_init_callbacks - ( char *(*string_cb)(int), void *(*find_cx)(void), void *(*init_cx)(void) ); +extern void +JAR_init_callbacks(char *(*string_cb)(int), + void *(*find_cx)(void), + void *(*init_cx)(void) ); /* * JAR_set_context @@ -294,12 +247,11 @@ extern void JAR_init_callbacks * 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 + * 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 JAR_set_context (JAR *jar, void /*MWContext*/ *mw); /* @@ -315,12 +267,11 @@ int JAR_set_context (JAR *jar, void /*MWContext*/ *mw); * * JAR_Item *item; * JAR_find (jar, "*.class", jarTypeMF); - * while (JAR_find_next (jar, &item) >= 0) - * { do stuff } + * while (JAR_find_next (jar, &item) >= 0) + * { do stuff } * */ - /* Replacement functions with an external context */ extern JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type); @@ -329,14 +280,13 @@ extern int JAR_find_next (JAR_Context *ctx, JAR_Item **it); extern void JAR_find_end (JAR_Context *ctx); - /* * 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. + * Several manifests may be included in the zip file. * * You must pass the MANIFEST.MF file before any .SF files. * @@ -355,9 +305,9 @@ extern void JAR_find_end (JAR_Context *ctx); * */ -extern int JAR_parse_manifest - (JAR *jar, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url); +extern int +JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path, + const char *url); /* * Verify data (nonstreaming). The signature is actually @@ -365,13 +315,14 @@ extern int JAR_parse_manifest * */ -extern JAR_Digest * PR_CALLBACK JAR_calculate_digest - (void ZHUGEP *data, long length); +extern JAR_Digest * PR_CALLBACK +JAR_calculate_digest(void *data, long length); -extern int PR_CALLBACK JAR_verify_digest - (JAR *jar, const char *name, JAR_Digest *dig); +extern int PR_CALLBACK +JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig); -extern int JAR_digest_file (char *filename, JAR_Digest *dig); +extern int +JAR_digest_file(char *filename, JAR_Digest *dig); /* * Get attribute from certificate: @@ -382,16 +333,16 @@ extern int JAR_digest_file (char *filename, JAR_Digest *dig); * */ -extern int PR_CALLBACK JAR_cert_attribute - (JAR *jar, jarCert attrib, long keylen, void *key, - void **result, unsigned long *length); +extern int PR_CALLBACK +JAR_cert_attribute(JAR *jar, jarCert attrib, 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. + * 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. @@ -403,79 +354,65 @@ extern int PR_CALLBACK JAR_cert_attribute * */ -extern int JAR_get_metainfo - (JAR *jar, char *name, char *header, void **info, unsigned long *length); +extern int +JAR_get_metainfo(JAR *jar, char *name, char *header, void **info, + unsigned long *length); extern char *JAR_get_filename (JAR *jar); extern char *JAR_get_url (JAR *jar); -/* - * Return an HTML mockup of a certificate or signature. - * - * Returns a zero terminated ascii string - * in raw HTML format. - * - */ - -extern char *JAR_cert_html - (JAR *jar, int style, long keylen, void *key, int *result); - /* save the certificate with this fingerprint in persistent - storage, somewhere, for retrieval in a future session when there + storage, somewhere, for retrieval in a future session when there is no corresponding JAR structure. */ - -extern int PR_CALLBACK JAR_stash_cert - (JAR *jar, long keylen, void *key); +extern int PR_CALLBACK +JAR_stash_cert(JAR *jar, long keylen, void *key); /* retrieve a certificate presumably stashed with the above function, but may be any certificate. Type is &CERTCertificate */ - -void *JAR_fetch_cert (long length, void *key); +CERTCertificate * +JAR_fetch_cert(long length, void *key); /* * New functions to handle archives alone * (call JAR_new beforehand) * * JAR_pass_archive acts much like parse_manifest. Certificates - * are returned in the JAR structure but as opaque data. When calling - * JAR_verified_extract you still need to decide which of these - * certificates to honor. + * are returned in the JAR structure but as opaque data. When calling + * JAR_verified_extract you still need to decide which of these + * certificates to honor. * - * Code to examine a JAR structure is in jarbert.c. You can obtain both + * Code to examine a JAR structure is in jarbert.c. You can obtain both * a list of filenames and certificates from traversing the linked list. * */ - -extern int JAR_pass_archive - (JAR *jar, jarArch format, char *filename, const char *url); +extern int +JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url); /* * Same thing, but don't check signatures */ -extern int JAR_pass_archive_unverified - (JAR *jar, jarArch format, char *filename, const char *url); +extern int +JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename, + const char *url); /* * Extracts a relative pathname from the archive and places it - * in the filename specified. - * + * in the filename specified. + * * Call JAR_set_nailed if you want to keep the file descriptors * open between multiple calls to JAR_verify_extract. * */ - -extern int JAR_verified_extract - (JAR *jar, char *path, char *outpath); +extern int +JAR_verified_extract(JAR *jar, char *path, char *outpath); /* * JAR_extract does no crypto checking. This can be used if you * need to extract a manifest file or signature, etc. * */ +extern int +JAR_extract(JAR *jar, char *path, char *outpath); -extern int JAR_extract - (JAR *jar, char *path, char *outpath); - - -#endif /* __JAR_h_ */ +#endif /* __JAR_h_ */ diff --git a/security/nss/lib/jar/jarfile.c b/security/nss/lib/jar/jarfile.c index ac2132706..3393d0f56 100644 --- a/security/nss/lib/jar/jarfile.c +++ b/security/nss/lib/jar/jarfile.c @@ -39,11 +39,9 @@ * * Parsing of a Jar file */ - #define JAR_SIZE 256 #include "jar.h" - #include "jarint.h" #include "jarfile.h" @@ -56,50 +54,69 @@ #include "sechash.h" /* for HASH_GetHashObject() */ -/* extracting */ +PR_STATIC_ASSERT(46 == sizeof(struct ZipCentral)); +PR_STATIC_ASSERT(30 == sizeof(struct ZipLocal)); +PR_STATIC_ASSERT(22 == sizeof(struct ZipEnd)); -static int jar_guess_jar (char *filename, JAR_FILE fp); +/* extracting */ +static int +jar_guess_jar(const char *filename, JAR_FILE fp); -static int jar_inflate_memory - (unsigned int method, long *length, long expected_out_len, char ZHUGEP **data); +static int +jar_inflate_memory(unsigned int method, long *length, long expected_out_len, + char **data); -static int jar_physical_extraction - (JAR_FILE fp, char *outpath, long offset, long length); +static int +jar_physical_extraction(JAR_FILE fp, char *outpath, long offset, long length); -static int jar_physical_inflate - (JAR_FILE fp, char *outpath, long offset, - long length, unsigned int method); +static int +jar_physical_inflate(JAR_FILE fp, char *outpath, long offset, long length, + unsigned int method); -static int jar_verify_extract - (JAR *jar, char *path, char *physical_path); +static int +jar_verify_extract(JAR *jar, char *path, char *physical_path); -static JAR_Physical *jar_get_physical (JAR *jar, char *pathname); +static JAR_Physical * +jar_get_physical(JAR *jar, char *pathname); -static int jar_extract_manifests (JAR *jar, jarArch format, JAR_FILE fp); +static int +jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp); -static int jar_extract_mf (JAR *jar, jarArch format, JAR_FILE fp, char *ext); +static int +jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext); /* indexing */ +static int +jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp); -static int jar_gen_index (JAR *jar, jarArch format, JAR_FILE fp); +static int +jar_listtar(JAR *jar, JAR_FILE fp); -static int jar_listtar (JAR *jar, JAR_FILE fp); - -static int jar_listzip (JAR *jar, JAR_FILE fp); +static int +jar_listzip(JAR *jar, JAR_FILE fp); /* conversions */ +static int +dosdate(char *date, const char *s); -static int dosdate (char *date, char *s); - -static int dostime (char *time, char *s); +static int +dostime(char *time, const char *s); -static unsigned int xtoint (unsigned char *ii); +#ifdef NSS_X86_OR_X64 +#define x86ShortToUint32(ii) ((const PRUint32)*((const PRUint16 *)(ii))) +#define x86LongToUint32(ii) (*(const PRUint32 *)(ii)) +#else +static PRUint32 +x86ShortToUint32(const void *ii); -static unsigned long xtolong (unsigned char *ll); +static PRUint32 +x86LongToUint32(const void *ll); +#endif -static long atoo (char *s); +static long +octalToLong(const char *s); /* * J A R _ p a s s _ a r c h i v e @@ -109,44 +126,37 @@ static long atoo (char *s); * the archive file, and do whatever nastiness. * */ +int +JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url) +{ + JAR_FILE fp; + int status = 0; -int JAR_pass_archive - (JAR *jar, jarArch format, char *filename, const char *url) - { - JAR_FILE fp; - int status = 0; - - if (filename == NULL) - return JAR_ERR_GENERAL; - - if ((fp = JAR_FOPEN (filename, "rb")) != NULL) - { - if (format == jarArchGuess) - format = (jarArch)jar_guess_jar (filename, fp); - - jar->format = format; - jar->url = url ? PORT_Strdup (url) : NULL; - jar->filename = PORT_Strdup (filename); + if (filename == NULL) + return JAR_ERR_GENERAL; - status = jar_gen_index (jar, format, fp); + if ((fp = JAR_FOPEN (filename, "rb")) != NULL) { + if (format == jarArchGuess) + format = (jarArch)jar_guess_jar (filename, fp); - if (status == 0) - status = jar_extract_manifests (jar, format, fp); + jar->format = format; + jar->url = url ? PORT_Strdup (url) : NULL; + jar->filename = PORT_Strdup (filename); - JAR_FCLOSE (fp); + status = jar_gen_index (jar, format, fp); + if (status == 0) + status = jar_extract_manifests (jar, format, fp); - if (status < 0) - return status; + JAR_FCLOSE (fp); + if (status < 0) + return status; - /* people were expecting it this way */ - return jar->valid; + /* people were expecting it this way */ + return jar->valid; } - else - { /* file not found */ return JAR_ERR_FNF; - } - } +} /* * J A R _ p a s s _ a r c h i v e _ u n v e r i f i e d @@ -154,43 +164,41 @@ int JAR_pass_archive * Same as JAR_pass_archive, but doesn't parse signatures. * */ -int JAR_pass_archive_unverified - (JAR *jar, jarArch format, char *filename, const char *url) +int +JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename, + const char *url) { - JAR_FILE fp; - int status = 0; + JAR_FILE fp; + int status = 0; - if (filename == NULL) { - return JAR_ERR_GENERAL; - } - - if ((fp = JAR_FOPEN (filename, "rb")) != NULL) { - if (format == jarArchGuess) { - format = (jarArch)jar_guess_jar (filename, fp); - } - - jar->format = format; - jar->url = url ? PORT_Strdup (url) : NULL; - jar->filename = PORT_Strdup (filename); + if (filename == NULL) { + return JAR_ERR_GENERAL; + } - status = jar_gen_index (jar, format, fp); + if ((fp = JAR_FOPEN (filename, "rb")) != NULL) { + if (format == jarArchGuess) { + format = (jarArch)jar_guess_jar (filename, fp); + } - if (status == 0) { - status = jar_extract_mf(jar, format, fp, "mf"); - } + jar->format = format; + jar->url = url ? PORT_Strdup (url) : NULL; + jar->filename = PORT_Strdup (filename); - JAR_FCLOSE (fp); + status = jar_gen_index (jar, format, fp); + if (status == 0) { + status = jar_extract_mf(jar, format, fp, "mf"); + } - if (status < 0) { - return status; - } + JAR_FCLOSE (fp); + if (status < 0) { + return status; + } - /* people were expecting it this way */ - return jar->valid; - } else { - /* file not found */ - return JAR_ERR_FNF; - } + /* people were expecting it this way */ + return jar->valid; + } + /* file not found */ + return JAR_ERR_FNF; } /* @@ -198,78 +206,61 @@ int JAR_pass_archive_unverified * * Optimization: keep a file descriptor open * inside the JAR structure, so we don't have to - * open the file 25 times to run java. + * open the file 25 times to run java. * */ -int JAR_verified_extract - (JAR *jar, char *path, char *outpath) - { - int status; - - status = JAR_extract (jar, path, outpath); +int +JAR_verified_extract(JAR *jar, char *path, char *outpath) +{ + int status = JAR_extract (jar, path, outpath); - if (status >= 0) - return jar_verify_extract (jar, path, outpath); - else + if (status >= 0) + return jar_verify_extract(jar, path, outpath); return status; - } - -int JAR_extract - (JAR *jar, char *path, char *outpath) - { - int result; +} - JAR_Physical *phy; +int +JAR_extract(JAR *jar, char *path, char *outpath) +{ + int result; + JAR_Physical *phy; - if (jar->fp == NULL && jar->filename) - { - jar->fp = (FILE*)JAR_FOPEN (jar->filename, "rb"); + if (jar->fp == NULL && jar->filename) { + jar->fp = (FILE*)JAR_FOPEN (jar->filename, "rb"); } - - if (jar->fp == NULL) - { - /* file not found */ - return JAR_ERR_FNF; + if (jar->fp == NULL) { + /* file not found */ + return JAR_ERR_FNF; } - phy = jar_get_physical (jar, path); - - if (phy) - { - if (phy->compression != 0 && phy->compression != 8) - { - /* unsupported compression method */ - result = JAR_ERR_CORRUPT; - } - - if (phy->compression == 0) - { - result = jar_physical_extraction - ((PRFileDesc*)jar->fp, outpath, phy->offset, phy->length); - } - else - { - result = jar_physical_inflate - ((PRFileDesc*)jar->fp, outpath, phy->offset, phy->length, - (unsigned int) phy->compression); - } + phy = jar_get_physical (jar, path); + if (phy) { + if (phy->compression != 0 && phy->compression != 8) { + /* unsupported compression method */ + result = JAR_ERR_CORRUPT; + } + if (phy->compression == 0) { + result = jar_physical_extraction + ((PRFileDesc*)jar->fp, outpath, phy->offset, phy->length); + } else { + result = jar_physical_inflate((PRFileDesc*)jar->fp, outpath, + phy->offset, phy->length, + (unsigned int) phy->compression); + } #if defined(XP_UNIX) || defined(XP_BEOS) - if (phy->mode) - chmod (outpath, 0400 | (mode_t) phy->mode); + if (phy->mode) + chmod (outpath, 0400 | (mode_t) phy->mode); #endif + } else { + /* pathname not found in archive */ + result = JAR_ERR_PNF; } - else - { - /* pathname not found in archive */ - result = JAR_ERR_PNF; - } - - return result; - } + return result; +} -/* +/* * p h y s i c a l _ e x t r a c t i o n * * This needs to be done in chunks of say 32k, instead of @@ -280,57 +271,41 @@ int JAR_extract #define CHUNK 32768 -static int jar_physical_extraction - (JAR_FILE fp, char *outpath, long offset, long length) - { - JAR_FILE out; - - char *buffer; - long at, chunk; - - int status = 0; - - buffer = (char *) PORT_ZAlloc (CHUNK); - - if (buffer == NULL) - return JAR_ERR_MEMORY; - - if ((out = JAR_FOPEN (outpath, "wb")) != NULL) - { - at = 0; - - JAR_FSEEK (fp, offset, (PRSeekWhence)0); - - while (at < length) - { - chunk = (at + CHUNK <= length) ? CHUNK : length - at; - - if (JAR_FREAD (fp, buffer, chunk) != chunk) - { - status = JAR_ERR_DISK; - break; - } - - at += chunk; - - if (JAR_FWRITE (out, buffer, chunk) < chunk) - { - /* most likely a disk full error */ - status = JAR_ERR_DISK; - break; - } - } - JAR_FCLOSE (out); - } - else - { - /* error opening output file */ - status = JAR_ERR_DISK; +static int +jar_physical_extraction(JAR_FILE fp, char *outpath, long offset, long length) +{ + JAR_FILE out; + char *buffer = (char *)PORT_ZAlloc(CHUNK); + int status = 0; + + if (buffer == NULL) + return JAR_ERR_MEMORY; + + if ((out = JAR_FOPEN (outpath, "wb")) != NULL) { + long at = 0; + + JAR_FSEEK (fp, offset, (PRSeekWhence)0); + while (at < length) { + long chunk = (at + CHUNK <= length) ? CHUNK : length - at; + if (JAR_FREAD (fp, buffer, chunk) != chunk) { + status = JAR_ERR_DISK; + break; + } + at += chunk; + if (JAR_FWRITE (out, buffer, chunk) < chunk) { + /* most likely a disk full error */ + status = JAR_ERR_DISK; + break; + } + } + JAR_FCLOSE (out); + } else { + /* error opening output file */ + status = JAR_ERR_DISK; } - - PORT_Free (buffer); - return status; - } + PORT_Free (buffer); + return status; +} /* * j a r _ p h y s i c a l _ i n f l a t e @@ -339,196 +314,147 @@ static int jar_physical_extraction * result to "outpath". Chunk based. * */ - /* input and output chunks differ, assume 4x compression */ #define ICHUNK 8192 #define OCHUNK 32768 -static int jar_physical_inflate - (JAR_FILE fp, char *outpath, long offset, - long length, unsigned int method) - { - z_stream zs; - - JAR_FILE out; - - long at, chunk; - char *inbuf, *outbuf; - - int status = 0; - - unsigned long prev_total, ochunk, tin; - - /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ - if ((inbuf = (char *) PORT_ZAlloc (ICHUNK + 1)) == NULL) - return JAR_ERR_MEMORY; - - if ((outbuf = (char *) PORT_ZAlloc (OCHUNK)) == NULL) - { - PORT_Free (inbuf); - return JAR_ERR_MEMORY; +static int +jar_physical_inflate(JAR_FILE fp, char *outpath, long offset, long length, + unsigned int method) +{ + char *inbuf, *outbuf; + int status = 0; + z_stream zs; + JAR_FILE out; + + /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ + if ((inbuf = (char *)PORT_ZAlloc(ICHUNK + 1)) == NULL) + return JAR_ERR_MEMORY; + + if ((outbuf = (char *)PORT_ZAlloc(OCHUNK)) == NULL) { + PORT_Free (inbuf); + return JAR_ERR_MEMORY; } - PORT_Memset (&zs, 0, sizeof (zs)); - status = inflateInit2 (&zs, -MAX_WBITS); - - if (status != Z_OK) - { - PORT_Free (inbuf); - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + PORT_Memset (&zs, 0, sizeof (zs)); + status = inflateInit2 (&zs, -MAX_WBITS); + if (status != Z_OK) { + PORT_Free (inbuf); + PORT_Free (outbuf); + return JAR_ERR_GENERAL; } - if ((out = JAR_FOPEN (outpath, "wb")) != NULL) - { - at = 0; - - JAR_FSEEK (fp, offset, (PRSeekWhence)0); - - while (at < length) - { - chunk = (at + ICHUNK <= length) ? ICHUNK : length - at; - - if (JAR_FREAD (fp, inbuf, chunk) != chunk) - { - /* incomplete read */ - JAR_FCLOSE (out); - PORT_Free (inbuf); - PORT_Free (outbuf); - return JAR_ERR_CORRUPT; - } - - at += chunk; - - if (at == length) - { - /* add an extra dummy byte at the end */ - inbuf[chunk++] = 0xDD; - } - - zs.next_in = (Bytef *) inbuf; - zs.avail_in = chunk; - zs.avail_out = OCHUNK; - - tin = zs.total_in; - - while ((zs.total_in - tin < chunk) || (zs.avail_out == 0)) - { - prev_total = zs.total_out; - - zs.next_out = (Bytef *) outbuf; - zs.avail_out = OCHUNK; - - status = inflate (&zs, Z_NO_FLUSH); - - if (status != Z_OK && status != Z_STREAM_END) - { - /* error during decompression */ - JAR_FCLOSE (out); - PORT_Free (inbuf); - PORT_Free (outbuf); - return JAR_ERR_CORRUPT; - } - - ochunk = zs.total_out - prev_total; - - if (JAR_FWRITE (out, outbuf, ochunk) < ochunk) - { - /* most likely a disk full error */ - status = JAR_ERR_DISK; - break; - } - - if (status == Z_STREAM_END) - break; - } - } - - JAR_FCLOSE (out); - status = inflateEnd (&zs); - } - else - { - /* error opening output file */ - status = JAR_ERR_DISK; + if ((out = JAR_FOPEN (outpath, "wb")) != NULL) { + long at = 0; + + JAR_FSEEK (fp, offset, (PRSeekWhence)0); + while (at < length) { + long chunk = (at + ICHUNK <= length) ? ICHUNK : length - at; + unsigned long tin; + + if (JAR_FREAD (fp, inbuf, chunk) != chunk) { + /* incomplete read */ + JAR_FCLOSE (out); + PORT_Free (inbuf); + PORT_Free (outbuf); + return JAR_ERR_CORRUPT; + } + at += chunk; + if (at == length) { + /* add an extra dummy byte at the end */ + inbuf[chunk++] = 0xDD; + } + zs.next_in = (Bytef *) inbuf; + zs.avail_in = chunk; + zs.avail_out = OCHUNK; + tin = zs.total_in; + while ((zs.total_in - tin < chunk) || (zs.avail_out == 0)) { + unsigned long prev_total = zs.total_out; + unsigned long ochunk; + + zs.next_out = (Bytef *) outbuf; + zs.avail_out = OCHUNK; + status = inflate (&zs, Z_NO_FLUSH); + if (status != Z_OK && status != Z_STREAM_END) { + /* error during decompression */ + JAR_FCLOSE (out); + PORT_Free (inbuf); + PORT_Free (outbuf); + return JAR_ERR_CORRUPT; + } + ochunk = zs.total_out - prev_total; + if (JAR_FWRITE (out, outbuf, ochunk) < ochunk) { + /* most likely a disk full error */ + status = JAR_ERR_DISK; + break; + } + if (status == Z_STREAM_END) + break; + } + } + JAR_FCLOSE (out); + status = inflateEnd (&zs); + } else { + /* error opening output file */ + status = JAR_ERR_DISK; } - - PORT_Free (inbuf); - PORT_Free (outbuf); - - return status; - } + PORT_Free (inbuf); + PORT_Free (outbuf); + return status; +} /* * j a r _ i n f l a t e _ m e m o r y * - * Call zlib to inflate the given memory chunk. It is re-XP_ALLOC'd, + * Call zlib to inflate the given memory chunk. It is re-XP_ALLOC'd, * and thus appears to operate inplace to the caller. * */ - -static int jar_inflate_memory - (unsigned int method, long *length, long expected_out_len, char ZHUGEP **data) - { - int status; - z_stream zs; - - long insz, outsz; - - char *inbuf, *outbuf; - - inbuf = *data; - insz = *length; - - outsz = expected_out_len; - outbuf = (char*)PORT_ZAlloc (outsz); - - if (outbuf == NULL) - return JAR_ERR_MEMORY; - - PORT_Memset (&zs, 0, sizeof (zs)); - - status = inflateInit2 (&zs, -MAX_WBITS); - - if (status < 0) - { - /* error initializing zlib stream */ - PORT_Free (outbuf); - return JAR_ERR_GENERAL; +static int +jar_inflate_memory(unsigned int method, long *length, long expected_out_len, + char **data) +{ + char *inbuf = *data; + char *outbuf = (char*)PORT_ZAlloc(expected_out_len); + long insz = *length; + int status; + z_stream zs; + + if (outbuf == NULL) + return JAR_ERR_MEMORY; + + PORT_Memset(&zs, 0, sizeof zs); + status = inflateInit2 (&zs, -MAX_WBITS); + if (status < 0) { + /* error initializing zlib stream */ + PORT_Free (outbuf); + return JAR_ERR_GENERAL; } - zs.next_in = (Bytef *) inbuf; - zs.next_out = (Bytef *) outbuf; - - zs.avail_in = insz; - zs.avail_out = outsz; - - status = inflate (&zs, Z_FINISH); + zs.next_in = (Bytef *) inbuf; + zs.next_out = (Bytef *) outbuf; + zs.avail_in = insz; + zs.avail_out = expected_out_len; - if (status != Z_OK && status != Z_STREAM_END) - { - /* error during deflation */ - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + status = inflate (&zs, Z_FINISH); + if (status != Z_OK && status != Z_STREAM_END) { + /* error during deflation */ + PORT_Free (outbuf); + return JAR_ERR_GENERAL; } - status = inflateEnd (&zs); - - if (status != Z_OK) - { - /* error during deflation */ - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + status = inflateEnd (&zs); + if (status != Z_OK) { + /* error during deflation */ + PORT_Free (outbuf); + return JAR_ERR_GENERAL; } - - PORT_Free (*data); - - *data = outbuf; - *length = zs.total_out; - - return 0; - } + PORT_Free(*data); + *data = outbuf; + *length = zs.total_out; + return 0; +} /* * v e r i f y _ e x t r a c t @@ -536,20 +462,18 @@ static int jar_inflate_memory * Validate signature on the freshly extracted file. * */ +static int +jar_verify_extract(JAR *jar, char *path, char *physical_path) +{ + int status; + JAR_Digest dig; -static int jar_verify_extract (JAR *jar, char *path, char *physical_path) - { - int status; - JAR_Digest dig; - - PORT_Memset (&dig, 0, sizeof (JAR_Digest)); - status = JAR_digest_file (physical_path, &dig); - - if (!status) - status = JAR_verify_digest (jar, path, &dig); - - return status; - } + PORT_Memset (&dig, 0, sizeof dig); + status = JAR_digest_file (physical_path, &dig); + if (!status) + status = JAR_verify_digest (jar, path, &dig); + return status; +} /* * g e t _ p h y s i c a l @@ -558,36 +482,28 @@ static int jar_verify_extract (JAR *jar, char *path, char *physical_path) * Obtains the offset and length of this file in the jar file. * */ - -static JAR_Physical *jar_get_physical (JAR *jar, char *pathname) - { - JAR_Item *it; - - JAR_Physical *phy; - - ZZLink *link; - ZZList *list; - - list = jar->phy; - - if (ZZ_ListEmpty (list)) - return NULL; - - for (link = ZZ_ListHead (list); - !ZZ_ListIterDone (list, link); - link = link->next) - { - it = link->thing; - if (it->type == jarTypePhy - && it->pathname && !PORT_Strcmp (it->pathname, pathname)) - { - phy = (JAR_Physical *) it->data; - return phy; - } +static JAR_Physical * +jar_get_physical(JAR *jar, char *pathname) +{ + ZZLink *link; + ZZList *list = jar->phy; + + if (ZZ_ListEmpty (list)) + return NULL; + + for (link = ZZ_ListHead (list); + !ZZ_ListIterDone (list, link); + link = link->next) { + JAR_Item *it = link->thing; + + if (it->type == jarTypePhy && + it->pathname && !PORT_Strcmp (it->pathname, pathname)) { + JAR_Physical *phy = (JAR_Physical *)it->data; + return phy; + } } - - return NULL; - } + return NULL; +} /* * j a r _ e x t r a c t _ m a n i f e s t s @@ -596,162 +512,138 @@ static JAR_Physical *jar_get_physical (JAR *jar, char *pathname) * from an open archive file whose contents are known. * */ - -static int jar_extract_manifests (JAR *jar, jarArch format, JAR_FILE fp) - { - int status, signatures; - - if (format != jarArchZip && format != jarArchTar) - return JAR_ERR_CORRUPT; - - if ((status = jar_extract_mf (jar, format, fp, "mf")) < 0) - return status; - if (!status) - return JAR_ERR_ORDER; - if ((status = jar_extract_mf (jar, format, fp, "sf")) < 0) - return status; - if (!status) - return JAR_ERR_ORDER; - if ((status = jar_extract_mf (jar, format, fp, "rsa")) < 0) - return status; - signatures = status; - if ((status = jar_extract_mf (jar, format, fp, "dsa")) < 0) - return status; - if (!(signatures += status)) - return JAR_ERR_SIG; - return 0; - } +static int +jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp) +{ + int status, signatures; + + if (format != jarArchZip && format != jarArchTar) + return JAR_ERR_CORRUPT; + + if ((status = jar_extract_mf (jar, format, fp, "mf")) < 0) + return status; + if (!status) + return JAR_ERR_ORDER; + if ((status = jar_extract_mf (jar, format, fp, "sf")) < 0) + return status; + if (!status) + return JAR_ERR_ORDER; + if ((status = jar_extract_mf (jar, format, fp, "rsa")) < 0) + return status; + signatures = status; + if ((status = jar_extract_mf (jar, format, fp, "dsa")) < 0) + return status; + if (!(signatures += status)) + return JAR_ERR_SIG; + return 0; +} /* * j a r _ e x t r a c t _ m f * - * Extracts manifest files based on an extension, which - * should be .MF, .SF, .RSA, etc. Order of the files is now no + * Extracts manifest files based on an extension, which + * should be .MF, .SF, .RSA, etc. Order of the files is now no * longer important when zipping jar files. * */ - -static int jar_extract_mf (JAR *jar, jarArch format, JAR_FILE fp, char *ext) - { - JAR_Item *it; - - JAR_Physical *phy; - - ZZLink *link; - ZZList *list; - - char *fn, *e; - char ZHUGEP *manifest; - - long length; - int status, ret = 0, num; - - list = jar->phy; - - if (ZZ_ListEmpty (list)) - return JAR_ERR_PNF; - - for (link = ZZ_ListHead (list); - ret >= 0 && !ZZ_ListIterDone (list, link); - link = link->next) - { - it = link->thing; - if (it->type == jarTypePhy - && !PORT_Strncmp (it->pathname, "META-INF", 8)) - { - phy = (JAR_Physical *) it->data; - - if (PORT_Strlen (it->pathname) < 8) - continue; - - fn = it->pathname + 8; - if (*fn == '/' || *fn == '\\') fn++; - - if (*fn == 0) - { - /* just a directory entry */ - continue; - } - - /* skip to extension */ - for (e = fn; *e && *e != '.'; e++) - /* yip */ ; - - /* and skip dot */ - if (*e == '.') e++; - - if (PORT_Strcasecmp (ext, e)) - { - /* not the right extension */ - continue; - } - - if (phy->length == 0 || phy->length > 0xFFFF) - { - /* manifest files cannot be zero length or too big! */ - /* the 0xFFFF limit is per J2SE SDK */ - return JAR_ERR_CORRUPT; - } - - /* Read in the manifest and parse it */ - /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ - manifest = (char ZHUGEP *) PORT_ZAlloc (phy->length + 1); - if (manifest) - { - JAR_FSEEK (fp, phy->offset, (PRSeekWhence)0); - num = JAR_FREAD (fp, manifest, phy->length); - - if (num != phy->length) - { - /* corrupt archive file */ - PORT_Free (manifest); - return JAR_ERR_CORRUPT; - } - - if (phy->compression == 8) - { - length = phy->length; - /* add an extra dummy byte at the end */ - manifest[length++] = 0xDD; - - status = jar_inflate_memory ((unsigned int) phy->compression, &length, phy->uncompressed_length, &manifest); - - if (status < 0) - { - PORT_Free (manifest); - return status; - } - } - else if (phy->compression) - { - /* unsupported compression method */ - PORT_Free (manifest); - return JAR_ERR_CORRUPT; - } - else - length = phy->length; - - status = JAR_parse_manifest - (jar, manifest, length, it->pathname, "url"); - - PORT_Free (manifest); - - if (status < 0) - ret = status; - else - ++ret; - } - else - return JAR_ERR_MEMORY; - } - else if (it->type == jarTypePhy) - { - /* ordinary file */ - } +static int +jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext) +{ + ZZLink *link; + ZZList *list = jar->phy; + int ret = 0; + + if (ZZ_ListEmpty (list)) + return JAR_ERR_PNF; + + for (link = ZZ_ListHead (list); + ret >= 0 && !ZZ_ListIterDone (list, link); + link = link->next) { + JAR_Item *it = link->thing; + + if (it->type == jarTypePhy && + !PORT_Strncmp (it->pathname, "META-INF", 8)) + { + JAR_Physical *phy = (JAR_Physical *) it->data; + char *fn = it->pathname + 8; + char *e; + char *manifest; + long length; + int num, status; + + if (PORT_Strlen (it->pathname) < 8) + continue; + + if (*fn == '/' || *fn == '\\') + fn++; + if (*fn == 0) { + /* just a directory entry */ + continue; + } + + /* skip to extension */ + for (e = fn; *e && *e != '.'; e++) + /* yip */ ; + + /* and skip dot */ + if (*e == '.') + e++; + if (PORT_Strcasecmp (ext, e)) { + /* not the right extension */ + continue; + } + if (phy->length == 0 || phy->length > 0xFFFF) { + /* manifest files cannot be zero length or too big! */ + /* the 0xFFFF limit is per J2SE SDK */ + return JAR_ERR_CORRUPT; + } + + /* Read in the manifest and parse it */ + /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ + manifest = (char *)PORT_ZAlloc(phy->length + 1); + if (!manifest) + return JAR_ERR_MEMORY; + + JAR_FSEEK (fp, phy->offset, (PRSeekWhence)0); + num = JAR_FREAD (fp, manifest, phy->length); + if (num != phy->length) { + /* corrupt archive file */ + PORT_Free (manifest); + return JAR_ERR_CORRUPT; + } + + if (phy->compression == 8) { + length = phy->length; + /* add an extra dummy byte at the end */ + manifest[length++] = 0xDD; + status = jar_inflate_memory((unsigned int)phy->compression, + &length, + phy->uncompressed_length, + &manifest); + if (status < 0) { + PORT_Free (manifest); + return status; + } + } else if (phy->compression) { + /* unsupported compression method */ + PORT_Free (manifest); + return JAR_ERR_CORRUPT; + } else + length = phy->length; + + status = JAR_parse_manifest(jar, manifest, length, + it->pathname, "url"); + PORT_Free (manifest); + if (status < 0) + ret = status; + else + ++ret; + } else if (it->type == jarTypePhy) { + /* ordinary file */ + } } - - return ret; - } + return ret; +} /* * j a r _ g e n _ i n d e x @@ -760,406 +652,331 @@ static int jar_extract_mf (JAR *jar, jarArch format, JAR_FILE fp, char *ext) * known archive files. Right now .ZIP and .TAR * */ +static int +jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp) +{ + int result = JAR_ERR_CORRUPT; -static int jar_gen_index (JAR *jar, jarArch format, JAR_FILE fp) - { - int result = JAR_ERR_CORRUPT; - JAR_FSEEK (fp, 0, (PRSeekWhence)0); - - switch (format) - { + JAR_FSEEK (fp, 0, (PRSeekWhence)0); + switch (format) { case jarArchZip: - result = jar_listzip (jar, fp); - break; + result = jar_listzip (jar, fp); + break; case jarArchTar: - result = jar_listtar (jar, fp); - break; + result = jar_listtar (jar, fp); + break; case jarArchGuess: case jarArchNone: - return JAR_ERR_GENERAL; + return JAR_ERR_GENERAL; } - - JAR_FSEEK (fp, 0, (PRSeekWhence)0); - return result; - } - + JAR_FSEEK (fp, 0, (PRSeekWhence)0); + return result; +} /* * j a r _ l i s t z i p * - * List the physical contents of a Phil Katz + * List the physical contents of a Phil Katz * style .ZIP file into the JAR linked list. * */ - -static int jar_listzip (JAR *jar, JAR_FILE fp) - { - int err = 0; - - long pos = 0L; - char filename [JAR_SIZE]; - - char date [9], time [9]; - char sig [4]; - - unsigned int compression; - unsigned int filename_len, extra_len; - - struct ZipLocal *Local; - struct ZipCentral *Central; - struct ZipEnd *End; - - /* phy things */ - - ZZLink *ent; - JAR_Item *it; - JAR_Physical *phy; - - Local = (struct ZipLocal *) PORT_ZAlloc (30); - Central = (struct ZipCentral *) PORT_ZAlloc (46); - End = (struct ZipEnd *) PORT_ZAlloc (22); - - if (!Local || !Central || !End) - { - /* out of memory */ - err = JAR_ERR_MEMORY; - goto loser; +static int +jar_listzip(JAR *jar, JAR_FILE fp) +{ + ZZLink *ent; + JAR_Item *it; + JAR_Physical *phy; + struct ZipLocal *Local = PORT_ZNew(struct ZipLocal); + struct ZipCentral *Central = PORT_ZNew(struct ZipCentral); + struct ZipEnd *End = PORT_ZNew(struct ZipEnd); + + int err = 0; + long pos = 0L; + unsigned int compression; + unsigned int filename_len, extra_len; + + char filename[JAR_SIZE]; + char date[9], time[9]; + char sig[4]; + + if (!Local || !Central || !End) { + /* out of memory */ + err = JAR_ERR_MEMORY; + goto loser; } - while (1) - { - JAR_FSEEK (fp, pos, (PRSeekWhence)0); - - if (JAR_FREAD (fp, (char *) sig, 4) != 4) - { - /* zip file ends prematurely */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - JAR_FSEEK (fp, pos, (PRSeekWhence)0); - - if (xtolong ((unsigned char *)sig) == LSIG) - { - JAR_FREAD (fp, (char *) Local, 30); - - filename_len = xtoint ((unsigned char *) Local->filename_len); - extra_len = xtoint ((unsigned char *) Local->extrafield_len); - - if (filename_len >= JAR_SIZE) - { - /* corrupt zip file */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - if (JAR_FREAD (fp, filename, filename_len) != filename_len) - { - /* truncated archive file */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - filename [filename_len] = 0; - - /* Add this to our jar chain */ - - phy = (JAR_Physical *) PORT_ZAlloc (sizeof (JAR_Physical)); - - if (phy == NULL) - { - err = JAR_ERR_MEMORY; - goto loser; - } - - /* We will index any file that comes our way, but when it comes - to actually extraction, compression must be 0 or 8 */ - - compression = xtoint ((unsigned char *) Local->method); - phy->compression = compression >= 0 && - compression <= 255 ? compression : 222; - - phy->offset = pos + 30 + filename_len + extra_len; - phy->length = xtolong ((unsigned char *) Local->size); - phy->uncompressed_length = xtolong((unsigned char *) Local->orglen); - - dosdate (date, Local->date); - dostime (time, Local->time); - - it = (JAR_Item*)PORT_ZAlloc (sizeof (JAR_Item)); - if (it == NULL) - { - err = JAR_ERR_MEMORY; - goto loser; - } - - it->pathname = PORT_Strdup (filename); - - it->type = jarTypePhy; - - it->data = (unsigned char *) phy; - it->size = sizeof (JAR_Physical); - - ent = ZZ_NewLink (it); - - if (ent == NULL) - { - err = JAR_ERR_MEMORY; - goto loser; - } - - ZZ_AppendLink (jar->phy, ent); - - pos = phy->offset + phy->length; - } - else if (xtolong ( (unsigned char *)sig) == CSIG) - { - if (JAR_FREAD (fp, (char *) Central, 46) != 46) - { - /* apparently truncated archive */ - err = JAR_ERR_CORRUPT; - goto loser; - } + while (1) { + PRUint32 sigVal; + JAR_FSEEK (fp, pos, (PRSeekWhence)0); + + if (JAR_FREAD(fp, sig, sizeof sig) != sizeof sig) { + /* zip file ends prematurely */ + err = JAR_ERR_CORRUPT; + goto loser; + } + + JAR_FSEEK (fp, pos, (PRSeekWhence)0); + sigVal = x86LongToUint32(sig); + if (sigVal == LSIG) { + JAR_FREAD (fp, Local, sizeof *Local); + + filename_len = x86ShortToUint32(Local->filename_len); + extra_len = x86ShortToUint32(Local->extrafield_len); + if (filename_len >= JAR_SIZE) { + /* corrupt zip file */ + err = JAR_ERR_CORRUPT; + goto loser; + } + + if (JAR_FREAD (fp, filename, filename_len) != filename_len) { + /* truncated archive file */ + err = JAR_ERR_CORRUPT; + goto loser; + } + filename [filename_len] = 0; + /* Add this to our jar chain */ + phy = PORT_ZNew(JAR_Physical); + if (phy == NULL) { + err = JAR_ERR_MEMORY; + goto loser; + } + + /* We will index any file that comes our way, but when it comes + to actually extraction, compression must be 0 or 8 */ + compression = x86ShortToUint32(Local->method); + phy->compression = + (compression >= 0 && compression <= 255) ? compression : 222; + /* XXX 222 is bad magic. */ + + phy->offset = pos + (sizeof *Local) + filename_len + extra_len; + phy->length = x86LongToUint32(Local->size); + phy->uncompressed_length = x86LongToUint32(Local->orglen); + + dosdate (date, Local->date); + dostime (time, Local->time); + + it = PORT_ZNew(JAR_Item); + if (it == NULL) { + err = JAR_ERR_MEMORY; + goto loser; + } + + it->pathname = PORT_Strdup(filename); + it->type = jarTypePhy; + it->data = (unsigned char *) phy; + it->size = sizeof (JAR_Physical); + + ent = ZZ_NewLink (it); + if (ent == NULL) { + err = JAR_ERR_MEMORY; + goto loser; + } + + ZZ_AppendLink (jar->phy, ent); + pos = phy->offset + phy->length; + } else if (sigVal == CSIG) { + unsigned int attr = 0; + if (JAR_FREAD(fp, Central, sizeof *Central) != sizeof *Central) { + /* apparently truncated archive */ + err = JAR_ERR_CORRUPT; + goto loser; + } #if defined(XP_UNIX) || defined(XP_BEOS) - /* with unix we need to locate any bits from - the protection mask in the external attributes. */ - { - unsigned int attr; - - /* determined empirically */ - attr = Central->external_attributes [2]; - - if (attr) - { - /* we have to read the filename, again */ - - filename_len = xtoint ((unsigned char *) Central->filename_len); - - if (filename_len >= JAR_SIZE) - { - /* corrupt in central directory */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - if (JAR_FREAD (fp, filename, filename_len) != filename_len) - { - /* truncated in central directory */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - filename [filename_len] = 0; - - /* look up this name again */ - phy = jar_get_physical (jar, filename); - - if (phy) - { - /* always allow access by self */ - phy->mode = 0400 | attr; - } - } - } + /* with unix we need to locate any bits from + the protection mask in the external attributes. */ + attr = Central->external_attributes [2]; /* magic */ + if (attr) { + /* we have to read the filename, again */ + filename_len = x86ShortToUint32(Central->filename_len); + if (filename_len >= JAR_SIZE) { + /* corrupt in central directory */ + err = JAR_ERR_CORRUPT; + goto loser; + } + + if (JAR_FREAD(fp, filename, filename_len) != filename_len) { + /* truncated in central directory */ + err = JAR_ERR_CORRUPT; + goto loser; + } + filename [filename_len] = 0; + + /* look up this name again */ + phy = jar_get_physical (jar, filename); + if (phy) { + /* always allow access by self */ + phy->mode = 0400 | attr; + } + } #endif - - pos += 46 + xtoint ( (unsigned char *)Central->filename_len) - + xtoint ( (unsigned char *)Central->commentfield_len) - + xtoint ( (unsigned char *)Central->extrafield_len); - } - else if (xtolong ( (unsigned char *)sig) == ESIG) - { - if (JAR_FREAD (fp, (char *) End, 22) != 22) - { - err = JAR_ERR_CORRUPT; - goto loser; - } - else - break; - } - else - { - /* garbage in archive */ - err = JAR_ERR_CORRUPT; - goto loser; - } + pos += sizeof(struct ZipCentral) + + x86ShortToUint32(Central->filename_len) + + x86ShortToUint32(Central->commentfield_len) + + x86ShortToUint32(Central->extrafield_len); + } else if (sigVal == ESIG) { + if (JAR_FREAD(fp, End, sizeof *End) != sizeof *End) { + err = JAR_ERR_CORRUPT; + goto loser; + } + break; + } else { + /* garbage in archive */ + err = JAR_ERR_CORRUPT; + goto loser; + } } loser: - - if (Local) PORT_Free (Local); - if (Central) PORT_Free (Central); - if (End) PORT_Free (End); - - return err; - } + if (Local) + PORT_Free(Local); + if (Central) + PORT_Free(Central); + if (End) + PORT_Free(End); + return err; +} /* * j a r _ l i s t t a r * - * List the physical contents of a Unix + * List the physical contents of a Unix * .tar file into the JAR linked list. * */ -static int jar_listtar (JAR *jar, JAR_FILE fp) - { - long pos = 0L; - - long sz, mode; - time_t when; - union TarEntry tarball; - - char *s; - - /* phy things */ - - JAR_Physical *phy; - - while (1) - { - JAR_FSEEK (fp, pos, (PRSeekWhence)0); - - if (JAR_FREAD (fp, (char *) &tarball, 512) < 512) - break; - - if (!*tarball.val.filename) - break; - - when = atoo (tarball.val.time); - sz = atoo (tarball.val.size); - mode = atoo (tarball.val.mode); - - - /* Tag the end of filename */ - - s = tarball.val.filename; - while (*s && *s != ' ') s++; - *s = 0; - - - /* Add to our linked list */ - - phy = (JAR_Physical *) PORT_ZAlloc (sizeof (JAR_Physical)); - - if (phy == NULL) - return JAR_ERR_MEMORY; - - phy->compression = 0; - phy->offset = pos + 512; - phy->length = sz; - - ADDITEM (jar->phy, jarTypePhy, - tarball.val.filename, phy, sizeof (JAR_Physical)); - - - /* Advance to next file entry */ - - sz += 511; - sz = (sz / 512) * 512; - - pos += sz + 512; +static int +jar_listtar(JAR *jar, JAR_FILE fp) +{ + char *s; + JAR_Physical *phy; + long pos = 0L; + long sz, mode; + time_t when; + union TarEntry tarball; + + while (1) { + JAR_FSEEK (fp, pos, (PRSeekWhence)0); + + if (JAR_FREAD (fp, &tarball, sizeof tarball) < sizeof tarball) + break; + + if (!*tarball.val.filename) + break; + + when = octalToLong (tarball.val.time); + sz = octalToLong (tarball.val.size); + mode = octalToLong (tarball.val.mode); + + /* Tag the end of filename */ + s = tarball.val.filename; + while (*s && *s != ' ') + s++; + *s = 0; + + /* Add to our linked list */ + phy = PORT_ZNew(JAR_Physical); + if (phy == NULL) + return JAR_ERR_MEMORY; + + phy->compression = 0; + phy->offset = pos + sizeof tarball; + phy->length = sz; + + ADDITEM(jar->phy, jarTypePhy, tarball.val.filename, phy, + sizeof *phy); + + /* Advance to next file entry */ + sz = PR_ROUNDUP(sz,sizeof tarball); + pos += sz + sizeof tarball; } - return 0; - } + return 0; +} /* * d o s d a t e * * Not used right now, but keep it in here because - * it will be needed. + * it will be needed. * */ +static int +dosdate(char *date, const char *s) +{ + PRUint32 num = x86ShortToUint32(s); -static int dosdate (char *date, char *s) - { - int num = xtoint ( (unsigned char *)s); - - PR_snprintf (date, 9, "%02d-%02d-%02d", - ((num >> 5) & 0x0F), (num & 0x1F), ((num >> 9) + 80)); - - return 0; - } + PR_snprintf(date, 9, "%02d-%02d-%02d", ((num >> 5) & 0x0F), (num & 0x1F), + ((num >> 9) + 80)); + return 0; +} /* * d o s t i m e * * Not used right now, but keep it in here because - * it will be needed. + * it will be needed. * */ +static int +dostime (char *time, const char *s) +{ + PRUint32 num = x86ShortToUint32(s); -static int dostime (char *time, char *s) - { - int num = xtoint ( (unsigned char *)s); - - PR_snprintf (time, 6, "%02d:%02d", - ((num >> 11) & 0x1F), ((num >> 5) & 0x3F)); - - return 0; - } + PR_snprintf (time, 6, "%02d:%02d", ((num >> 11) & 0x1F), + ((num >> 5) & 0x3F)); + return 0; +} +#ifndef NSS_X86_OR_X64 /* - * x t o i n t - * - * Converts a two byte ugly endianed integer - * to our platform's integer. - * + * Simulates an x86 (little endian, unaligned) ushort fetch from any address. */ - -static unsigned int xtoint (unsigned char *ii) - { - return (int) (ii [0]) | ((int) ii [1] << 8); - } +static PRUint32 +x86ShortToUint32(const void * v) +{ + const unsigned char *ii = (const unsigned char *)v; + PRUint32 ret = (PRUint32)(ii[0]) | ((PRUint32)(ii[1]) << 8); + return ret; +} /* - * x t o l o n g - * - * Converts a four byte ugly endianed integer - * to our platform's integer. - * + * Simulates an x86 (little endian, unaligned) uint fetch from any address. */ - -static unsigned long xtolong (unsigned char *ll) - { - unsigned long ret; - - ret = ( - (((unsigned long) ll [0]) << 0) | - (((unsigned long) ll [1]) << 8) | - (((unsigned long) ll [2]) << 16) | - (((unsigned long) ll [3]) << 24) - ); - - return ret; - } +static PRUint32 +x86LongToUint32(const void *v) +{ + const unsigned char *ll = (const unsigned char *)v; + PRUint32 ret; + + ret = ((((PRUint32)(ll[0])) << 0) | + (((PRUint32)(ll[1])) << 8) | + (((PRUint32)(ll[2])) << 16) | + (((PRUint32)(ll[3])) << 24)); + return ret; +} +#endif /* - * a t o o - * - * Ascii octal to decimal. + * ASCII octal to binary long. * Used for integer encoding inside tar files. * */ +static long +octalToLong(const char *s) +{ + long num = 0L; -static long atoo (char *s) - { - long num = 0L; - - while (*s == ' ') s++; - - while (*s >= '0' && *s <= '7') - { - num <<= 3; - num += *s++ - '0'; + while (*s == ' ') + s++; + while (*s >= '0' && *s <= '7') { + num <<= 3; + num += *s++ - '0'; } - - return num; - } + return num; +} /* * g u e s s _ j a r @@ -1169,15 +986,13 @@ static long atoo (char *s) * or at its filename. * */ +static int +jar_guess_jar(const char *filename, JAR_FILE fp) +{ + PRInt32 len = PORT_Strlen(filename); + const char *ext = filename + len - 4; /* 4 for ".tar" */ -static int jar_guess_jar (char *filename, JAR_FILE fp) - { - char *ext; - - ext = filename + PORT_Strlen (filename) - 4; - - if (!PORT_Strcmp (ext, ".tar")) - return jarArchTar; - - return jarArchZip; - } + if (len >= 4 && !PL_strcasecmp(ext, ".tar")) + return jarArchTar; + return jarArchZip; +} diff --git a/security/nss/lib/jar/jarfile.h b/security/nss/lib/jar/jarfile.h index ce3ed3d37..1664223f7 100644 --- a/security/nss/lib/jar/jarfile.h +++ b/security/nss/lib/jar/jarfile.h @@ -36,82 +36,73 @@ /* * JARFILE.H - * + * * Certain constants and structures for the archive format. * */ /* ZIP */ +struct ZipLocal { /* 30 bytes */ + char signature [4]; + char word [2]; + char bitflag [2]; + char method [2]; + char time [2]; + char date [2]; + char crc32 [4]; + char size [4]; + char orglen [4]; + char filename_len [2]; + char extrafield_len [2]; +}; -struct ZipLocal - { - char signature [4]; - char word [2]; - char bitflag [2]; - char method [2]; - char time [2]; - char date [2]; - char crc32 [4]; - char size [4]; - char orglen [4]; - char filename_len [2]; - char extrafield_len [2]; - }; - -struct ZipCentral - { - char signature [4]; - char version_made_by [2]; - char version [2]; - char bitflag [2]; - char method [2]; - char time [2]; - char date [2]; - char crc32 [4]; - char size [4]; - char orglen [4]; - char filename_len [2]; - char extrafield_len [2]; - char commentfield_len [2]; - char diskstart_number [2]; - char internal_attributes [2]; - char external_attributes [4]; - char localhdr_offset [4]; - }; +struct ZipCentral { /* 46 bytes */ + char signature [4]; + char version_made_by [2]; + char version [2]; + char bitflag [2]; + char method [2]; + char time [2]; + char date [2]; + char crc32 [4]; + char size [4]; + char orglen [4]; + char filename_len [2]; + char extrafield_len [2]; + char commentfield_len [2]; + char diskstart_number [2]; + char internal_attributes [2]; + char external_attributes [4]; + char localhdr_offset [4]; +}; -struct ZipEnd - { - char signature [4]; - char disk_nr [2]; - char start_central_dir [2]; - char total_entries_disk [2]; - char total_entries_archive [2]; - char central_dir_size [4]; - char offset_central_dir [4]; - char commentfield_len [2]; - }; +struct ZipEnd { /* 22 bytes */ + char signature [4]; + char disk_nr [2]; + char start_central_dir [2]; + char total_entries_disk [2]; + char total_entries_archive [2]; + char central_dir_size [4]; + char offset_central_dir [4]; + char commentfield_len [2]; +}; #define LSIG 0x04034B50l #define CSIG 0x02014B50l #define ESIG 0x06054B50l /* TAR */ - -union TarEntry - { - struct header - { - char filename [100]; - char mode [8]; - char uid [8]; - char gid [8]; - char size [12]; - char time [12]; - char checksum [8]; - char linkflag; - char linkname [100]; - } - val; - - char buffer [512]; - }; +union TarEntry { /* 512 bytes */ + struct header { /* 257 bytes */ + char filename [100]; + char mode [8]; + char uid [8]; + char gid [8]; + char size [12]; + char time [12]; + char checksum [8]; + char linkflag; + char linkname [100]; + } val; + char buffer [512]; +}; diff --git a/security/nss/lib/jar/jarint.c b/security/nss/lib/jar/jarint.c index a6245fe99..59c8f2936 100644 --- a/security/nss/lib/jar/jarint.c +++ b/security/nss/lib/jar/jarint.c @@ -49,36 +49,36 @@ PRFileDesc* JAR_FOPEN_to_PR_Open(const char* name, const char *mode) { - PRIntn prflags=0, prmode=0; + PRIntn prflags=0, prmode=0; - /* Get read/write flags */ - if(strchr(mode, 'r') && !strchr(mode, '+')) { - prflags |= PR_RDONLY; - } else if( (strchr(mode, 'w') || strchr(mode, 'a')) && - !strchr(mode,'+') ) { - prflags |= PR_WRONLY; - } else { - prflags |= PR_RDWR; - } + /* Get read/write flags */ + if (strchr(mode, 'r') && !strchr(mode, '+')) { + prflags |= PR_RDONLY; + } else if( (strchr(mode, 'w') || strchr(mode, 'a')) && + !strchr(mode,'+') ) { + prflags |= PR_WRONLY; + } else { + prflags |= PR_RDWR; + } - /* Create a new file? */ - if(strchr(mode, 'w') || strchr(mode, 'a')) { - prflags |= PR_CREATE_FILE; - } + /* Create a new file? */ + if (strchr(mode, 'w') || strchr(mode, 'a')) { + prflags |= PR_CREATE_FILE; + } - /* Append? */ - if(strchr(mode, 'a')) { - prflags |= PR_APPEND; - } + /* Append? */ + if (strchr(mode, 'a')) { + prflags |= PR_APPEND; + } - /* Truncate? */ - if(strchr(mode, 'w')) { - prflags |= PR_TRUNCATE; - } + /* Truncate? */ + if (strchr(mode, 'w')) { + prflags |= PR_TRUNCATE; + } - /* We can't do umask because it isn't XP. Choose some default + /* We can't do umask because it isn't XP. Choose some default mode for created files */ - prmode = 0755; + prmode = 0755; - return PR_Open(name, prflags, prmode); + return PR_Open(name, prflags, prmode); } diff --git a/security/nss/lib/jar/jarint.h b/security/nss/lib/jar/jarint.h index c1abc4f94..a61b10093 100644 --- a/security/nss/lib/jar/jarint.h +++ b/security/nss/lib/jar/jarint.h @@ -37,9 +37,6 @@ /* JAR internal routines */ #include "nspr.h" - -/* definitely required */ -/*#include "certdb.h" */ #include "key.h" #include "base64.h" @@ -57,33 +54,34 @@ extern void JAR_destroy_signer (JAR_Signer *signer); extern JAR_Signer *jar_get_signer (JAR *jar, char *basename); -extern int jar_append (ZZList *list, int type, - char *pathname, void *data, size_t size); +extern int +jar_append(ZZList *list, int type, char *pathname, void *data, size_t size); /* Translate fopen mode arg to PR_Open flags and mode */ PRFileDesc* JAR_FOPEN_to_PR_Open(const char *name, const char *mode); - #define ADDITEM(list,type,pathname,data,size) \ - { int err; err = jar_append (list, type, pathname, data, size); \ - if (err < 0) return err; } +{ \ + int err = jar_append (list, type, pathname, data, size); \ + if (err < 0) \ + return err; \ +} /* Here is some ugliness in the event it is necessary to link - with NSPR 1.0 libraries, which do not include an FSEEK. It is + with NSPR 1.0 libraries, which do not include an FSEEK. It is difficult to fudge an FSEEK into 1.0 so we use stdio. */ /* nspr 2.0 suite */ #define JAR_FILE PRFileDesc * -/* #define JAR_FOPEN(fn,mode) PR_Open(fn,0,0) */ #define JAR_FOPEN(fn,mode) JAR_FOPEN_to_PR_Open(fn,mode) #define JAR_FCLOSE PR_Close #define JAR_FSEEK PR_Seek #define JAR_FREAD PR_Read #define JAR_FWRITE PR_Write -int jar_create_pk7 - (CERTCertDBHandle *certdb, void *keydb, - CERTCertificate *cert, char *password, JAR_FILE infp, - JAR_FILE outfp); +int +jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, + CERTCertificate *cert, char *password, JAR_FILE infp, + JAR_FILE outfp); diff --git a/security/nss/lib/jar/jarnav.c b/security/nss/lib/jar/jarnav.c index 58c67df67..63fab59ab 100644 --- a/security/nss/lib/jar/jarnav.c +++ b/security/nss/lib/jar/jarnav.c @@ -45,11 +45,6 @@ #include "jarint.h" /* from proto.h */ -#ifdef MOZILLA_CLIENT_OLD -extern MWContext *XP_FindSomeContext(void); -#endif - -/* sigh */ extern MWContext *FE_GetInitContext(void); /* To return an MWContext for Java */ @@ -62,17 +57,13 @@ static MWContext *(*jar_fn_GetInitContext) (void) = NULL; * J A R _ i n i t * * Initialize the JAR functions. - * + * */ void JAR_init (void) - { -#ifdef MOZILLA_CLIENT_OLD - JAR_init_callbacks (XP_GetString, XP_FindSomeContext, FE_GetInitContext); -#else - JAR_init_callbacks (XP_GetString, NULL, NULL); -#endif - } +{ + JAR_init_callbacks (XP_GetString, NULL, NULL); +} /* * J A R _ s e t _ c o n t e x t @@ -81,30 +72,23 @@ void JAR_init (void) * it may be needed to prompt the user for a password. * */ - -int JAR_set_context (JAR *jar, MWContext *mw) - { - if (mw) - { - jar->mw = mw; +int +JAR_set_context(JAR *jar, MWContext *mw) +{ + if (mw) { + jar->mw = mw; + } else { + /* jar->mw = XP_FindSomeContext(); */ + jar->mw = NULL; + /* + * We can't find a context because we're in startup state and none + * exist yet. go get an FE_InitContext that only works at + * initialization time. + */ + /* Turn on the mac when we get the FE_ function */ + if (jar->mw == NULL) { + jar->mw = jar_fn_GetInitContext(); + } } - else - { - /* jar->mw = XP_FindSomeContext(); */ - jar->mw = NULL; - - /* - * We can't find a context because we're in startup state and none - * exist yet. go get an FE_InitContext that only works at initialization - * time. - */ - - /* Turn on the mac when we get the FE_ function */ - if (jar->mw == NULL) - { - jar->mw = jar_fn_GetInitContext(); - } - } - - return 0; - } + return 0; +} diff --git a/security/nss/lib/jar/jarsign.c b/security/nss/lib/jar/jarsign.c index fb4ad1555..30b7454b1 100644 --- a/security/nss/lib/jar/jarsign.c +++ b/security/nss/lib/jar/jarsign.c @@ -50,160 +50,111 @@ /* from libevent.h */ typedef void (*ETVoidPtrFunc) (void * data); -#ifdef MOZILLA_CLIENT_OLD - -extern void ET_moz_CallFunction (ETVoidPtrFunc fn, void *data); - -/* from proto.h */ -/* extern MWContext *XP_FindSomeContext(void); */ -extern void *XP_FindSomeContext(void); - -#endif - /* key database wrapper */ - /* static SECKEYKeyDBHandle *jar_open_key_database (void); */ - /* CHUNQ is our bite size */ #define CHUNQ 64000 #define FILECHUNQ 32768 /* - * J A R _ c a l c u l a t e _ d i g e s t + * J A R _ c a l c u l a t e _ d i g e s t * * Quick calculation of a digest for * the specified block of memory. Will calculate * for all supported algorithms, now MD5. * * This version supports huge pointers for WIN16. - * + * */ +JAR_Digest * PR_CALLBACK +JAR_calculate_digest(void *data, long length) +{ + PK11Context *md5 = 0; + PK11Context *sha1 = 0; + JAR_Digest *dig = PORT_ZNew(JAR_Digest); + long chunq; + unsigned int md5_length, sha1_length; -JAR_Digest * PR_CALLBACK JAR_calculate_digest (void ZHUGEP *data, long length) - { - long chunq; - JAR_Digest *dig; - - unsigned int md5_length, sha1_length; - - PK11Context *md5 = 0; - PK11Context *sha1 = 0; - - dig = (JAR_Digest *) PORT_ZAlloc (sizeof (JAR_Digest)); - - if (dig == NULL) - { - /* out of memory allocating digest */ - return NULL; + if (dig == NULL) { + /* out of memory allocating digest */ + return NULL; } -#if defined(XP_WIN16) - PORT_Assert ( !IsBadHugeReadPtr(data, length) ); -#endif + md5 = PK11_CreateDigestContext(SEC_OID_MD5); + sha1 = PK11_CreateDigestContext(SEC_OID_SHA1); - md5 = PK11_CreateDigestContext (SEC_OID_MD5); - sha1 = PK11_CreateDigestContext (SEC_OID_SHA1); + if (length >= 0) { + PK11_DigestBegin (md5); + PK11_DigestBegin (sha1); - if (length >= 0) - { - PK11_DigestBegin (md5); - PK11_DigestBegin (sha1); - - do { - chunq = length; - -#ifdef XP_WIN16 - if (length > CHUNQ) chunq = CHUNQ; - - /* - * If the block of data crosses one or more segment - * boundaries then only pass the chunk of data in the - * first segment. - * - * This allows the data to be treated as FAR by the - * PK11_DigestOp(...) routine. - * - */ - - if (OFFSETOF(data) + chunq >= 0x10000) - chunq = 0x10000 - OFFSETOF(data); -#endif - - PK11_DigestOp (md5, (unsigned char*)data, chunq); - PK11_DigestOp (sha1, (unsigned char*)data, chunq); + do { + chunq = length; - length -= chunq; - data = ((char ZHUGEP *) data + chunq); - } - while (length > 0); + PK11_DigestOp(md5, (unsigned char*)data, chunq); + PK11_DigestOp(sha1, (unsigned char*)data, chunq); + length -= chunq; + data = ((char *) data + chunq); + } + while (length > 0); - PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH); - PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH); + PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH); + PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH); - PK11_DestroyContext (md5, PR_TRUE); - PK11_DestroyContext (sha1, PR_TRUE); + PK11_DestroyContext (md5, PR_TRUE); + PK11_DestroyContext (sha1, PR_TRUE); } - - return dig; - } + return dig; +} /* * J A R _ d i g e s t _ f i l e * - * Calculates the MD5 and SHA1 digests for a file + * Calculates the MD5 and SHA1 digests for a file * present on disk, and returns these in JAR_Digest struct. * */ - -int JAR_digest_file (char *filename, JAR_Digest *dig) - { +int +JAR_digest_file (char *filename, JAR_Digest *dig) +{ JAR_FILE fp; - - int num; - unsigned char *buf; - PK11Context *md5 = 0; PK11Context *sha1 = 0; - + unsigned char *buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ); + int num; unsigned int md5_length, sha1_length; - buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ); - if (buf == NULL) - { - /* out of memory */ - return JAR_ERR_MEMORY; - } - - if ((fp = JAR_FOPEN (filename, "rb")) == 0) - { - /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */ - PORT_Free (buf); - return JAR_ERR_FNF; - } + if (buf == NULL) { + /* out of memory */ + return JAR_ERR_MEMORY; + } + + if ((fp = JAR_FOPEN (filename, "rb")) == 0) { + /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */ + PORT_Free (buf); + return JAR_ERR_FNF; + } md5 = PK11_CreateDigestContext (SEC_OID_MD5); sha1 = PK11_CreateDigestContext (SEC_OID_SHA1); - if (md5 == NULL || sha1 == NULL) - { - /* can't generate digest contexts */ - PORT_Free (buf); - JAR_FCLOSE (fp); - return JAR_ERR_GENERAL; - } + if (md5 == NULL || sha1 == NULL) { + /* can't generate digest contexts */ + PORT_Free (buf); + JAR_FCLOSE (fp); + return JAR_ERR_GENERAL; + } PK11_DigestBegin (md5); PK11_DigestBegin (sha1); - while (1) - { - if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0) - break; + while (1) { + if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0) + break; - PK11_DigestOp (md5, buf, num); - PK11_DigestOp (sha1, buf, num); - } + PK11_DigestOp (md5, buf, num); + PK11_DigestOp (sha1, buf, num); + } PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH); PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH); @@ -215,23 +166,25 @@ int JAR_digest_file (char *filename, JAR_Digest *dig) JAR_FCLOSE (fp); return 0; - } +} /* * J A R _ o p e n _ k e y _ d a t a b a s e * */ -void* jar_open_key_database (void) - { +void* +jar_open_key_database(void) +{ return NULL; - } +} -int jar_close_key_database (void *keydb) - { - /* We never do close it */ - return 0; - } +int +jar_close_key_database(void *keydb) +{ + /* We never do close it */ + return 0; +} /* @@ -240,114 +193,78 @@ int jar_close_key_database (void *keydb) */ static void jar_pk7_out (void *arg, const char *buf, unsigned long len) - { - JAR_FWRITE ((JAR_FILE) arg, buf, len); - } - -int jar_create_pk7 - (CERTCertDBHandle *certdb, void *keydb, - CERTCertificate *cert, char *password, JAR_FILE infp, JAR_FILE outfp) - { - int nb; - unsigned char buffer [4096], digestdata[32]; - const SECHashObject *hashObj; - void *hashcx; - unsigned int len; - - int status = 0; - char *errstring; - - SECItem digest; - SEC_PKCS7ContentInfo *cinfo; - SECStatus rv; - - void /*MWContext*/ *mw; - - if (outfp == NULL || infp == NULL || cert == NULL) - return JAR_ERR_GENERAL; - - /* we sign with SHA */ - hashObj = HASH_GetHashObject(HASH_AlgSHA1); - - hashcx = (* hashObj->create)(); - if (hashcx == NULL) - return JAR_ERR_GENERAL; - - (* hashObj->begin)(hashcx); - - while (1) - { - /* nspr2.0 doesn't support feof - if (feof (infp)) break; */ - - nb = JAR_FREAD (infp, buffer, sizeof (buffer)); - if (nb == 0) - { - /* eof */ - break; - } - (* hashObj->update) (hashcx, buffer, nb); +{ + JAR_FWRITE ((JAR_FILE) arg, buf, len); +} + +int +jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert, + char *password, JAR_FILE infp, JAR_FILE outfp) +{ + SEC_PKCS7ContentInfo *cinfo; + const SECHashObject *hashObj; + char *errstring; + void *mw = NULL; + void *hashcx; + unsigned int len; + int status = 0; + SECStatus rv; + SECItem digest; + unsigned char digestdata[32]; + unsigned char buffer[4096]; + + if (outfp == NULL || infp == NULL || cert == NULL) + return JAR_ERR_GENERAL; + + /* we sign with SHA */ + hashObj = HASH_GetHashObject(HASH_AlgSHA1); + + hashcx = (* hashObj->create)(); + if (hashcx == NULL) + return JAR_ERR_GENERAL; + + (* hashObj->begin)(hashcx); + while (1) { + int nb = JAR_FREAD(infp, buffer, sizeof buffer); + if (nb == 0) { /* eof */ + break; + } + (* hashObj->update) (hashcx, buffer, nb); } - - (* hashObj->end) (hashcx, digestdata, &len, 32); - (* hashObj->destroy) (hashcx, PR_TRUE); - - digest.data = digestdata; - digest.len = len; - - /* signtool must use any old context it can find since it's - calling from inside javaland. */ - -#ifdef MOZILLA_CLIENT_OLD - mw = XP_FindSomeContext(); -#else - mw = NULL; -#endif - - PORT_SetError (0); - - cinfo = SEC_PKCS7CreateSignedData - (cert, certUsageObjectSigner, NULL, - SEC_OID_SHA1, &digest, NULL, (void *) mw); - - if (cinfo == NULL) - return JAR_ERR_PK7; - - rv = SEC_PKCS7IncludeCertChain (cinfo, NULL); - if (rv != SECSuccess) - { - status = PORT_GetError(); - SEC_PKCS7DestroyContentInfo (cinfo); - return status; + (* hashObj->end)(hashcx, digestdata, &len, 32); + (* hashObj->destroy)(hashcx, PR_TRUE); + + digest.data = digestdata; + digest.len = len; + + /* signtool must use any old context it can find since it's + calling from inside javaland. */ + PORT_SetError (0); + cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL, + SEC_OID_SHA1, &digest, NULL, mw); + if (cinfo == NULL) + return JAR_ERR_PK7; + + rv = SEC_PKCS7IncludeCertChain(cinfo, NULL); + if (rv != SECSuccess) { + status = PORT_GetError(); + SEC_PKCS7DestroyContentInfo(cinfo); + return status; } - /* Having this here forces signtool to always include - signing time. */ - - rv = SEC_PKCS7AddSigningTime (cinfo); - if (rv != SECSuccess) - { + /* Having this here forces signtool to always include signing time. */ + rv = SEC_PKCS7AddSigningTime(cinfo); /* don't check error */ - } - - PORT_SetError (0); + PORT_SetError(0); - /* if calling from mozilla thread*/ - rv = SEC_PKCS7Encode - (cinfo, jar_pk7_out, outfp, - NULL, /* pwfn */ NULL, /* pwarg */ (void *) mw); - - if (rv != SECSuccess) - status = PORT_GetError(); - - SEC_PKCS7DestroyContentInfo (cinfo); - - if (rv != SECSuccess) - { - errstring = JAR_get_error (status); - /*XP_TRACE (("Jar signing failed (reason %d = %s)", status, errstring));*/ - return status < 0 ? status : JAR_ERR_GENERAL; + /* if calling from mozilla thread*/ + rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw); + if (rv != SECSuccess) + status = PORT_GetError(); + SEC_PKCS7DestroyContentInfo (cinfo); + if (rv != SECSuccess) { + errstring = JAR_get_error (status); + return ((status < 0) ? status : JAR_ERR_GENERAL); } - - return 0; - } + return 0; +} diff --git a/security/nss/lib/jar/jarver.c b/security/nss/lib/jar/jarver.c index d8753dc1d..28e281789 100644 --- a/security/nss/lib/jar/jarver.c +++ b/security/nss/lib/jar/jarver.c @@ -50,136 +50,124 @@ /*#include "cdbhdl.h" */ #include "secder.h" -/* to use huge pointers in win16 */ - -#define xp_HUGE_MEMCPY PORT_Memcpy -#define xp_HUGE_STRCPY PORT_Strcpy -#define xp_HUGE_STRLEN PORT_Strlen -#define xp_HUGE_STRNCASECMP PORT_Strncasecmp - /* from certdb.h */ #define CERTDB_USER (1<<6) #define SZ 512 -static int jar_validate_pkcs7 - (JAR *jar, JAR_Signer *signer, char *data, long length); +static int +jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length); -static void jar_catch_bytes - (void *arg, const char *buf, unsigned long len); +static void +jar_catch_bytes(void *arg, const char *buf, unsigned long len); -static int jar_gather_signers - (JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo); +static int +jar_gather_signers(JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo); -static char ZHUGEP *jar_eat_line - (int lines, int eating, char ZHUGEP *data, long *len); +static char * +jar_eat_line(int lines, int eating, char *data, long *len); -static JAR_Digest *jar_digest_section - (char ZHUGEP *manifest, long length); +static JAR_Digest * +jar_digest_section(char *manifest, long length); -static JAR_Digest *jar_get_mf_digest (JAR *jar, char *path); +static JAR_Digest *jar_get_mf_digest(JAR *jar, char *path); -static int jar_parse_digital_signature - (char *raw_manifest, JAR_Signer *signer, long length, JAR *jar); +static int +jar_parse_digital_signature(char *raw_manifest, JAR_Signer *signer, + long length, JAR *jar); -static int jar_add_cert - (JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert); +static int +jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert); -static CERTCertificate *jar_get_certificate - (JAR *jar, long keylen, void *key, int *result); +static CERTCertificate * +jar_get_certificate(JAR *jar, long keylen, void *key, int *result); -static char *jar_cert_element (char *name, char *tag, int occ); +static char * jar_cert_element(char *name, char *tag, int occ); -static char *jar_choose_nickname (CERTCertificate *cert); +static char *jar_choose_nickname(CERTCertificate *cert); -static char *jar_basename (const char *path); +static char *jar_basename(const char *path); -static int jar_signal - (int status, JAR *jar, const char *metafile, char *pathname); +static int +jar_signal(int status, JAR *jar, const char *metafile, char *pathname); #ifdef DEBUG -static int jar_insanity_check (char ZHUGEP *data, long length); +static int jar_insanity_check(char *data, long length); #endif -int jar_parse_mf - (JAR *jar, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url); +int +jar_parse_mf(JAR *jar, char *raw_manifest, long length, + const char *path, const char *url); -int jar_parse_sf - (JAR *jar, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url); +int +jar_parse_sf(JAR *jar, char *raw_manifest, long length, + const char *path, const char *url); -int jar_parse_sig - (JAR *jar, const char *path, char ZHUGEP *raw_manifest, long length); +int +jar_parse_sig(JAR *jar, const char *path, char *raw_manifest, + long length); -int jar_parse_any - (JAR *jar, int type, JAR_Signer *signer, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url); +int +jar_parse_any(JAR *jar, int type, JAR_Signer *signer, + char *raw_manifest, long length, const char *path, + const char *url); -static int jar_internal_digest - (JAR *jar, const char *path, char *x_name, JAR_Digest *dig); +static int +jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig); /* * J A R _ p a r s e _ m a n i f e s t - * + * * Pass manifest files to this function. They are * decoded and placed into internal representations. - * + * * Accepts both signature and manifest files. Use - * the same "jar" for both. + * the same "jar" for both. * */ - -int JAR_parse_manifest - (JAR *jar, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url) +int +JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, + const char *path, const char *url) { - int filename_free = 0; + int filename_free = 0; - /* fill in the path, if supplied. This is a the location - of the jar file on disk, if known */ + /* fill in the path, if supplied. This is a the location + of the jar file on disk, if known */ - if (jar->filename == NULL && path) - { - jar->filename = PORT_Strdup (path); - if (jar->filename == NULL) - return JAR_ERR_MEMORY; - filename_free = 1; + if (jar->filename == NULL && path) { + jar->filename = PORT_Strdup(path); + if (jar->filename == NULL) + return JAR_ERR_MEMORY; + filename_free = 1; } - /* fill in the URL, if supplied. This is the place - from which the jar file was retrieved. */ + /* fill in the URL, if supplied. This is the place + from which the jar file was retrieved. */ - if (jar->url == NULL && url) - { - jar->url = PORT_Strdup (url); - if (jar->url == NULL) - { - if (filename_free) - { - PORT_Free (jar->filename); - } - return JAR_ERR_MEMORY; - } + if (jar->url == NULL && url) { + jar->url = PORT_Strdup(url); + if (jar->url == NULL) { + if (filename_free) { + PORT_Free(jar->filename); + } + return JAR_ERR_MEMORY; + } } - /* Determine what kind of file this is from the META-INF - directory. It could be MF, SF, or a binary RSA/DSA file */ + /* Determine what kind of file this is from the META-INF + directory. It could be MF, SF, or a binary RSA/DSA file */ - if (!xp_HUGE_STRNCASECMP (raw_manifest, "Manifest-Version:", 17)) - { - return jar_parse_mf (jar, raw_manifest, length, path, url); - } - else if (!xp_HUGE_STRNCASECMP (raw_manifest, "Signature-Version:", 18)) - { - return jar_parse_sf (jar, raw_manifest, length, path, url); + if (!PORT_Strncasecmp (raw_manifest, "Manifest-Version:", 17)) { + return jar_parse_mf(jar, raw_manifest, length, path, url); } - else + else if (!PORT_Strncasecmp (raw_manifest, "Signature-Version:", 18)) { - /* This is probably a binary signature */ - return jar_parse_sig (jar, path, raw_manifest, length); + return jar_parse_sf(jar, raw_manifest, length, path, url); + } else { + /* This is probably a binary signature */ + return jar_parse_sig(jar, path, raw_manifest, length); } - } +} /* * j a r _ p a r s e _ s i g @@ -188,62 +176,56 @@ int JAR_parse_manifest * on, after checking to see if it comes at an appropriate state. * */ - -int jar_parse_sig - (JAR *jar, const char *path, char ZHUGEP *raw_manifest, long length) +int +jar_parse_sig(JAR *jar, const char *path, char *raw_manifest, + long length) { - JAR_Signer *signer; - int status = JAR_ERR_ORDER; + JAR_Signer *signer; + int status = JAR_ERR_ORDER; - if (length <= 128) - { - /* signature is way too small */ - return JAR_ERR_SIG; + if (length <= 128) { + /* signature is way too small */ + return JAR_ERR_SIG; } - /* make sure that MF and SF have already been processed */ - - if (jar->globalmeta == NULL) - return JAR_ERR_ORDER; + /* make sure that MF and SF have already been processed */ - /* Determine whether or not this RSA file has - has an associated SF file */ + if (jar->globalmeta == NULL) + return JAR_ERR_ORDER; - if (path) - { - char *owner; - owner = jar_basename (path); + /* Determine whether or not this RSA file has + has an associated SF file */ - if (owner == NULL) - return JAR_ERR_MEMORY; + if (path) { + char *owner; + owner = jar_basename(path); - signer = jar_get_signer (jar, owner); + if (owner == NULL) + return JAR_ERR_MEMORY; - PORT_Free (owner); - } - else - signer = jar_get_signer (jar, "*"); + signer = jar_get_signer(jar, owner); + PORT_Free(owner); + } else + signer = jar_get_signer(jar, "*"); - if (signer == NULL) - return JAR_ERR_ORDER; + if (signer == NULL) + return JAR_ERR_ORDER; - /* Do not pass a huge pointer to this function, - since the underlying security code is unaware. We will - never pass >64k through here. */ + /* Do not pass a huge pointer to this function, + since the underlying security code is unaware. We will + never pass >64k through here. */ - if (length > 64000) - { - /* this digital signature is way too big */ - return JAR_ERR_SIG; + if (length > 64000) { + /* this digital signature is way too big */ + return JAR_ERR_SIG; } - /* don't expense unneeded calloc overhead on non-win16 */ - status = jar_parse_digital_signature - (raw_manifest, signer, length, jar); + /* don't expense unneeded calloc overhead on non-win16 */ + status = jar_parse_digital_signature(raw_manifest, signer, length, jar); - return status; - } + return status; +} /* * j a r _ p a r s e _ m f @@ -252,522 +234,428 @@ int jar_parse_sig * information applies to all signers. * */ - -int jar_parse_mf - (JAR *jar, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url) - { - if (jar->globalmeta) - { - /* refuse a second manifest file, if passed for some reason */ - return JAR_ERR_ORDER; +int +jar_parse_mf(JAR *jar, char *raw_manifest, long length, + const char *path, const char *url) +{ + if (jar->globalmeta) { + /* refuse a second manifest file, if passed for some reason */ + return JAR_ERR_ORDER; } - - /* remember a digest for the global section */ - - jar->globalmeta = jar_digest_section (raw_manifest, length); - - if (jar->globalmeta == NULL) - return JAR_ERR_MEMORY; - - - return jar_parse_any - (jar, jarTypeMF, NULL, raw_manifest, length, path, url); - } + /* remember a digest for the global section */ + jar->globalmeta = jar_digest_section(raw_manifest, length); + if (jar->globalmeta == NULL) + return JAR_ERR_MEMORY; + return jar_parse_any(jar, jarTypeMF, NULL, raw_manifest, length, + path, url); +} /* * j a r _ p a r s e _ s f * * Parse META-INF/xxx.sf, a digitally signed file - * pointing to a subset of MF sections. + * pointing to a subset of MF sections. * */ +int +jar_parse_sf(JAR *jar, char *raw_manifest, long length, + const char *path, const char *url) +{ + JAR_Signer *signer = NULL; + int status = JAR_ERR_MEMORY; -int jar_parse_sf - (JAR *jar, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url) - { - JAR_Signer *signer = NULL; - int status = JAR_ERR_MEMORY; - - if (jar->globalmeta == NULL) - { - /* It is a requirement that the MF file be passed before the SF file */ - return JAR_ERR_ORDER; + if (jar->globalmeta == NULL) { + /* It is a requirement that the MF file be passed before the SF file */ + return JAR_ERR_ORDER; } - signer = JAR_new_signer(); + signer = JAR_new_signer(); + if (signer == NULL) + goto loser; - if (signer == NULL) - goto loser; - - if (path) - { - signer->owner = jar_basename (path); - if (signer->owner == NULL) - goto loser; + if (path) { + signer->owner = jar_basename(path); + if (signer->owner == NULL) + goto loser; } - - /* check for priors. When someone doctors a jar file - to contain identical path entries, prevent the second - one from affecting JAR functions */ - - if (jar_get_signer (jar, signer->owner)) - { - /* someone is trying to spoof us */ - status = JAR_ERR_ORDER; - goto loser; + /* check for priors. When someone doctors a jar file + to contain identical path entries, prevent the second + one from affecting JAR functions */ + if (jar_get_signer(jar, signer->owner)) { + /* someone is trying to spoof us */ + status = JAR_ERR_ORDER; + goto loser; } + /* remember its digest */ + signer->digest = JAR_calculate_digest (raw_manifest, length); + if (signer->digest == NULL) + goto loser; - /* remember its digest */ - - signer->digest = JAR_calculate_digest (raw_manifest, length); - - if (signer->digest == NULL) - goto loser; - - /* Add this signer to the jar */ - - ADDITEM (jar->signers, jarTypeOwner, - signer->owner, signer, sizeof (JAR_Signer)); - + /* Add this signer to the jar */ + ADDITEM(jar->signers, jarTypeOwner, signer->owner, signer, + sizeof (JAR_Signer)); - return jar_parse_any - (jar, jarTypeSF, signer, raw_manifest, length, path, url); + return jar_parse_any(jar, jarTypeSF, signer, raw_manifest, length, + path, url); loser: + if (signer) + JAR_destroy_signer (signer); + return status; +} - if (signer) - JAR_destroy_signer (signer); - - return status; - } - -/* +/* * j a r _ p a r s e _ a n y * - * Parse a MF or SF manifest file. + * Parse a MF or SF manifest file. * */ - -int jar_parse_any - (JAR *jar, int type, JAR_Signer *signer, char ZHUGEP *raw_manifest, - long length, const char *path, const char *url) - { - int status; - - long raw_len; - - JAR_Digest *dig, *mfdig = NULL; - - char line [SZ]; - char x_name [SZ], x_md5 [SZ], x_sha [SZ]; - - char *x_info; - - char *sf_md5 = NULL, *sf_sha1 = NULL; +int +jar_parse_any(JAR *jar, int type, JAR_Signer *signer, + char *raw_manifest, long length, const char *path, + const char *url) +{ + int status; + long raw_len; + JAR_Digest *dig, *mfdig = NULL; + char line [SZ]; + char x_name [SZ], x_md5 [SZ], x_sha [SZ]; + char *x_info; + char *sf_md5 = NULL, *sf_sha1 = NULL; - *x_name = 0; - *x_md5 = 0; - *x_sha = 0; + *x_name = 0; + *x_md5 = 0; + *x_sha = 0; - PORT_Assert( length > 0 ); - raw_len = length; + PORT_Assert( length > 0 ); + raw_len = length; #ifdef DEBUG - if ((status = jar_insanity_check (raw_manifest, raw_len)) < 0) - return status; + if ((status = jar_insanity_check(raw_manifest, raw_len)) < 0) + return status; #endif + /* null terminate the first line */ + raw_manifest = jar_eat_line(0, PR_TRUE, raw_manifest, &raw_len); - /* null terminate the first line */ - raw_manifest = jar_eat_line (0, PR_TRUE, raw_manifest, &raw_len); - - - /* skip over the preliminary section */ - /* This is one section at the top of the file with global metainfo */ - - while (raw_len) - { - JAR_Metainfo *met; - - raw_manifest = jar_eat_line (1, PR_TRUE, raw_manifest, &raw_len); - if (!*raw_manifest) break; - - met = (JAR_Metainfo*)PORT_ZAlloc (sizeof (JAR_Metainfo)); - if (met == NULL) - return JAR_ERR_MEMORY; + /* skip over the preliminary section */ + /* This is one section at the top of the file with global metainfo */ + while (raw_len) { + JAR_Metainfo *met; - /* Parse out the header & info */ + raw_manifest = jar_eat_line(1, PR_TRUE, raw_manifest, &raw_len); + if (!*raw_manifest) + break; - if (xp_HUGE_STRLEN (raw_manifest) >= SZ) - { - /* almost certainly nonsense */ - PORT_Free (met); - continue; - } + met = PORT_ZNew(JAR_Metainfo); + if (met == NULL) + return JAR_ERR_MEMORY; - xp_HUGE_STRCPY (line, raw_manifest); - x_info = line; + /* Parse out the header & info */ + if (PORT_Strlen (raw_manifest) >= SZ) { + /* almost certainly nonsense */ + PORT_Free(met); + continue; + } - while (*x_info && *x_info != ' ' && *x_info != '\t' && *x_info != ':') - x_info++; + PORT_Strcpy (line, raw_manifest); + x_info = line; - if (*x_info) *x_info++ = 0; + while (*x_info && *x_info != ' ' && *x_info != '\t' && *x_info != ':') + x_info++; - while (*x_info == ' ' || *x_info == '\t') - x_info++; + if (*x_info) + *x_info++ = 0; - /* metainfo (name, value) pair is now (line, x_info) */ + while (*x_info == ' ' || *x_info == '\t') + x_info++; - met->header = PORT_Strdup (line); - met->info = PORT_Strdup (x_info); + /* metainfo (name, value) pair is now (line, x_info) */ + met->header = PORT_Strdup(line); + met->info = PORT_Strdup(x_info); - if (type == jarTypeMF) - { - ADDITEM (jar->metainfo, jarTypeMeta, - /* pathname */ NULL, met, sizeof (JAR_Metainfo)); - } + if (type == jarTypeMF) { + ADDITEM (jar->metainfo, jarTypeMeta, + /* pathname */ NULL, met, sizeof (JAR_Metainfo)); + } - /* For SF files, this metadata may be the digests - of the MF file, still in the "met" structure. */ + /* For SF files, this metadata may be the digests + of the MF file, still in the "met" structure. */ - if (type == jarTypeSF) - { - if (!PORT_Strcasecmp (line, "MD5-Digest")) - sf_md5 = (char *) met->info; + if (type == jarTypeSF) { + if (!PORT_Strcasecmp(line, "MD5-Digest")) + sf_md5 = (char *) met->info; - if (!PORT_Strcasecmp (line, "SHA1-Digest") || !PORT_Strcasecmp (line, "SHA-Digest")) - sf_sha1 = (char *) met->info; - } + if (!PORT_Strcasecmp(line, "SHA1-Digest") || !PORT_Strcasecmp (line, "SHA-Digest")) + sf_sha1 = (char *) met->info; + } - if (type != jarTypeMF) - { - PORT_Free (met->header); - if (type != jarTypeSF) - { - PORT_Free (met->info); - } - PORT_Free (met); - } + if (type != jarTypeMF) { + PORT_Free(met->header); + if (type != jarTypeSF) { + PORT_Free(met->info); + } + PORT_Free(met); + } } - if (type == jarTypeSF && jar->globalmeta) - { - /* this is a SF file which may contain a digest of the manifest.mf's - global metainfo. */ + if (type == jarTypeSF && jar->globalmeta) { + /* this is a SF file which may contain a digest of the manifest.mf's + global metainfo. */ - int match = 0; - JAR_Digest *glob = jar->globalmeta; + int match = 0; + JAR_Digest *glob = jar->globalmeta; - if (sf_md5) - { - unsigned int md5_length; - unsigned char *md5_digest; + if (sf_md5) { + unsigned int md5_length; + unsigned char *md5_digest; - md5_digest = ATOB_AsciiToData (sf_md5, &md5_length); - PORT_Assert( md5_length == MD5_LENGTH ); + md5_digest = ATOB_AsciiToData (sf_md5, &md5_length); + PORT_Assert( md5_length == MD5_LENGTH ); - if (md5_length != MD5_LENGTH) - return JAR_ERR_CORRUPT; + if (md5_length != MD5_LENGTH) + return JAR_ERR_CORRUPT; - match = PORT_Memcmp (md5_digest, glob->md5, MD5_LENGTH); - } + match = PORT_Memcmp(md5_digest, glob->md5, MD5_LENGTH); + } - if (sf_sha1 && match == 0) - { - unsigned int sha1_length; - unsigned char *sha1_digest; + if (sf_sha1 && match == 0) { + unsigned int sha1_length; + unsigned char *sha1_digest; - sha1_digest = ATOB_AsciiToData (sf_sha1, &sha1_length); - PORT_Assert( sha1_length == SHA1_LENGTH ); + sha1_digest = ATOB_AsciiToData (sf_sha1, &sha1_length); + PORT_Assert( sha1_length == SHA1_LENGTH ); - if (sha1_length != SHA1_LENGTH) - return JAR_ERR_CORRUPT; + if (sha1_length != SHA1_LENGTH) + return JAR_ERR_CORRUPT; - match = PORT_Memcmp (sha1_digest, glob->sha1, SHA1_LENGTH); - } + match = PORT_Memcmp(sha1_digest, glob->sha1, SHA1_LENGTH); + } - if (match != 0) - { - /* global digest doesn't match, SF file therefore invalid */ - jar->valid = JAR_ERR_METADATA; - return JAR_ERR_METADATA; - } + if (match != 0) { + /* global digest doesn't match, SF file therefore invalid */ + jar->valid = JAR_ERR_METADATA; + return JAR_ERR_METADATA; + } } - /* done with top section of global data */ - - - while (raw_len) - { - *x_md5 = 0; - *x_sha = 0; - *x_name = 0; - - - /* If this is a manifest file, attempt to get a digest of the following section, - without damaging it. This digest will be saved later. */ - - if (type == jarTypeMF) - { - char ZHUGEP *sec; - long sec_len = raw_len; - - if (!*raw_manifest || *raw_manifest == '\n') - { - /* skip the blank line */ - sec = jar_eat_line (1, PR_FALSE, raw_manifest, &sec_len); - } - else - sec = raw_manifest; - - if (!xp_HUGE_STRNCASECMP (sec, "Name:", 5)) - { - if (type == jarTypeMF) - mfdig = jar_digest_section (sec, sec_len); - else - mfdig = NULL; - } - } - - - while (raw_len) - { - raw_manifest = jar_eat_line (1, PR_TRUE, raw_manifest, &raw_len); - if (!*raw_manifest) break; /* blank line, done with this entry */ - - if (xp_HUGE_STRLEN (raw_manifest) >= SZ) - { - /* almost certainly nonsense */ - continue; - } - - - /* Parse out the name/value pair */ - - xp_HUGE_STRCPY (line, raw_manifest); - x_info = line; - - while (*x_info && *x_info != ' ' && *x_info != '\t' && *x_info != ':') - x_info++; - - if (*x_info) *x_info++ = 0; - - while (*x_info == ' ' || *x_info == '\t') - x_info++; - - - if (!PORT_Strcasecmp (line, "Name")) - PORT_Strcpy (x_name, x_info); - - else if (!PORT_Strcasecmp (line, "MD5-Digest")) - PORT_Strcpy (x_md5, x_info); - - else if (!PORT_Strcasecmp (line, "SHA1-Digest") - || !PORT_Strcasecmp (line, "SHA-Digest")) - { - PORT_Strcpy (x_sha, x_info); - } - - /* Algorithm list is meta info we don't care about; keeping it out - of metadata saves significant space for large jar files */ + /* done with top section of global data */ + while (raw_len) { + *x_md5 = 0; + *x_sha = 0; + *x_name = 0; + + /* If this is a manifest file, attempt to get a digest of the following + section, without damaging it. This digest will be saved later. */ + + if (type == jarTypeMF) { + char *sec; + long sec_len = raw_len; + + if (!*raw_manifest || *raw_manifest == '\n') { + /* skip the blank line */ + sec = jar_eat_line(1, PR_FALSE, raw_manifest, &sec_len); + } else + sec = raw_manifest; + + if (!PORT_Strncasecmp(sec, "Name:", 5)) { + if (type == jarTypeMF) + mfdig = jar_digest_section(sec, sec_len); + else + mfdig = NULL; + } + } - else if (!PORT_Strcasecmp (line, "Digest-Algorithms") - || !PORT_Strcasecmp (line, "Hash-Algorithms")) - { - continue; - } - /* Meta info is only collected for the manifest.mf file, - since the JAR_get_metainfo call does not support identity */ + while (raw_len) { + raw_manifest = jar_eat_line(1, PR_TRUE, raw_manifest, &raw_len); + if (!*raw_manifest) + break; /* blank line, done with this entry */ - else if (type == jarTypeMF) - { - JAR_Metainfo *met; + if (PORT_Strlen(raw_manifest) >= SZ) { + /* almost certainly nonsense */ + continue; + } + + /* Parse out the name/value pair */ + PORT_Strcpy(line, raw_manifest); + x_info = line; + + while (*x_info && *x_info != ' ' && *x_info != '\t' && + *x_info != ':') + x_info++; + + if (*x_info) + *x_info++ = 0; + + while (*x_info == ' ' || *x_info == '\t') + x_info++; + + if (!PORT_Strcasecmp(line, "Name")) + PORT_Strcpy(x_name, x_info); + else if (!PORT_Strcasecmp(line, "MD5-Digest")) + PORT_Strcpy(x_md5, x_info); + else if (!PORT_Strcasecmp(line, "SHA1-Digest") + || !PORT_Strcasecmp(line, "SHA-Digest")) + PORT_Strcpy(x_sha, x_info); + + /* Algorithm list is meta info we don't care about; keeping it out + of metadata saves significant space for large jar files */ + else if (!PORT_Strcasecmp(line, "Digest-Algorithms") + || !PORT_Strcasecmp(line, "Hash-Algorithms")) + continue; - /* this is meta-data */ + /* Meta info is only collected for the manifest.mf file, + since the JAR_get_metainfo call does not support identity */ + else if (type == jarTypeMF) { + JAR_Metainfo *met; + + /* this is meta-data */ + met = PORT_ZNew(JAR_Metainfo); + if (met == NULL) + return JAR_ERR_MEMORY; + + /* metainfo (name, value) pair is now (line, x_info) */ + if ((met->header = PORT_Strdup(line)) == NULL) { + PORT_Free(met); + return JAR_ERR_MEMORY; + } + + if ((met->info = PORT_Strdup(x_info)) == NULL) { + PORT_Free(met->header); + PORT_Free(met); + return JAR_ERR_MEMORY; + } + + ADDITEM (jar->metainfo, jarTypeMeta, + x_name, met, sizeof (JAR_Metainfo)); + } + } - met = (JAR_Metainfo*)PORT_ZAlloc (sizeof (JAR_Metainfo)); + if (!x_name || !*x_name) { + /* Whatever that was, it wasn't an entry, because we didn't get a + name. We don't really have anything, so don't record this. */ + continue; + } - if (met == NULL) - return JAR_ERR_MEMORY; + dig = PORT_ZNew(JAR_Digest); + if (dig == NULL) + return JAR_ERR_MEMORY; + + if (*x_md5) { + unsigned int binary_length; + unsigned char *binary_digest; + + binary_digest = ATOB_AsciiToData (x_md5, &binary_length); + PORT_Assert( binary_length == MD5_LENGTH ); + if (binary_length != MD5_LENGTH) { + PORT_Free(dig); + return JAR_ERR_CORRUPT; + } + memcpy (dig->md5, binary_digest, MD5_LENGTH); + dig->md5_status = jarHashPresent; + } - /* metainfo (name, value) pair is now (line, x_info) */ + if (*x_sha ) { + unsigned int binary_length; + unsigned char *binary_digest; + + binary_digest = ATOB_AsciiToData (x_sha, &binary_length); + PORT_Assert( binary_length == SHA1_LENGTH ); + if (binary_length != SHA1_LENGTH) { + PORT_Free(dig); + return JAR_ERR_CORRUPT; + } + memcpy (dig->sha1, binary_digest, SHA1_LENGTH); + dig->sha1_status = jarHashPresent; + } - if ((met->header = PORT_Strdup (line)) == NULL) - { - PORT_Free (met); - return JAR_ERR_MEMORY; - } + PORT_Assert( type == jarTypeMF || type == jarTypeSF ); + if (type == jarTypeMF) { + ADDITEM (jar->hashes, jarTypeMF, x_name, dig, sizeof (JAR_Digest)); + } else if (type == jarTypeSF) { + ADDITEM (signer->sf, jarTypeSF, x_name, dig, sizeof (JAR_Digest)); + } else { + PORT_Free(dig); + return JAR_ERR_ORDER; + } - if ((met->info = PORT_Strdup (x_info)) == NULL) - { - PORT_Free (met->header); - PORT_Free (met); - return JAR_ERR_MEMORY; - } + /* we're placing these calculated digests of manifest.mf + sections in a list where they can subsequently be forgotten */ + if (type == jarTypeMF && mfdig) { + ADDITEM (jar->manifest, jarTypeSect, + x_name, mfdig, sizeof (JAR_Digest)); + mfdig = NULL; + } - ADDITEM (jar->metainfo, jarTypeMeta, - x_name, met, sizeof (JAR_Metainfo)); - } - } + /* Retrieve our saved SHA1 digest from saved copy and check digests. + This is just comparing the digest of the MF section as indicated in + the SF file with the one we remembered from parsing the MF file */ - if(!x_name || !*x_name) { - /* Whatever that was, it wasn't an entry, because we didn't get a name. - * We don't really have anything, so don't record this. */ - continue; + if (type == jarTypeSF) { + if ((status = jar_internal_digest(jar, path, x_name, dig)) < 0) + return status; } - - dig = (JAR_Digest*)PORT_ZAlloc (sizeof (JAR_Digest)); - if (dig == NULL) - return JAR_ERR_MEMORY; - - if (*x_md5 ) - { - unsigned int binary_length; - unsigned char *binary_digest; - - binary_digest = ATOB_AsciiToData (x_md5, &binary_length); - PORT_Assert( binary_length == MD5_LENGTH ); - - if (binary_length != MD5_LENGTH) - { - PORT_Free (dig); - return JAR_ERR_CORRUPT; - } - - memcpy (dig->md5, binary_digest, MD5_LENGTH); - dig->md5_status = jarHashPresent; - } - - if (*x_sha ) - { - unsigned int binary_length; - unsigned char *binary_digest; - - binary_digest = ATOB_AsciiToData (x_sha, &binary_length); - PORT_Assert( binary_length == SHA1_LENGTH ); - - if (binary_length != SHA1_LENGTH) - { - PORT_Free (dig); - return JAR_ERR_CORRUPT; - } - - memcpy (dig->sha1, binary_digest, SHA1_LENGTH); - dig->sha1_status = jarHashPresent; - } - - PORT_Assert( type == jarTypeMF || type == jarTypeSF ); - - - if (type == jarTypeMF) - { - ADDITEM (jar->hashes, jarTypeMF, x_name, dig, sizeof (JAR_Digest)); - } - else if (type == jarTypeSF) - { - ADDITEM (signer->sf, jarTypeSF, x_name, dig, sizeof (JAR_Digest)); - } - else - { - PORT_Free (dig); - return JAR_ERR_ORDER; - } - - /* we're placing these calculated digests of manifest.mf - sections in a list where they can subsequently be forgotten */ - - if (type == jarTypeMF && mfdig) - { - ADDITEM (jar->manifest, jarTypeSect, - x_name, mfdig, sizeof (JAR_Digest)); - - mfdig = NULL; - } - - - /* Retrieve our saved SHA1 digest from saved copy and check digests. - This is just comparing the digest of the MF section as indicated in - the SF file with the one we remembered from parsing the MF file */ - - if (type == jarTypeSF) - { - if ((status = jar_internal_digest (jar, path, x_name, dig)) < 0) - return status; - } } - return 0; - } + return 0; +} -static int jar_internal_digest - (JAR *jar, const char *path, char *x_name, JAR_Digest *dig) - { - int cv; - int status; +static int +jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig) +{ + int cv; + int status; + + JAR_Digest *savdig; + + savdig = jar_get_mf_digest(jar, x_name); + if (savdig == NULL) { + /* no .mf digest for this pathname */ + status = jar_signal(JAR_ERR_ENTRY, jar, path, x_name); + if (status < 0) + return 0; /* was continue; */ + return status; + } - JAR_Digest *savdig; + /* check for md5 consistency */ + if (dig->md5_status) { + cv = PORT_Memcmp(savdig->md5, dig->md5, MD5_LENGTH); + /* md5 hash of .mf file is not what expected */ + if (cv) { + status = jar_signal(JAR_ERR_HASH, jar, path, x_name); - savdig = jar_get_mf_digest (jar, x_name); + /* bad hash, man */ + dig->md5_status = jarHashBad; + savdig->md5_status = jarHashBad; - if (savdig == NULL) - { - /* no .mf digest for this pathname */ - status = jar_signal (JAR_ERR_ENTRY, jar, path, x_name); - if (status < 0) - return 0; /* was continue; */ - else - return status; + if (status < 0) + return 0; /* was continue; */ + return status; + } } - /* check for md5 consistency */ - if (dig->md5_status) - { - cv = PORT_Memcmp (savdig->md5, dig->md5, MD5_LENGTH); - /* md5 hash of .mf file is not what expected */ - if (cv) - { - status = jar_signal (JAR_ERR_HASH, jar, path, x_name); - - /* bad hash, man */ - - dig->md5_status = jarHashBad; - savdig->md5_status = jarHashBad; - - if (status < 0) - return 0; /* was continue; */ - else - return status; - } - } + /* check for sha1 consistency */ + if (dig->sha1_status) { + cv = PORT_Memcmp(savdig->sha1, dig->sha1, SHA1_LENGTH); + /* sha1 hash of .mf file is not what expected */ + if (cv) { + status = jar_signal(JAR_ERR_HASH, jar, path, x_name); - /* check for sha1 consistency */ - if (dig->sha1_status) - { - cv = PORT_Memcmp (savdig->sha1, dig->sha1, SHA1_LENGTH); - /* sha1 hash of .mf file is not what expected */ - if (cv) - { - status = jar_signal (JAR_ERR_HASH, jar, path, x_name); - - /* bad hash, man */ - - dig->sha1_status = jarHashBad; - savdig->sha1_status = jarHashBad; - - if (status < 0) - return 0; /* was continue; */ - else - return status; - } + /* bad hash, man */ + dig->sha1_status = jarHashBad; + savdig->sha1_status = jarHashBad; + + if (status < 0) + return 0; /* was continue; */ + return status; + } } - return 0; - } + return 0; +} #ifdef DEBUG /* @@ -777,26 +665,22 @@ static int jar_internal_digest * in the manifest files, to detect potential memory * corruption by our neighbors. Debug only, since * not I18N safe. - * + * */ - -static int jar_insanity_check (char ZHUGEP *data, long length) - { - int c; - long off; - - for (off = 0; off < length; off++) - { - c = data [off]; - - if (c == '\n' || c == '\r' || (c >= ' ' && c <= 128)) - continue; - - return JAR_ERR_CORRUPT; +static int +jar_insanity_check(char *data, long length) +{ + int c; + long off; + + for (off = 0; off < length; off++) { + c = data [off]; + if (c == '\n' || c == '\r' || (c >= ' ' && c <= 128)) + continue; + return JAR_ERR_CORRUPT; } - - return 0; - } + return 0; +} #endif /* @@ -806,158 +690,134 @@ static int jar_insanity_check (char ZHUGEP *data, long length) * Right now everything is PKCS7. * */ - -static int jar_parse_digital_signature - (char *raw_manifest, JAR_Signer *signer, long length, JAR *jar) - { - return jar_validate_pkcs7 (jar, signer, raw_manifest, length); - } +static int +jar_parse_digital_signature(char *raw_manifest, JAR_Signer *signer, + long length, JAR *jar) +{ + return jar_validate_pkcs7 (jar, signer, raw_manifest, length); +} /* * j a r _ a d d _ c e r t - * + * * Add information for the given certificate * (or whatever) to the JAR linked list. A pointer * is passed for some relevant reference, say * for example the original certificate. * */ - -static int jar_add_cert - (JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert) - { - JAR_Cert *fing; - unsigned char *keyData; - - if (cert == NULL) - return JAR_ERR_ORDER; - - fing = (JAR_Cert*)PORT_ZAlloc (sizeof (JAR_Cert)); - - if (fing == NULL) - goto loser; - - fing->cert = CERT_DupCertificate (cert); - - /* get the certkey */ - - fing->length = cert->derIssuer.len + 2 + cert->serialNumber.len; - - keyData = (unsigned char *) PORT_ZAlloc (fing->length); - fing->key = keyData; - - if (fing->key == NULL) - goto loser; - keyData[0] = ((cert->derIssuer.len) >> 8) & 0xff; - keyData[1] = ((cert->derIssuer.len) & 0xff); - PORT_Memcpy (&keyData[2], cert->derIssuer.data, cert->derIssuer.len); - PORT_Memcpy (&keyData[2+cert->derIssuer.len], cert->serialNumber.data, - cert->serialNumber.len); - - ADDITEM (signer->certs, type, - /* pathname */ NULL, fing, sizeof (JAR_Cert)); - - return 0; +static int +jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert) +{ + JAR_Cert *fing; + unsigned char *keyData; + + if (cert == NULL) + return JAR_ERR_ORDER; + + fing = PORT_ZNew(JAR_Cert); + if (fing == NULL) + goto loser; + + fing->cert = CERT_DupCertificate (cert); + + /* get the certkey */ + fing->length = cert->derIssuer.len + 2 + cert->serialNumber.len; + fing->key = keyData = (unsigned char *) PORT_ZAlloc(fing->length); + if (fing->key == NULL) + goto loser; + keyData[0] = ((cert->derIssuer.len) >> 8) & 0xff; + keyData[1] = ((cert->derIssuer.len) & 0xff); + PORT_Memcpy(&keyData[2], cert->derIssuer.data, cert->derIssuer.len); + PORT_Memcpy(&keyData[2+cert->derIssuer.len], cert->serialNumber.data, + cert->serialNumber.len); + + ADDITEM (signer->certs, type, NULL, fing, sizeof (JAR_Cert)); + return 0; loser: - - if (fing) - { - if (fing->cert) - CERT_DestroyCertificate (fing->cert); - - PORT_Free (fing); + if (fing) { + if (fing->cert) + CERT_DestroyCertificate (fing->cert); + PORT_Free(fing); } - - return JAR_ERR_MEMORY; - } + return JAR_ERR_MEMORY; +} /* - * e a t _ l i n e - * - * Consume an ascii line from the top of a file kept - * in memory. This destroys the file in place. This function - * handles PC, Mac, and Unix style text files. + * e a t _ l i n e * + * Consume an ASCII line from the top of a file kept in memory. + * This destroys the file in place. + * This function handles PC, Mac, and Unix style text files. */ +static char * +jar_eat_line(int lines, int eating, char *data, long *len) +{ + char *ret; -static char ZHUGEP *jar_eat_line - (int lines, int eating, char ZHUGEP *data, long *len) - { - char ZHUGEP *ret; - - ret = data; - if (!*len) return ret; - - /* Eat the requisite number of lines, if any; - prior to terminating the current line with a 0. */ - - for (/* yip */ ; lines; lines--) - { - while (*data && *data != '\n') - data++; + ret = data; + if (!*len) + return ret; - /* After the CR, ok to eat one LF */ + /* Eat the requisite number of lines, if any; + prior to terminating the current line with a 0. */ - if (*data == '\n') - data++; + for (/* yip */ ; lines; lines--) { + while (*data && *data != '\n') + data++; - /* If there are zeros, we put them there */ + /* After the CR, ok to eat one LF */ + if (*data == '\n') + data++; - while (*data == 0 && data - ret < *len) - data++; + /* If there are zeros, we put them there */ + while (*data == 0 && data - ret < *len) + data++; } - *len -= data - ret; - ret = data; - - if (eating) - { - /* Terminate this line with a 0 */ - - while (*data && *data != '\n' && *data != '\r') - data++; - - /* In any case we are allowed to eat CR */ + *len -= data - ret; + ret = data; - if (*data == '\r') - *data++ = 0; + if (eating) { + /* Terminate this line with a 0 */ + while (*data && *data != '\n' && *data != '\r') + data++; - /* After the CR, ok to eat one LF */ + /* In any case we are allowed to eat CR */ + if (*data == '\r') + *data++ = 0; - if (*data == '\n') - *data++ = 0; + /* After the CR, ok to eat one LF */ + if (*data == '\n') + *data++ = 0; } - - return ret; - } + return ret; +} /* * j a r _ d i g e s t _ s e c t i o n * * Return the digests of the next section of the manifest file. * Does not damage the manifest file, unlike parse_manifest. - * + * */ +static JAR_Digest * +jar_digest_section(char *manifest, long length) +{ + long global_len; + char *global_end; -static JAR_Digest *jar_digest_section - (char ZHUGEP *manifest, long length) - { - long global_len; - char ZHUGEP *global_end; - - global_end = manifest; - global_len = length; + global_end = manifest; + global_len = length; - while (global_len) - { - global_end = jar_eat_line (1, PR_FALSE, global_end, &global_len); - if (*global_end == 0 || *global_end == '\n') - break; + while (global_len) { + global_end = jar_eat_line(1, PR_FALSE, global_end, &global_len); + if (*global_end == 0 || *global_end == '\n') + break; } - - return JAR_calculate_digest (manifest, global_end - manifest); - } + return JAR_calculate_digest (manifest, global_end - manifest); +} /* * J A R _ v e r i f y _ d i g e s t @@ -966,276 +826,280 @@ static JAR_Digest *jar_digest_section * expected value in the manifest. * */ +int PR_CALLBACK +JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig) +{ + JAR_Item *it; + JAR_Digest *shindig; + ZZLink *link; + ZZList *list = jar->hashes; + int result1 = 0; + int result2 = 0; -int PR_CALLBACK JAR_verify_digest - (JAR *jar, const char *name, JAR_Digest *dig) - { - JAR_Item *it; - - JAR_Digest *shindig; - - ZZLink *link; - ZZList *list; - - int result1, result2; - - list = jar->hashes; - - result1 = result2 = 0; - if (jar->valid < 0) - { - /* signature not valid */ - return JAR_ERR_SIG; + if (jar->valid < 0) { + /* signature not valid */ + return JAR_ERR_SIG; } - - if (ZZ_ListEmpty (list)) - { - /* empty list */ - return JAR_ERR_PNF; + if (ZZ_ListEmpty (list)) { + /* empty list */ + return JAR_ERR_PNF; } - for (link = ZZ_ListHead (list); - !ZZ_ListIterDone (list, link); - link = link->next) - { - it = link->thing; - if (it->type == jarTypeMF - && it->pathname && !PORT_Strcmp (it->pathname, name)) - { - shindig = (JAR_Digest *) it->data; - - if (shindig->md5_status) - { - if (shindig->md5_status == jarHashBad) - return JAR_ERR_HASH; - else - result1 = memcmp (dig->md5, shindig->md5, MD5_LENGTH); - } - - if (shindig->sha1_status) - { - if (shindig->sha1_status == jarHashBad) - return JAR_ERR_HASH; - else - result2 = memcmp (dig->sha1, shindig->sha1, SHA1_LENGTH); - } - - return (result1 == 0 && result2 == 0) ? 0 : JAR_ERR_HASH; - } + for (link = ZZ_ListHead (list); + !ZZ_ListIterDone (list, link); + link = link->next) { + it = link->thing; + if (it->type == jarTypeMF + && it->pathname && !PORT_Strcmp(it->pathname, name)) { + shindig = (JAR_Digest *) it->data; + if (shindig->md5_status) { + if (shindig->md5_status == jarHashBad) + return JAR_ERR_HASH; + result1 = memcmp (dig->md5, shindig->md5, MD5_LENGTH); + } + if (shindig->sha1_status) { + if (shindig->sha1_status == jarHashBad) + return JAR_ERR_HASH; + result2 = memcmp (dig->sha1, shindig->sha1, SHA1_LENGTH); + } + return (result1 == 0 && result2 == 0) ? 0 : JAR_ERR_HASH; + } } + return JAR_ERR_PNF; +} - return JAR_ERR_PNF; - } - -/* +/* * J A R _ c e r t _ a t t r i b u t e * * Return the named certificate attribute from the * certificate specified by the given key. * */ - -int PR_CALLBACK JAR_cert_attribute - (JAR *jar, jarCert attrib, long keylen, void *key, - void **result, unsigned long *length) - { - int status = 0; - char *ret = NULL; - - CERTCertificate *cert; - - CERTCertDBHandle *certdb; - - JAR_Digest *dig; - SECItem hexme; - - *length = 0; - - if (attrib == 0 || key == 0) - return JAR_ERR_GENERAL; - - if (attrib == jarCertJavaHack) - { - cert = (CERTCertificate *) NULL; - certdb = JAR_open_database(); - - if (certdb) - { - cert = CERT_FindCertByNickname (certdb, key); - - if (cert) - { - *length = cert->certKey.len; - - *result = (void *) PORT_ZAlloc (*length); - - if (*result) - PORT_Memcpy (*result, cert->certKey.data, *length); - else - { - JAR_close_database (certdb); - return JAR_ERR_MEMORY; - } - } - JAR_close_database (certdb); - } - - return cert ? 0 : JAR_ERR_GENERAL; +int PR_CALLBACK +JAR_cert_attribute(JAR *jar, jarCert attrib, long keylen, void *key, + void **result, unsigned long *length) +{ + int status = 0; + char *ret = NULL; + CERTCertificate *cert; + CERTCertDBHandle *certdb; + JAR_Digest *dig; + SECItem hexme; + + *length = 0; + + if (attrib == 0 || key == 0) + return JAR_ERR_GENERAL; + + if (attrib == jarCertJavaHack) { + cert = (CERTCertificate *) NULL; + certdb = JAR_open_database(); + + if (certdb) { + cert = CERT_FindCertByNickname (certdb, key); + if (cert) { + *length = cert->certKey.len; + *result = (void *) PORT_ZAlloc(*length); + if (*result) + PORT_Memcpy(*result, cert->certKey.data, *length); + else { + JAR_close_database (certdb); + return JAR_ERR_MEMORY; + } + } + JAR_close_database (certdb); + } + return cert ? 0 : JAR_ERR_GENERAL; } - if (jar && jar->pkcs7 == 0) - return JAR_ERR_GENERAL; - - cert = jar_get_certificate (jar, keylen, key, &status); + if (jar && jar->pkcs7 == 0) + return JAR_ERR_GENERAL; - if (cert == NULL || status < 0) - return JAR_ERR_GENERAL; + cert = jar_get_certificate(jar, keylen, key, &status); + if (cert == NULL || status < 0) + return JAR_ERR_GENERAL; #define SEP " <br> " #define SEPLEN (PORT_Strlen(SEP)) - switch (attrib) - { + switch (attrib) { case jarCertCompany: - - ret = cert->subjectName; - - /* This is pretty ugly looking but only used - here for this one purpose. */ - - if (ret) - { - int retlen = 0; - - char *cer_ou1, *cer_ou2, *cer_ou3; - char *cer_cn, *cer_e, *cer_o, *cer_l; - - cer_cn = CERT_GetCommonName (&cert->subject); - cer_e = CERT_GetCertEmailAddress (&cert->subject); - cer_ou3 = jar_cert_element (ret, "OU=", 3); - cer_ou2 = jar_cert_element (ret, "OU=", 2); - cer_ou1 = jar_cert_element (ret, "OU=", 1); - cer_o = CERT_GetOrgName (&cert->subject); - cer_l = CERT_GetCountryName (&cert->subject); - - if (cer_cn) retlen += SEPLEN + PORT_Strlen (cer_cn); - if (cer_e) retlen += SEPLEN + PORT_Strlen (cer_e); - if (cer_ou1) retlen += SEPLEN + PORT_Strlen (cer_ou1); - if (cer_ou2) retlen += SEPLEN + PORT_Strlen (cer_ou2); - if (cer_ou3) retlen += SEPLEN + PORT_Strlen (cer_ou3); - if (cer_o) retlen += SEPLEN + PORT_Strlen (cer_o); - if (cer_l) retlen += SEPLEN + PORT_Strlen (cer_l); - - ret = (char *) PORT_ZAlloc (1 + retlen); - - if (cer_cn) { PORT_Strcpy (ret, cer_cn); PORT_Strcat (ret, SEP); } - if (cer_e) { PORT_Strcat (ret, cer_e); PORT_Strcat (ret, SEP); } - if (cer_ou1) { PORT_Strcat (ret, cer_ou1); PORT_Strcat (ret, SEP); } - if (cer_ou2) { PORT_Strcat (ret, cer_ou2); PORT_Strcat (ret, SEP); } - if (cer_ou3) { PORT_Strcat (ret, cer_ou3); PORT_Strcat (ret, SEP); } - if (cer_o) { PORT_Strcat (ret, cer_o); PORT_Strcat (ret, SEP); } - if (cer_l) PORT_Strcat (ret, cer_l); - - /* return here to avoid unsightly memory leak */ - - *result = ret; - *length = PORT_Strlen (ret); - - return 0; - } - break; + ret = cert->subjectName; + + /* This is pretty ugly looking but only used + here for this one purpose. */ + if (ret) { + int retlen = 0; + + char *cer_ou1, *cer_ou2, *cer_ou3; + char *cer_cn, *cer_e, *cer_o, *cer_l; + + cer_cn = CERT_GetCommonName (&cert->subject); + cer_e = CERT_GetCertEmailAddress (&cert->subject); + cer_ou3 = jar_cert_element(ret, "OU=", 3); + cer_ou2 = jar_cert_element(ret, "OU=", 2); + cer_ou1 = jar_cert_element(ret, "OU=", 1); + cer_o = CERT_GetOrgName (&cert->subject); + cer_l = CERT_GetCountryName (&cert->subject); + + if (cer_cn) + retlen += SEPLEN + PORT_Strlen(cer_cn); + if (cer_e) + retlen += SEPLEN + PORT_Strlen(cer_e); + if (cer_ou1) + retlen += SEPLEN + PORT_Strlen(cer_ou1); + if (cer_ou2) + retlen += SEPLEN + PORT_Strlen(cer_ou2); + if (cer_ou3) + retlen += SEPLEN + PORT_Strlen(cer_ou3); + if (cer_o) + retlen += SEPLEN + PORT_Strlen(cer_o); + if (cer_l) + retlen += SEPLEN + PORT_Strlen(cer_l); + + ret = (char *) PORT_ZAlloc(1 + retlen); + + if (cer_cn) { + PORT_Strcpy(ret, cer_cn); + PORT_Strcat(ret, SEP); + } + if (cer_e) { + PORT_Strcat(ret, cer_e); + PORT_Strcat(ret, SEP); + } + if (cer_ou1) { + PORT_Strcat(ret, cer_ou1); + PORT_Strcat(ret, SEP); + } + if (cer_ou2) { + PORT_Strcat(ret, cer_ou2); + PORT_Strcat(ret, SEP); + } + if (cer_ou3) { + PORT_Strcat(ret, cer_ou3); + PORT_Strcat(ret, SEP); + } + if (cer_o) { + PORT_Strcat(ret, cer_o); + PORT_Strcat(ret, SEP); + } + if (cer_l) + PORT_Strcat(ret, cer_l); + + /* return here to avoid unsightly memory leak */ + *result = ret; + *length = PORT_Strlen(ret); + CERT_DestroyCertificate(cert); + return 0; + } + break; case jarCertCA: - - ret = cert->issuerName; - - if (ret) - { - int retlen = 0; - - char *cer_ou1, *cer_ou2, *cer_ou3; - char *cer_cn, *cer_e, *cer_o, *cer_l; - - /* This is pretty ugly looking but only used - here for this one purpose. */ - - cer_cn = CERT_GetCommonName (&cert->issuer); - cer_e = CERT_GetCertEmailAddress (&cert->issuer); - cer_ou3 = jar_cert_element (ret, "OU=", 3); - cer_ou2 = jar_cert_element (ret, "OU=", 2); - cer_ou1 = jar_cert_element (ret, "OU=", 1); - cer_o = CERT_GetOrgName (&cert->issuer); - cer_l = CERT_GetCountryName (&cert->issuer); - - if (cer_cn) retlen += SEPLEN + PORT_Strlen (cer_cn); - if (cer_e) retlen += SEPLEN + PORT_Strlen (cer_e); - if (cer_ou1) retlen += SEPLEN + PORT_Strlen (cer_ou1); - if (cer_ou2) retlen += SEPLEN + PORT_Strlen (cer_ou2); - if (cer_ou3) retlen += SEPLEN + PORT_Strlen (cer_ou3); - if (cer_o) retlen += SEPLEN + PORT_Strlen (cer_o); - if (cer_l) retlen += SEPLEN + PORT_Strlen (cer_l); - - ret = (char *) PORT_ZAlloc (1 + retlen); - - if (cer_cn) { PORT_Strcpy (ret, cer_cn); PORT_Strcat (ret, SEP); } - if (cer_e) { PORT_Strcat (ret, cer_e); PORT_Strcat (ret, SEP); } - if (cer_ou1) { PORT_Strcat (ret, cer_ou1); PORT_Strcat (ret, SEP); } - if (cer_ou2) { PORT_Strcat (ret, cer_ou2); PORT_Strcat (ret, SEP); } - if (cer_ou3) { PORT_Strcat (ret, cer_ou3); PORT_Strcat (ret, SEP); } - if (cer_o) { PORT_Strcat (ret, cer_o); PORT_Strcat (ret, SEP); } - if (cer_l) PORT_Strcat (ret, cer_l); - - /* return here to avoid unsightly memory leak */ - - *result = ret; - *length = PORT_Strlen (ret); - - return 0; - } - - break; + ret = cert->issuerName; + if (ret) { + int retlen = 0; + + char *cer_ou1, *cer_ou2, *cer_ou3; + char *cer_cn, *cer_e, *cer_o, *cer_l; + + /* This is pretty ugly looking but only used + here for this one purpose. */ + + cer_cn = CERT_GetCommonName (&cert->issuer); + cer_e = CERT_GetCertEmailAddress (&cert->issuer); + cer_ou3 = jar_cert_element(ret, "OU=", 3); + cer_ou2 = jar_cert_element(ret, "OU=", 2); + cer_ou1 = jar_cert_element(ret, "OU=", 1); + cer_o = CERT_GetOrgName (&cert->issuer); + cer_l = CERT_GetCountryName (&cert->issuer); + + if (cer_cn) + retlen += SEPLEN + PORT_Strlen(cer_cn); + if (cer_e) + retlen += SEPLEN + PORT_Strlen(cer_e); + if (cer_ou1) + retlen += SEPLEN + PORT_Strlen(cer_ou1); + if (cer_ou2) + retlen += SEPLEN + PORT_Strlen(cer_ou2); + if (cer_ou3) + retlen += SEPLEN + PORT_Strlen(cer_ou3); + if (cer_o) + retlen += SEPLEN + PORT_Strlen(cer_o); + if (cer_l) + retlen += SEPLEN + PORT_Strlen(cer_l); + + ret = (char *) PORT_ZAlloc(1 + retlen); + + if (cer_cn) { + PORT_Strcpy(ret, cer_cn); + PORT_Strcat(ret, SEP); + } + if (cer_e) { + PORT_Strcat(ret, cer_e); + PORT_Strcat(ret, SEP); + } + if (cer_ou1) { + PORT_Strcat(ret, cer_ou1); + PORT_Strcat(ret, SEP); + } + if (cer_ou2) { + PORT_Strcat(ret, cer_ou2); + PORT_Strcat(ret, SEP); + } + if (cer_ou3) { + PORT_Strcat(ret, cer_ou3); + PORT_Strcat(ret, SEP); + } + if (cer_o) { + PORT_Strcat(ret, cer_o); + PORT_Strcat(ret, SEP); + } + if (cer_l) + PORT_Strcat(ret, cer_l); + + /* return here to avoid unsightly memory leak */ + *result = ret; + *length = PORT_Strlen(ret); + CERT_DestroyCertificate(cert); + return 0; + } + break; case jarCertSerial: - - ret = CERT_Hexify (&cert->serialNumber, 1); - break; + ret = CERT_Hexify (&cert->serialNumber, 1); + break; case jarCertExpires: - - ret = DER_UTCDayToAscii (&cert->validity.notAfter); - break; + ret = DER_UTCDayToAscii (&cert->validity.notAfter); + break; case jarCertNickname: - - ret = jar_choose_nickname (cert); - break; + ret = jar_choose_nickname(cert); + break; case jarCertFinger: - - dig = JAR_calculate_digest - ((char *) cert->derCert.data, cert->derCert.len); - - if (dig) - { - hexme.len = sizeof (dig->md5); - hexme.data = dig->md5; - ret = CERT_Hexify (&hexme, 1); - } - break; + dig = JAR_calculate_digest((char *) cert->derCert.data, + cert->derCert.len); + if (dig) { + hexme.len = sizeof (dig->md5); + hexme.data = dig->md5; + ret = CERT_Hexify (&hexme, 1); + } + break; default: - - return JAR_ERR_GENERAL; + CERT_DestroyCertificate(cert); + return JAR_ERR_GENERAL; } - *result = ret ? PORT_Strdup (ret) : NULL; - *length = ret ? PORT_Strlen (ret) : 0; - - return 0; - } + *result = ret ? PORT_Strdup(ret) : NULL; + *length = ret ? PORT_Strlen(ret) : 0; + CERT_DestroyCertificate(cert); + return 0; +} -/* +/* * j a r _ c e r t _ e l e m e n t * * Retrieve an element from an x400ish ascii @@ -1243,134 +1107,93 @@ int PR_CALLBACK JAR_cert_attribute * thing would probably be to sort AVATags. * */ +static char * +jar_cert_element(char *name, char *tag, int occ) +{ + if (name && tag) { + char *s; + int found = 0; + while (occ--) { + if (PORT_Strstr(name, tag)) { + name = PORT_Strstr(name, tag) + PORT_Strlen (tag); + found = 1; + } else { + name = PORT_Strstr(name, "="); + if (name == NULL) return NULL; + found = 0; + } + } + if (!found) + return NULL; -static char *jar_cert_element (char *name, char *tag, int occ) - { - if (name && tag) - { - char *s; - int found = 0; + /* must mangle only the copy */ + name = PORT_Strdup(name); - while (occ--) - { - if (PORT_Strstr (name, tag)) - { - name = PORT_Strstr (name, tag) + PORT_Strlen (tag); - found = 1; - } - else - { - name = PORT_Strstr (name, "="); - if (name == NULL) return NULL; - found = 0; - } - } - - if (!found) return NULL; - - /* must mangle only the copy */ - name = PORT_Strdup (name); - - /* advance to next equal */ - for (s = name; *s && *s != '='; s++) - /* yip */ ; - - /* back up to previous comma */ - while (s > name && *s != ',') s--; - - /* zap the whitespace and return */ - *s = 0; - } + /* advance to next equal */ + for (s = name; *s && *s != '='; s++) + /* yip */ ; + + /* back up to previous comma */ + while (s > name && *s != ',') + s--; - return name; - } + /* zap the whitespace and return */ + *s = 0; + } + return name; +} -/* +/* * j a r _ c h o o s e _ n i c k n a m e * * Attempt to determine a suitable nickname for - * a certificate with a computer-generated "tmpcertxxx" + * a certificate with a computer-generated "tmpcertxxx" * nickname. It needs to be something a user can * understand, so try a few things. * */ - -static char *jar_choose_nickname (CERTCertificate *cert) - { - char *cert_cn; - char *cert_o; - char *cert_cn_o; - - int cn_o_length; - - /* is the existing name ok */ - - if (cert->nickname && PORT_Strncmp (cert->nickname, "tmpcert", 7)) - return PORT_Strdup (cert->nickname); - - /* we have an ugly name here people */ - - /* Try the CN */ - cert_cn = CERT_GetCommonName (&cert->subject); - - if (cert_cn) - { - /* check for duplicate nickname */ - - if (CERT_FindCertByNickname (CERT_GetDefaultCertDB(), cert_cn) == NULL) - return cert_cn; - - /* Try the CN plus O */ - cert_o = CERT_GetOrgName (&cert->subject); - - cn_o_length = PORT_Strlen (cert_cn) + 3 + PORT_Strlen (cert_o) + 20; - cert_cn_o = (char*)PORT_ZAlloc (cn_o_length); - - PR_snprintf (cert_cn_o, cn_o_length, - "%s's %s Certificate", cert_cn, cert_o); - - if (CERT_FindCertByNickname (CERT_GetDefaultCertDB(), cert_cn_o) == NULL) - { - PORT_Free (cert_cn_o); - return cert_cn; - } - PORT_Free (cert_cn_o); +static char * +jar_choose_nickname(CERTCertificate *cert) +{ + char *cert_cn; + char *cert_o; + char *cert_cn_o; + int cn_o_length; + + /* is the existing name ok */ + if (cert->nickname && PORT_Strncmp(cert->nickname, "tmpcert", 7)) + return PORT_Strdup(cert->nickname); + + /* Try the CN */ + cert_cn = CERT_GetCommonName(&cert->subject); + if (cert_cn) { + CERTCertificate *cert1; + /* check for duplicate nickname */ + cert1 = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), cert_cn); + if (cert1 == NULL) + return cert_cn; + CERT_DestroyCertificate(cert1); cert1 = NULL; + + /* Try the CN plus O */ + cert_o = CERT_GetOrgName (&cert->subject); + /* XXX: Get Yer Magic Numbers here! */ + cn_o_length = PORT_Strlen(cert_cn) + 3 + PORT_Strlen (cert_o) + 20; + cert_cn_o = (char*)PORT_ZAlloc(cn_o_length); + PR_snprintf(cert_cn_o, cn_o_length, "%s's %s Certificate", + cert_cn, cert_o); + + cert1 = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), cert_cn_o); + if (cert1 == NULL) { + PORT_Free(cert_cn_o); + return cert_cn; + } + CERT_DestroyCertificate(cert1); cert1 = NULL; + PORT_Free(cert_cn_o); } - /* If all that failed, use the ugly nickname */ - return cert->nickname ? PORT_Strdup (cert->nickname) : NULL; - } - -/* - * J A R _ c e r t _ h t m l - * - * Return an HTML representation of the certificate - * designated by the given fingerprint, in specified style. - * - * JAR is optional, but supply it if you can in order - * to optimize. - * - */ - -char *JAR_cert_html - (JAR *jar, int style, long keylen, void *key, int *result) - { - CERTCertificate *cert; - - *result = -1; - - if (style != 0) - return NULL; - - cert = jar_get_certificate (jar, keylen, key, result); - - if (cert == NULL || *result < 0) - return NULL; - - *result = -1; - - return NULL; - } + /* If all that failed, use the ugly nickname */ + return cert->nickname ? PORT_Strdup(cert->nickname) : NULL; +} /* * J A R _ s t a s h _ c e r t @@ -1379,136 +1202,106 @@ char *JAR_cert_html * fingerprint, in persistent storage somewhere. * */ - -extern int PR_CALLBACK JAR_stash_cert - (JAR *jar, long keylen, void *key) - { - int result = 0; - - char *nickname; - CERTCertTrust trust; - - CERTCertDBHandle *certdb; - CERTCertificate *cert, *newcert; - - cert = jar_get_certificate (jar, keylen, key, &result); - - if (result < 0) - return result; - - if (cert == NULL) - return JAR_ERR_GENERAL; - - if ((certdb = JAR_open_database()) == NULL) - return JAR_ERR_GENERAL; - - /* Attempt to give a name to the newish certificate */ - nickname = jar_choose_nickname (cert); - - newcert = CERT_FindCertByNickname (certdb, nickname); - - if (newcert && newcert->isperm) - { - /* already in permanant database */ - JAR_close_database (certdb); - return 0; +int PR_CALLBACK +JAR_stash_cert(JAR *jar, long keylen, void *key) +{ + int result = 0; + char *nickname; + CERTCertTrust trust; + CERTCertDBHandle *certdb; + CERTCertificate *cert, *newcert; + + cert = jar_get_certificate(jar, keylen, key, &result); + if (cert == NULL) + return JAR_ERR_GENERAL; + + if ((certdb = JAR_open_database()) == NULL) + return JAR_ERR_GENERAL; + + /* Attempt to give a name to the newish certificate */ + nickname = jar_choose_nickname(cert); + newcert = CERT_FindCertByNickname(certdb, nickname); + if (newcert && newcert->isperm) { + /* already in permanent database */ + CERT_DestroyCertificate(newcert); + JAR_close_database (certdb); + return 0; } - - if (newcert) cert = newcert; - - /* FIX, since FindCert returns a bogus dbhandle - set it ourselves */ - - cert->dbhandle = certdb; - - if (nickname != NULL) - { - PORT_Memset ((void *) &trust, 0, sizeof(trust)); - - if (CERT_AddTempCertToPerm (cert, nickname, &trust) != SECSuccess) - { - /* XXX might want to call PORT_GetError here */ - result = JAR_ERR_GENERAL; - } + if (newcert) { + CERT_DestroyCertificate(cert); + cert = newcert; } - - JAR_close_database (certdb); - - return result; - } + if (nickname != NULL) { + PORT_Memset((void *) &trust, 0, sizeof(trust)); + if (CERT_AddTempCertToPerm (cert, nickname, &trust) != SECSuccess) { + /* XXX might want to call PORT_GetError here */ + result = JAR_ERR_GENERAL; + } + } + CERT_DestroyCertificate(cert); + JAR_close_database(certdb); + return result; +} /* * J A R _ f e t c h _ c e r t * - * Given an opaque identifier of a certificate, + * Given an opaque identifier of a certificate, * return the full certificate. * * The new function, which retrieves by key. * */ +CERTCertificate * +JAR_fetch_cert(long length, void *key) +{ + CERTIssuerAndSN issuerSN; + CERTCertificate *cert = NULL; + CERTCertDBHandle *certdb; -void *JAR_fetch_cert (long length, void *key) - { - CERTIssuerAndSN issuerSN; - CERTCertificate *cert = NULL; - - CERTCertDBHandle *certdb; - - certdb = JAR_open_database(); - - if (certdb) - { - unsigned char *keyData = (unsigned char *)key; - issuerSN.derIssuer.len = (keyData[0] << 8) + keyData[0]; - issuerSN.derIssuer.data = &keyData[2]; - issuerSN.serialNumber.len = length - (2 + issuerSN.derIssuer.len); - issuerSN.serialNumber.data = &keyData[2+issuerSN.derIssuer.len]; - - cert = CERT_FindCertByIssuerAndSN (certdb, &issuerSN); - - JAR_close_database (certdb); + certdb = JAR_open_database(); + if (certdb) { + unsigned char *keyData = (unsigned char *)key; + issuerSN.derIssuer.len = (keyData[0] << 8) + keyData[0]; + issuerSN.derIssuer.data = &keyData[2]; + issuerSN.serialNumber.len = length - (2 + issuerSN.derIssuer.len); + issuerSN.serialNumber.data = &keyData[2+issuerSN.derIssuer.len]; + cert = CERT_FindCertByIssuerAndSN (certdb, &issuerSN); + JAR_close_database (certdb); } - - return (void *) cert; - } + return cert; +} /* * j a r _ g e t _ m f _ d i g e s t * * Retrieve a corresponding saved digest over a section - * of the main manifest file. + * of the main manifest file. * */ - -static JAR_Digest *jar_get_mf_digest (JAR *jar, char *pathname) - { - JAR_Item *it; - - JAR_Digest *dig; - - ZZLink *link; - ZZList *list; - - list = jar->manifest; - - if (ZZ_ListEmpty (list)) - return NULL; - - for (link = ZZ_ListHead (list); - !ZZ_ListIterDone (list, link); - link = link->next) - { - it = link->thing; - if (it->type == jarTypeSect - && it->pathname && !PORT_Strcmp (it->pathname, pathname)) - { - dig = (JAR_Digest *) it->data; - return dig; - } +static JAR_Digest * +jar_get_mf_digest(JAR *jar, char *pathname) +{ + JAR_Item *it; + JAR_Digest *dig; + ZZLink *link; + ZZList *list = jar->manifest; + + if (ZZ_ListEmpty (list)) + return NULL; + + for (link = ZZ_ListHead (list); + !ZZ_ListIterDone (list, link); + link = link->next) { + it = link->thing; + if (it->type == jarTypeSect + && it->pathname && !PORT_Strcmp(it->pathname, pathname)) { + dig = (JAR_Digest *) it->data; + return dig; + } } - - return NULL; - } + return NULL; +} /* * j a r _ b a s e n a m e @@ -1517,43 +1310,39 @@ static JAR_Digest *jar_get_mf_digest (JAR *jar, char *pathname) * extension ripped off -- of a path. * */ - -static char *jar_basename (const char *path) - { - char *pith, *e, *basename, *ext; - - if (path == NULL) - return PORT_Strdup (""); - - pith = PORT_Strdup (path); - - basename = pith; - - while (1) - { - for (e = basename; *e && *e != '/' && *e != '\\'; e++) - /* yip */ ; - if (*e) - basename = ++e; - else - break; +static char * +jar_basename(const char *path) +{ + char *pith, *e, *basename, *ext; + + if (path == NULL) + return PORT_Strdup(""); + + pith = PORT_Strdup(path); + basename = pith; + while (1) { + for (e = basename; *e && *e != '/' && *e != '\\'; e++) + /* yip */ ; + if (*e) + basename = ++e; + else + break; } - if ((ext = PORT_Strrchr (basename, '.')) != NULL) - *ext = 0; + if ((ext = PORT_Strrchr(basename, '.')) != NULL) + *ext = 0; - /* We already have the space allocated */ - PORT_Strcpy (pith, basename); - - return pith; - } + /* We already have the space allocated */ + PORT_Strcpy(pith, basename); + return pith; +} /* * + + + + + + + + + + + + + + + * * CRYPTO ROUTINES FOR JAR * - * The following functions are the cryptographic + * The following functions are the cryptographic * interface to PKCS7 for Jarnatures. * * + + + + + + + + + + + + + + + @@ -1567,13 +1356,12 @@ static char *jar_basename (const char *path) * But note that the lib/pkcs7 routines aren't ready for it. * */ - -static void jar_catch_bytes - (void *arg, const char *buf, unsigned long len) - { - /* Actually this should never be called, since there is - presumably no data in the signature itself. */ - } +static void +jar_catch_bytes(void *arg, const char *buf, unsigned long len) +{ + /* Actually this should never be called, since there is + presumably no data in the signature itself. */ +} /* * j a r _ v a l i d a t e _ p k c s 7 @@ -1582,96 +1370,72 @@ static void jar_catch_bytes * signature in DER format. * */ - -static int jar_validate_pkcs7 - (JAR *jar, JAR_Signer *signer, char *data, long length) +static int +jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length) { - SEC_PKCS7ContentInfo *cinfo = NULL; - SEC_PKCS7DecoderContext *dcx; - PRBool goodSig; - int status = 0; - SECItem detdig; - - PORT_Assert( jar != NULL && signer != NULL ); + SEC_PKCS7ContentInfo *cinfo = NULL; + SEC_PKCS7DecoderContext *dcx; + PRBool goodSig; + int status = 0; + SECItem detdig; - if (jar == NULL || signer == NULL) - return JAR_ERR_ORDER; + PORT_Assert( jar != NULL && signer != NULL ); - signer->valid = JAR_ERR_SIG; + if (jar == NULL || signer == NULL) + return JAR_ERR_ORDER; - /* We need a context if we can get one */ + signer->valid = JAR_ERR_SIG; -#ifdef MOZILLA_CLIENT_OLD - if (jar->mw == NULL) { - JAR_set_context (jar, NULL); - } -#endif - - - dcx = SEC_PKCS7DecoderStart - (jar_catch_bytes, NULL /*cb_arg*/, NULL /*getpassword*/, jar->mw, - NULL, NULL, NULL); - - if (dcx == NULL) - { - /* strange pkcs7 failure */ - return JAR_ERR_PK7; + /* We need a context if we can get one */ + dcx = SEC_PKCS7DecoderStart(jar_catch_bytes, NULL /*cb_arg*/, + NULL /*getpassword*/, jar->mw, + NULL, NULL, NULL); + if (dcx == NULL) { + /* strange pkcs7 failure */ + return JAR_ERR_PK7; } - SEC_PKCS7DecoderUpdate (dcx, data, length); - cinfo = SEC_PKCS7DecoderFinish (dcx); - - if (cinfo == NULL) - { - /* strange pkcs7 failure */ - return JAR_ERR_PK7; + SEC_PKCS7DecoderUpdate (dcx, data, length); + cinfo = SEC_PKCS7DecoderFinish (dcx); + if (cinfo == NULL) { + /* strange pkcs7 failure */ + return JAR_ERR_PK7; } - - if (SEC_PKCS7ContentIsEncrypted (cinfo)) - { - /* content was encrypted, fail */ - return JAR_ERR_PK7; + if (SEC_PKCS7ContentIsEncrypted (cinfo)) { + /* content was encrypted, fail */ + return JAR_ERR_PK7; } - - if (SEC_PKCS7ContentIsSigned (cinfo) == PR_FALSE) - { - /* content was not signed, fail */ - return JAR_ERR_PK7; - } - - PORT_SetError (0); - - /* use SHA1 only */ - - detdig.len = SHA1_LENGTH; - detdig.data = signer->digest->sha1; - - goodSig = SEC_PKCS7VerifyDetachedSignature(cinfo, certUsageObjectSigner, - &detdig, HASH_AlgSHA1, PR_FALSE); - jar_gather_signers (jar, signer, cinfo); - if (goodSig == PR_TRUE) - { - /* signature is valid */ - signer->valid = 0; + if (SEC_PKCS7ContentIsSigned (cinfo) == PR_FALSE) { + /* content was not signed, fail */ + return JAR_ERR_PK7; } - else - { - status = PORT_GetError(); - PORT_Assert( status < 0 ); - if (status >= 0) status = JAR_ERR_SIG; - - jar->valid = status; - signer->valid = status; + PORT_SetError(0); + + /* use SHA1 only */ + detdig.len = SHA1_LENGTH; + detdig.data = signer->digest->sha1; + goodSig = SEC_PKCS7VerifyDetachedSignature(cinfo, + certUsageObjectSigner, + &detdig, HASH_AlgSHA1, + PR_FALSE); + jar_gather_signers(jar, signer, cinfo); + if (goodSig == PR_TRUE) { + /* signature is valid */ + signer->valid = 0; + } else { + status = PORT_GetError(); + PORT_Assert( status < 0 ); + if (status >= 0) + status = JAR_ERR_SIG; + jar->valid = status; + signer->valid = status; } - - jar->pkcs7 = PR_TRUE; - signer->pkcs7 = PR_TRUE; - - SEC_PKCS7DestroyContentInfo (cinfo); - - return status; + jar->pkcs7 = PR_TRUE; + signer->pkcs7 = PR_TRUE; + SEC_PKCS7DestroyContentInfo(cinfo); + return status; } /* @@ -1681,47 +1445,37 @@ static int jar_validate_pkcs7 * certificate linked list. * */ +static int +jar_gather_signers(JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo) +{ + int result; + CERTCertificate *cert; + CERTCertDBHandle *certdb; + SEC_PKCS7SignedData *sdp = cinfo->content.signedData; + SEC_PKCS7SignerInfo **pksigners, *pksigner; -static int jar_gather_signers - (JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo) - { - int result; - - CERTCertificate *cert; - CERTCertDBHandle *certdb; - - SEC_PKCS7SignedData *sdp; - SEC_PKCS7SignerInfo **pksigners, *pksigner; - - sdp = cinfo->content.signedData; - - if (sdp == NULL) - return JAR_ERR_PK7; - - pksigners = sdp->signerInfos; - - /* permit exactly one signer */ - - if (pksigners == NULL || pksigners [0] == NULL || pksigners [1] != NULL) - return JAR_ERR_PK7; - - pksigner = *pksigners; - cert = pksigner->cert; - - if (cert == NULL) - return JAR_ERR_PK7; + if (sdp == NULL) + return JAR_ERR_PK7; - certdb = JAR_open_database(); + pksigners = sdp->signerInfos; + /* permit exactly one signer */ + if (pksigners == NULL || pksigners [0] == NULL || pksigners [1] != NULL) + return JAR_ERR_PK7; - if (certdb == NULL) - return JAR_ERR_GENERAL; + pksigner = *pksigners; + cert = pksigner->cert; - result = jar_add_cert (jar, signer, jarTypeSign, cert); + if (cert == NULL) + return JAR_ERR_PK7; - JAR_close_database (certdb); + certdb = JAR_open_database(); + if (certdb == NULL) + return JAR_ERR_GENERAL; - return result; - } + result = jar_add_cert(jar, signer, jarTypeSign, cert); + JAR_close_database (certdb); + return result; +} /* * j a r _ o p e n _ d a t a b a s e @@ -1730,15 +1484,11 @@ static int jar_gather_signers * for use by JAR functions. * */ - -CERTCertDBHandle *JAR_open_database (void) - { - CERTCertDBHandle *certdb; - - certdb = CERT_GetDefaultCertDB(); - - return certdb; - } +CERTCertDBHandle * +JAR_open_database(void) +{ + return CERT_GetDefaultCertDB(); +} /* * j a r _ c l o s e _ d a t a b a s e @@ -1747,91 +1497,77 @@ CERTCertDBHandle *JAR_open_database (void) * For use by JAR functions. * */ - -int JAR_close_database (CERTCertDBHandle *certdb) - { - return 0; - } +int +JAR_close_database(CERTCertDBHandle *certdb) +{ + return 0; +} /* * j a r _ g e t _ c e r t i f i c a t e * - * Return the certificate referenced + * Return a new reference to the certificate indicated * by a given fingerprint, or NULL if not found. * Error code is returned in result. - * + * Caller must destroy this reference, if it is non-NULL! */ - -static CERTCertificate *jar_get_certificate - (JAR *jar, long keylen, void *key, int *result) - { - int found = 0; - - JAR_Item *it; - JAR_Cert *fing = NULL; - - JAR_Context *ctx; - - if (jar == NULL) - { - void *cert; - cert = JAR_fetch_cert (keylen, key); - *result = (cert == NULL) ? JAR_ERR_GENERAL : 0; - return (CERTCertificate *) cert; +static CERTCertificate * +jar_get_certificate(JAR *jar, long keylen, void *key, int *result) +{ + int found = 0; + JAR_Item *it; + JAR_Cert *fing = NULL; + JAR_Context *ctx; + + if (jar == NULL) { + CERTCertificate * cert = JAR_fetch_cert(keylen, key); + *result = (cert == NULL) ? JAR_ERR_GENERAL : 0; + return cert; } - ctx = JAR_find (jar, NULL, jarTypeSign); + ctx = JAR_find (jar, NULL, jarTypeSign); + while (JAR_find_next (ctx, &it) >= 0) { + fing = (JAR_Cert *) it->data; + if (keylen != fing->length) + continue; - while (JAR_find_next (ctx, &it) >= 0) - { - fing = (JAR_Cert *) it->data; - - if (keylen != fing->length) - continue; - - PORT_Assert( keylen < 0xFFFF ); - if (!PORT_Memcmp (fing->key, key, keylen)) - { - found = 1; - break; - } + PORT_Assert( keylen < 0xFFFF ); + if (!PORT_Memcmp(fing->key, key, keylen)) { + found = 1; + break; + } } - JAR_find_end (ctx); - - if (found == 0) - { - *result = JAR_ERR_GENERAL; - return NULL; + JAR_find_end (ctx); + if (found == 0) { + *result = JAR_ERR_GENERAL; + return NULL; } - PORT_Assert(fing != NULL); - *result = 0; - return fing->cert; - } + PORT_Assert(fing != NULL); + *result = 0; + /* XXX: is this a new reference or not? + * If not, then this needs to be changed to call CERT_DupCertificate! + */ + return fing->cert; +} /* * j a r _ s i g n a l * * Nonfatal errors come here to callback Java. - * + * */ - -static int jar_signal - (int status, JAR *jar, const char *metafile, char *pathname) - { - char *errstring; - - errstring = JAR_get_error (status); - - if (jar->signal) - { - (*jar->signal) (status, jar, metafile, pathname, errstring); - return 0; +static int +jar_signal(int status, JAR *jar, const char *metafile, char *pathname) +{ + char *errstring = JAR_get_error (status); + if (jar->signal) { + (*jar->signal) (status, jar, metafile, pathname, errstring); + return 0; } - - return status; - } + return status; +} /* * j a r _ a p p e n d @@ -1840,45 +1576,35 @@ static int jar_signal * lists, with rudimentary error handling. * */ +int +jar_append(ZZList *list, int type, char *pathname, void *data, size_t size) +{ + JAR_Item *it = PORT_ZNew(JAR_Item); + ZZLink *entity; -int jar_append (ZZList *list, int type, - char *pathname, void *data, size_t size) - { - JAR_Item *it; - ZZLink *entity; - - it = (JAR_Item*)PORT_ZAlloc (sizeof (JAR_Item)); - - if (it == NULL) - goto loser; + if (it == NULL) + goto loser; - if (pathname) - { - it->pathname = PORT_Strdup (pathname); - if (it->pathname == NULL) - goto loser; + if (pathname) { + it->pathname = PORT_Strdup(pathname); + if (it->pathname == NULL) + goto loser; } - it->type = (jarType)type; - it->data = (unsigned char *) data; - it->size = size; - - entity = ZZ_NewLink (it); - - if (entity) - { - ZZ_AppendLink (list, entity); - return 0; + it->type = (jarType)type; + it->data = (unsigned char *) data; + it->size = size; + entity = ZZ_NewLink (it); + if (entity) { + ZZ_AppendLink (list, entity); + return 0; } loser: - - if (it) - { - if (it->pathname) PORT_Free (it->pathname); - PORT_Free (it); + if (it) { + if (it->pathname) + PORT_Free(it->pathname); + PORT_Free(it); } - - return JAR_ERR_MEMORY; - } - + return JAR_ERR_MEMORY; +} |