1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the Netscape security libraries.
16
* The Initial Developer of the Original Code is
17
* Netscape Communications Corporation.
18
* Portions created by the Initial Developer are Copyright (C) 1994-2000
19
* the Initial Developer. All Rights Reserved.
23
* Alternatively, the contents of this file may be used under the terms of
24
* either the GNU General Public License Version 2 or later (the "GPL"), or
25
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
* in which case the provisions of the GPL or the LGPL are applicable instead
27
* of those above. If you wish to allow use of your version of this file only
28
* under the terms of either the GPL or the LGPL, and not to allow others to
29
* use your version of this file under the terms of the MPL, indicate your
30
* decision by deleting the provisions above and replace them with the notice
31
* and other provisions required by the GPL or the LGPL. If you do not delete
32
* the provisions above, a recipient may use your version of this file under
33
* the terms of any one of the MPL, the GPL or the LGPL.
35
* ***** END LICENSE BLOCK ***** */
41
* Routines common to signing and validating.
48
static void jar_destroy_list (ZZList *list);
50
static int jar_find_first_cert
51
(JAR_Signer *signer, int type, JAR_Item **it);
56
* Create a new instantiation of a manifest representation.
57
* Use this as a token to any calls to this API.
65
if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL)
68
if ((jar->manifest = ZZ_NewList()) == NULL)
71
if ((jar->hashes = ZZ_NewList()) == NULL)
74
if ((jar->phy = ZZ_NewList()) == NULL)
77
if ((jar->metainfo = ZZ_NewList()) == NULL)
80
if ((jar->signers = ZZ_NewList()) == NULL)
90
ZZ_DestroyList (jar->manifest);
93
ZZ_DestroyList (jar->hashes);
96
ZZ_DestroyList (jar->phy);
99
ZZ_DestroyList (jar->metainfo);
102
ZZ_DestroyList (jar->signers);
111
* J A R _ d e s t r o y
117
void PR_CALLBACK JAR_destroy (JAR *jar)
119
PORT_Assert( jar != NULL );
124
if (jar->fp) JAR_FCLOSE ((PRFileDesc*)jar->fp);
126
if (jar->url) PORT_Free (jar->url);
127
if (jar->filename) PORT_Free (jar->filename);
129
/* Free the linked list elements */
131
jar_destroy_list (jar->manifest);
132
ZZ_DestroyList (jar->manifest);
134
jar_destroy_list (jar->hashes);
135
ZZ_DestroyList (jar->hashes);
137
jar_destroy_list (jar->phy);
138
ZZ_DestroyList (jar->phy);
140
jar_destroy_list (jar->metainfo);
141
ZZ_DestroyList (jar->metainfo);
143
jar_destroy_list (jar->signers);
144
ZZ_DestroyList (jar->signers);
149
static void jar_destroy_list (ZZList *list)
151
ZZLink *link, *oldlink;
161
if (list && !ZZ_ListEmpty (list))
163
link = ZZ_ListHead (list);
165
while (!ZZ_ListIterDone (list, link))
170
if (it->pathname) PORT_Free (it->pathname);
176
met = (JAR_Metainfo *) it->data;
179
if (met->header) PORT_Free (met->header);
180
if (met->info) PORT_Free (met->info);
187
phy = (JAR_Physical *) it->data;
194
fing = (JAR_Cert *) it->data;
198
CERT_DestroyCertificate (fing->cert);
200
PORT_Free (fing->key);
209
dig = (JAR_Digest *) it->data;
218
signer = (JAR_Signer *) it->data;
221
JAR_destroy_signer (signer);
227
/* PORT_Assert( 1 != 2 ); */
238
ZZ_DestroyLink (oldlink);
244
* J A R _ g e t _ m e t a i n f o
246
* Retrieve meta information from the manifest file.
247
* It doesn't matter whether it's from .MF or .SF, does it?
252
(JAR *jar, char *name, char *header, void **info, unsigned long *length)
261
PORT_Assert( jar != NULL && header != NULL );
263
if (jar == NULL || header == NULL)
266
list = jar->metainfo;
268
if (ZZ_ListEmpty (list))
271
for (link = ZZ_ListHead (list);
272
!ZZ_ListIterDone (list, link);
276
if (it->type == jarTypeMeta)
278
if ((name && !it->pathname) || (!name && it->pathname))
281
if (name && it->pathname && strcmp (it->pathname, name))
284
met = (JAR_Metainfo *) it->data;
286
if (!PORT_Strcasecmp (met->header, header))
288
*info = PORT_Strdup (met->info);
289
*length = PORT_Strlen (met->info);
301
* Establish the search pattern for use
302
* by JAR_find_next, to traverse the filenames
303
* or certificates in the JAR structure.
305
* See jar.h for a description on how to use.
309
JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type)
313
PORT_Assert( jar != NULL );
318
ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context));
327
if ((ctx->pattern = PORT_Strdup (pattern)) == NULL)
338
case jarTypeMF: ctx->next = ZZ_ListHead (jar->hashes);
342
case jarTypeSign: ctx->next = NULL;
343
ctx->nextsign = ZZ_ListHead (jar->signers);
346
case jarTypeSect: ctx->next = ZZ_ListHead (jar->manifest);
349
case jarTypePhy: ctx->next = ZZ_ListHead (jar->phy);
352
case jarTypeOwner: if (jar->signers)
353
ctx->next = ZZ_ListHead (jar->signers);
358
case jarTypeMeta: ctx->next = ZZ_ListHead (jar->metainfo);
361
default: PORT_Assert( 1 != 2);
369
* J A R _ f i n d _ e n d
371
* Destroy the find iterator context.
375
void JAR_find_end (JAR_Context *ctx)
377
PORT_Assert( ctx != NULL );
382
PORT_Free (ctx->pattern);
388
* J A R _ f i n d _ n e x t
390
* Return the next item of the given type
391
* from one of the JAR linked lists.
395
int JAR_find_next (JAR_Context *ctx, JAR_Item **it)
402
JAR_Signer *signer = NULL;
404
PORT_Assert( ctx != NULL );
405
PORT_Assert( ctx->jar != NULL );
409
/* Internally, convert jarTypeSign to jarTypeSF, and return
410
the actual attached certificate later */
412
finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding;
416
if (ZZ_ListIterDone (jar->signers, ctx->nextsign))
421
PORT_Assert (ctx->nextsign->thing != NULL);
422
signer = (JAR_Signer*)ctx->nextsign->thing->data;
426
/* Find out which linked list to traverse. Then if
427
necessary, advance to the next linked list. */
433
case jarTypeSign: /* not any more */
434
PORT_Assert( finding != jarTypeSign );
435
list = signer->certs;
438
case jarTypeSect: list = jar->manifest;
441
case jarTypePhy: list = jar->phy;
444
case jarTypeSF: /* signer, not jar */
445
PORT_Assert( signer != NULL );
449
case jarTypeMF: list = jar->hashes;
452
case jarTypeOwner: list = jar->signers;
455
case jarTypeMeta: list = jar->metainfo;
458
default: PORT_Assert( 1 != 2 );
468
/* When looping over lists of lists, advance
469
to the next signer. This is done when multiple
470
signers are possible. */
472
if (ZZ_ListIterDone (list, ctx->next))
474
if (ctx->nextsign && jar->signers)
476
ctx->nextsign = ctx->nextsign->next;
477
if (!ZZ_ListIterDone (jar->signers, ctx->nextsign))
479
PORT_Assert (ctx->nextsign->thing != NULL);
481
signer = (JAR_Signer*)ctx->nextsign->thing->data;
482
PORT_Assert( signer != NULL );
492
/* if the signer changed, still need to fill
493
in the "next" link */
495
if (ctx->nextsign && ctx->next == NULL)
501
ctx->next = ZZ_ListHead (signer->sf);
506
ctx->next = ZZ_ListHead (signer->certs);
511
PORT_Assert( ctx->next != NULL );
514
while (!ZZ_ListIterDone (list, ctx->next))
516
*it = ctx->next->thing;
517
ctx->next = ctx->next->next;
519
if (!it || !*it || (*it)->type != finding)
522
if (ctx->pattern && *ctx->pattern)
524
if (PORT_Strcmp ((*it)->pathname, ctx->pattern))
528
/* We have a valid match. If this is a jarTypeSign
529
return the certificate instead.. */
531
if (ctx->finding == jarTypeSign)
535
/* just the first one for now */
536
if (jar_find_first_cert (signer, jarTypeSign, &itt) >= 0)
551
static int jar_find_first_cert
552
(JAR_Signer *signer, int type, JAR_Item **it)
557
int status = JAR_ERR_PNF;
559
list = signer->certs;
563
if (ZZ_ListEmpty (list))
569
for (link = ZZ_ListHead (list);
570
!ZZ_ListIterDone (list, link);
573
if (link->thing->type == type)
584
JAR_Signer *JAR_new_signer (void)
588
signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer));
595
signer->certs = ZZ_NewList();
597
if (signer->certs == NULL)
602
signer->sf = ZZ_NewList();
604
if (signer->sf == NULL)
616
ZZ_DestroyList (signer->certs);
619
ZZ_DestroyList (signer->sf);
627
void JAR_destroy_signer (JAR_Signer *signer)
631
if (signer->owner) PORT_Free (signer->owner);
632
if (signer->digest) PORT_Free (signer->digest);
634
jar_destroy_list (signer->sf);
635
ZZ_DestroyList (signer->sf);
637
jar_destroy_list (signer->certs);
638
ZZ_DestroyList (signer->certs);
644
JAR_Signer *jar_get_signer (JAR *jar, char *basename)
649
JAR_Signer *candidate;
650
JAR_Signer *signer = NULL;
652
ctx = JAR_find (jar, NULL, jarTypeOwner);
657
while (JAR_find_next (ctx, &it) >= 0)
659
candidate = (JAR_Signer *) it->data;
660
if (*basename == '*' || !PORT_Strcmp (candidate->owner, basename))
673
* J A R _ g e t _ f i l e n a m e
675
* Returns the filename associated with
680
char *JAR_get_filename (JAR *jar)
682
return jar->filename;
686
* J A R _ g e t _ u r l
688
* Returns the URL associated with
689
* a JAR structure. Nobody really uses this now.
693
char *JAR_get_url (JAR *jar)
699
* J A R _ s e t _ c a l l b a c k
701
* Register some manner of callback function for this jar.
705
int JAR_set_callback (int type, JAR *jar,
706
int (*fn) (int status, JAR *jar,
707
const char *metafile, char *pathname, char *errortext))
709
if (type == JAR_CB_SIGNAL)
723
/* To return an error string */
724
char *(*jar_fn_GetString) (int) = NULL;
726
/* To return an MWContext for Java */
727
void *(*jar_fn_FindSomeContext) (void) = NULL;
729
/* To fabricate an MWContext for FE_GetPassword */
730
void *(*jar_fn_GetInitContext) (void) = NULL;
735
char *(*string_cb)(int),
736
void *(*find_cx)(void),
737
void *(*init_cx)(void)
740
jar_fn_GetString = string_cb;
741
jar_fn_FindSomeContext = find_cx;
742
jar_fn_GetInitContext = init_cx;
746
* J A R _ g e t _ e r r o r
748
* This is provided to map internal JAR errors to strings for
749
* the Java console. Also, a DLL may call this function if it does
750
* not have access to the XP_GetString function.
752
* These strings aren't UI, since they are Java console only.
756
char *JAR_get_error (int status)
758
char *errstring = NULL;
762
case JAR_ERR_GENERAL:
763
errstring = "General JAR file error";
767
errstring = "JAR file not found";
770
case JAR_ERR_CORRUPT:
771
errstring = "Corrupt JAR file";
775
errstring = "Out of memory";
779
errstring = "Disk error (perhaps out of space)";
783
errstring = "Inconsistent files in META-INF directory";
787
errstring = "Invalid digital signature file";
790
case JAR_ERR_METADATA:
791
errstring = "JAR metadata failed verification";
795
errstring = "No Manifest entry for this JAR entry";
799
errstring = "Invalid Hash of this JAR entry";
803
errstring = "Strange PKCS7 or RSA failure";
807
errstring = "Path not found inside JAR file";
811
if (jar_fn_GetString)
813
errstring = jar_fn_GetString (status);
817
/* this is not a normal situation, and would only be
818
called in cases of improper initialization */
822
err = (char*)PORT_Alloc (40);
824
PR_snprintf (err, 39, "Error %d\n", status);
826
err = "Error! Bad! Out of memory!";