security/nss/lib/jar/jar.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/jar/jar.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,684 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/*
     1.9 + *  JAR.C
    1.10 + *
    1.11 + *  Jarnature.
    1.12 + *  Routines common to signing and validating.
    1.13 + *
    1.14 + */
    1.15 +
    1.16 +#include "jar.h"
    1.17 +#include "jarint.h"
    1.18 +#include "portreg.h"
    1.19 +
    1.20 +static void 
    1.21 +jar_destroy_list (ZZList *list);
    1.22 +
    1.23 +static int 
    1.24 +jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it);
    1.25 +
    1.26 +/*
    1.27 + *  J A R _ n e w
    1.28 + *
    1.29 + *  Create a new instantiation of a manifest representation.
    1.30 + *  Use this as a token to any calls to this API.
    1.31 + *
    1.32 + */
    1.33 +JAR *
    1.34 +JAR_new(void)
    1.35 +{
    1.36 +    JAR *jar;
    1.37 +
    1.38 +    if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL)
    1.39 +	goto loser;
    1.40 +    if ((jar->manifest = ZZ_NewList()) == NULL)
    1.41 +	goto loser;
    1.42 +    if ((jar->hashes = ZZ_NewList()) == NULL)
    1.43 +	goto loser;
    1.44 +    if ((jar->phy = ZZ_NewList()) == NULL)
    1.45 +	goto loser;
    1.46 +    if ((jar->metainfo = ZZ_NewList()) == NULL)
    1.47 +	goto loser;
    1.48 +    if ((jar->signers = ZZ_NewList()) == NULL)
    1.49 +	goto loser;
    1.50 +    return jar;
    1.51 +
    1.52 +loser:
    1.53 +    if (jar) {
    1.54 +	if (jar->manifest)
    1.55 +	    ZZ_DestroyList (jar->manifest);
    1.56 +	if (jar->hashes)
    1.57 +	    ZZ_DestroyList (jar->hashes);
    1.58 +	if (jar->phy)
    1.59 +	    ZZ_DestroyList (jar->phy);
    1.60 +	if (jar->metainfo)
    1.61 +	    ZZ_DestroyList (jar->metainfo);
    1.62 +	if (jar->signers)
    1.63 +	    ZZ_DestroyList (jar->signers);
    1.64 +	PORT_Free (jar);
    1.65 +    }
    1.66 +    return NULL;
    1.67 +}
    1.68 +
    1.69 +/*
    1.70 + *  J A R _ d e s t r o y
    1.71 + */
    1.72 +void PR_CALLBACK 
    1.73 +JAR_destroy(JAR *jar)
    1.74 +{
    1.75 +    PORT_Assert( jar != NULL );
    1.76 +
    1.77 +    if (jar == NULL)
    1.78 +	return;
    1.79 +
    1.80 +    if (jar->fp) 
    1.81 +    	JAR_FCLOSE ((PRFileDesc*)jar->fp);
    1.82 +    if (jar->url)      
    1.83 +    	PORT_Free (jar->url);
    1.84 +    if (jar->filename) 
    1.85 +    	PORT_Free (jar->filename);
    1.86 +
    1.87 +    /* Free the linked list elements */
    1.88 +    jar_destroy_list (jar->manifest);
    1.89 +    ZZ_DestroyList (jar->manifest);
    1.90 +    jar_destroy_list (jar->hashes);
    1.91 +    ZZ_DestroyList (jar->hashes);
    1.92 +    jar_destroy_list (jar->phy);
    1.93 +    ZZ_DestroyList (jar->phy);
    1.94 +    jar_destroy_list (jar->metainfo);
    1.95 +    ZZ_DestroyList (jar->metainfo);
    1.96 +    jar_destroy_list (jar->signers);
    1.97 +    ZZ_DestroyList (jar->signers);
    1.98 +    PORT_Free (jar);
    1.99 +}
   1.100 +
   1.101 +static void 
   1.102 +jar_destroy_list(ZZList *list)
   1.103 +{
   1.104 +    ZZLink *link, *oldlink;
   1.105 +    JAR_Item *it;
   1.106 +    JAR_Physical *phy;
   1.107 +    JAR_Digest *dig;
   1.108 +    JAR_Cert *fing;
   1.109 +    JAR_Metainfo *met;
   1.110 +    JAR_Signer *signer;
   1.111 +
   1.112 +    if (list && !ZZ_ListEmpty (list)) {
   1.113 +	link = ZZ_ListHead (list);
   1.114 +	while (!ZZ_ListIterDone (list, link)) {
   1.115 +	    it = link->thing;
   1.116 +	    if (!it) 
   1.117 +	    	goto next;
   1.118 +	    if (it->pathname) 
   1.119 +	    	PORT_Free (it->pathname);
   1.120 +
   1.121 +	    switch (it->type) {
   1.122 +	    case jarTypeMeta:
   1.123 +		met = (JAR_Metainfo *) it->data;
   1.124 +		if (met) {
   1.125 +		    if (met->header) 
   1.126 +		    	PORT_Free (met->header);
   1.127 +		    if (met->info) 
   1.128 +		    	PORT_Free (met->info);
   1.129 +		    PORT_Free (met);
   1.130 +		}
   1.131 +		break;
   1.132 +
   1.133 +	    case jarTypePhy:
   1.134 +		phy = (JAR_Physical *) it->data;
   1.135 +		if (phy)
   1.136 +		    PORT_Free (phy);
   1.137 +		break;
   1.138 +
   1.139 +	    case jarTypeSign:
   1.140 +		fing = (JAR_Cert *) it->data;
   1.141 +		if (fing) {
   1.142 +		    if (fing->cert)
   1.143 +			CERT_DestroyCertificate (fing->cert);
   1.144 +		    if (fing->key)
   1.145 +			PORT_Free (fing->key);
   1.146 +		    PORT_Free (fing);
   1.147 +		}
   1.148 +		break;
   1.149 +
   1.150 +	    case jarTypeSect:
   1.151 +	    case jarTypeMF:
   1.152 +	    case jarTypeSF:
   1.153 +		dig = (JAR_Digest *) it->data;
   1.154 +		if (dig) {
   1.155 +		    PORT_Free (dig);
   1.156 +		}
   1.157 +		break;
   1.158 +
   1.159 +	    case jarTypeOwner:
   1.160 +		signer = (JAR_Signer *) it->data;
   1.161 +		if (signer)
   1.162 +		    JAR_destroy_signer (signer);
   1.163 +		break;
   1.164 +
   1.165 +	    default:
   1.166 +		/* PORT_Assert( 1 != 2 ); */
   1.167 +		break;
   1.168 +	    }
   1.169 +	    PORT_Free (it);
   1.170 +
   1.171 +next:
   1.172 +	    oldlink = link;
   1.173 +	    link = link->next;
   1.174 +	    ZZ_DestroyLink (oldlink);
   1.175 +	}
   1.176 +    }
   1.177 +}
   1.178 +
   1.179 +/*
   1.180 + *  J A R _ g e t _ m e t a i n f o
   1.181 + *
   1.182 + *  Retrieve meta information from the manifest file.
   1.183 + *  It doesn't matter whether it's from .MF or .SF, does it?
   1.184 + *
   1.185 + */
   1.186 +
   1.187 +int 
   1.188 +JAR_get_metainfo(JAR *jar, char *name, char *header, void **info, 
   1.189 +                 unsigned long *length)
   1.190 +{
   1.191 +    JAR_Item *it;
   1.192 +    ZZLink *link;
   1.193 +    ZZList *list;
   1.194 +
   1.195 +    PORT_Assert( jar != NULL && header != NULL );
   1.196 +
   1.197 +    if (jar == NULL || header == NULL)
   1.198 +	return JAR_ERR_PNF;
   1.199 +
   1.200 +    list = jar->metainfo;
   1.201 +
   1.202 +    if (ZZ_ListEmpty (list))
   1.203 +	return JAR_ERR_PNF;
   1.204 +
   1.205 +    for (link = ZZ_ListHead (list);
   1.206 +         !ZZ_ListIterDone (list, link);
   1.207 +         link = link->next) {
   1.208 +	it = link->thing;
   1.209 +	if (it->type == jarTypeMeta) {
   1.210 +	    JAR_Metainfo *met;
   1.211 +
   1.212 +	    if ((name && !it->pathname) || (!name && it->pathname))
   1.213 +		continue;
   1.214 +	    if (name && it->pathname && strcmp (it->pathname, name))
   1.215 +		continue;
   1.216 +	    met = (JAR_Metainfo *) it->data;
   1.217 +	    if (!PORT_Strcasecmp (met->header, header)) {
   1.218 +		*info = PORT_Strdup (met->info);
   1.219 +		*length = PORT_Strlen (met->info);
   1.220 +		return 0;
   1.221 +	    }
   1.222 +	}
   1.223 +    }
   1.224 +    return JAR_ERR_PNF;
   1.225 +}
   1.226 +
   1.227 +/*
   1.228 + *  J A R _ f i n d
   1.229 + *
   1.230 + *  Establish the search pattern for use
   1.231 + *  by JAR_find_next, to traverse the filenames
   1.232 + *  or certificates in the JAR structure.
   1.233 + *
   1.234 + *  See jar.h for a description on how to use.
   1.235 + *
   1.236 + */
   1.237 +JAR_Context *
   1.238 +JAR_find (JAR *jar, char *pattern, jarType type)
   1.239 +{
   1.240 +    JAR_Context *ctx;
   1.241 +
   1.242 +    PORT_Assert( jar != NULL );
   1.243 +
   1.244 +    if (!jar)
   1.245 +	return NULL;
   1.246 +
   1.247 +    ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context));
   1.248 +    if (ctx == NULL)
   1.249 +	return NULL;
   1.250 +
   1.251 +    ctx->jar = jar;
   1.252 +    if (pattern) {
   1.253 +	if ((ctx->pattern = PORT_Strdup (pattern)) == NULL) {
   1.254 +	    PORT_Free (ctx);
   1.255 +	    return NULL;
   1.256 +	}
   1.257 +    }
   1.258 +    ctx->finding = type;
   1.259 +
   1.260 +    switch (type) {
   1.261 +    case jarTypeMF:
   1.262 +	ctx->next = ZZ_ListHead (jar->hashes);
   1.263 +	break;
   1.264 +
   1.265 +    case jarTypeSF:
   1.266 +    case jarTypeSign:
   1.267 +	ctx->next = NULL;
   1.268 +	ctx->nextsign = ZZ_ListHead (jar->signers);
   1.269 +	break;
   1.270 +
   1.271 +    case jarTypeSect:
   1.272 +	ctx->next = ZZ_ListHead (jar->manifest);
   1.273 +	break;
   1.274 +
   1.275 +    case jarTypePhy:
   1.276 +	ctx->next = ZZ_ListHead (jar->phy);
   1.277 +	break;
   1.278 +
   1.279 +    case jarTypeOwner:
   1.280 +	if (jar->signers)
   1.281 +	    ctx->next = ZZ_ListHead (jar->signers);
   1.282 +	else
   1.283 +	    ctx->next = NULL;
   1.284 +	break;
   1.285 +
   1.286 +    case jarTypeMeta:
   1.287 +	ctx->next = ZZ_ListHead (jar->metainfo);
   1.288 +	break;
   1.289 +
   1.290 +    default:
   1.291 +	PORT_Assert( 1 != 2);
   1.292 +	break;
   1.293 +    }
   1.294 +    return ctx;
   1.295 +}
   1.296 +
   1.297 +/*
   1.298 + *  J A R _ f i n d _ e n d
   1.299 + *
   1.300 + *  Destroy the find iterator context.
   1.301 + *
   1.302 + */
   1.303 +void 
   1.304 +JAR_find_end (JAR_Context *ctx)
   1.305 +{
   1.306 +    PORT_Assert( ctx != NULL );
   1.307 +    if (ctx) {
   1.308 +	if (ctx->pattern)
   1.309 +	    PORT_Free (ctx->pattern);
   1.310 +	PORT_Free (ctx);
   1.311 +    }
   1.312 +}
   1.313 +
   1.314 +/*
   1.315 + *  J A R _ f i n d _ n e x t
   1.316 + *
   1.317 + *  Return the next item of the given type
   1.318 + *  from one of the JAR linked lists.
   1.319 + *
   1.320 + */
   1.321 +
   1.322 +int JAR_find_next (JAR_Context *ctx, JAR_Item **it)
   1.323 +{
   1.324 +    JAR *jar;
   1.325 +    ZZList *list = NULL;
   1.326 +    int finding;
   1.327 +    JAR_Signer *signer = NULL;
   1.328 +
   1.329 +    PORT_Assert( ctx != NULL );
   1.330 +    PORT_Assert( ctx->jar != NULL );
   1.331 +
   1.332 +    jar = ctx->jar;
   1.333 +
   1.334 +    /* Internally, convert jarTypeSign to jarTypeSF, and return
   1.335 +       the actual attached certificate later */
   1.336 +    finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding;
   1.337 +    if (ctx->nextsign) {
   1.338 +	if (ZZ_ListIterDone (jar->signers, ctx->nextsign)) {
   1.339 +	    *it = NULL;
   1.340 +	    return -1;
   1.341 +	}
   1.342 +	PORT_Assert (ctx->nextsign->thing != NULL);
   1.343 +	signer = (JAR_Signer*)ctx->nextsign->thing->data;
   1.344 +    }
   1.345 +
   1.346 +    /* Find out which linked list to traverse. Then if
   1.347 +       necessary, advance to the next linked list. */
   1.348 +    while (1) {
   1.349 +	switch (finding) {
   1.350 +	case jarTypeSign:    /* not any more */
   1.351 +	    PORT_Assert( finding != jarTypeSign );
   1.352 +	    list = signer->certs;
   1.353 +	    break;
   1.354 +
   1.355 +	case jarTypeSect:
   1.356 +	    list = jar->manifest;
   1.357 +	    break;
   1.358 +
   1.359 +	case jarTypePhy:
   1.360 +	    list = jar->phy;
   1.361 +	    break;
   1.362 +
   1.363 +	case jarTypeSF:      /* signer, not jar */
   1.364 +	    PORT_Assert( signer != NULL );
   1.365 +	    list = signer ? signer->sf : NULL;
   1.366 +	    break;
   1.367 +
   1.368 +	case jarTypeMF:
   1.369 +	    list = jar->hashes;
   1.370 +	    break;
   1.371 +
   1.372 +	case jarTypeOwner:
   1.373 +	    list = jar->signers;
   1.374 +	    break;
   1.375 +
   1.376 +	case jarTypeMeta:
   1.377 +	    list = jar->metainfo;
   1.378 +	    break;
   1.379 +
   1.380 +	default:
   1.381 +	    PORT_Assert( 1 != 2 );
   1.382 +	    list = NULL;
   1.383 +	    break;
   1.384 +	}
   1.385 +	if (list == NULL) {
   1.386 +	    *it = NULL;
   1.387 +	    return -1;
   1.388 +	}
   1.389 +	/* When looping over lists of lists, advance to the next signer. 
   1.390 +	   This is done when multiple signers are possible. */
   1.391 +	if (ZZ_ListIterDone (list, ctx->next)) {
   1.392 +	    if (ctx->nextsign && jar->signers) {
   1.393 +		ctx->nextsign = ctx->nextsign->next;
   1.394 +		if (!ZZ_ListIterDone (jar->signers, ctx->nextsign)) {
   1.395 +		    PORT_Assert (ctx->nextsign->thing != NULL);
   1.396 +		    signer = (JAR_Signer*)ctx->nextsign->thing->data;
   1.397 +		    PORT_Assert( signer != NULL );
   1.398 +		    ctx->next = NULL;
   1.399 +		    continue;
   1.400 +		}
   1.401 +	    }
   1.402 +	    *it = NULL;
   1.403 +	    return -1;
   1.404 +	}
   1.405 +
   1.406 +	/* if the signer changed, still need to fill in the "next" link */
   1.407 +	if (ctx->nextsign && ctx->next == NULL) {
   1.408 +	    switch (finding) {
   1.409 +	    case jarTypeSF:
   1.410 +		ctx->next = ZZ_ListHead (signer->sf);
   1.411 +		break;
   1.412 +
   1.413 +	    case jarTypeSign:
   1.414 +		ctx->next = ZZ_ListHead (signer->certs);
   1.415 +		break;
   1.416 +	    }
   1.417 +	}
   1.418 +	PORT_Assert( ctx->next != NULL );
   1.419 +	if (ctx->next == NULL) {
   1.420 +	    *it = NULL;
   1.421 +	    return -1;
   1.422 +	}
   1.423 +	while (!ZZ_ListIterDone (list, ctx->next)) {
   1.424 +	    *it = ctx->next->thing;
   1.425 +	    ctx->next = ctx->next->next;
   1.426 +	    if (!*it || (*it)->type != finding)
   1.427 +		continue;
   1.428 +	    if (ctx->pattern && *ctx->pattern) {
   1.429 +		if (PORT_RegExpSearch ((*it)->pathname, ctx->pattern))
   1.430 +		    continue;
   1.431 +	    }
   1.432 +	    /* We have a valid match. If this is a jarTypeSign
   1.433 +	       return the certificate instead.. */
   1.434 +	    if (ctx->finding == jarTypeSign) {
   1.435 +		JAR_Item *itt;
   1.436 +
   1.437 +		/* just the first one for now */
   1.438 +		if (jar_find_first_cert (signer, jarTypeSign, &itt) >= 0) {
   1.439 +		    *it = itt;
   1.440 +		    return 0;
   1.441 +		}
   1.442 +		continue;
   1.443 +	    }
   1.444 +	    return 0;
   1.445 +	}
   1.446 +    } /* end while */
   1.447 +}
   1.448 +
   1.449 +static int 
   1.450 +jar_find_first_cert (JAR_Signer *signer, int type, JAR_Item **it)
   1.451 +{
   1.452 +    ZZLink *link;
   1.453 +    ZZList *list = signer->certs;
   1.454 +    int status = JAR_ERR_PNF;
   1.455 +
   1.456 +    *it = NULL;
   1.457 +    if (ZZ_ListEmpty (list)) {
   1.458 +	/* empty list */
   1.459 +	return JAR_ERR_PNF;
   1.460 +    }
   1.461 +
   1.462 +    for (link = ZZ_ListHead (list);
   1.463 +	 !ZZ_ListIterDone (list, link);
   1.464 +	 link = link->next) {
   1.465 +	if (link->thing->type == type) {
   1.466 +	    *it = link->thing;
   1.467 +	    status = 0;
   1.468 +	    break;
   1.469 +	}
   1.470 +    }
   1.471 +    return status;
   1.472 +}
   1.473 +
   1.474 +JAR_Signer *
   1.475 +JAR_new_signer (void) 
   1.476 +{
   1.477 +    JAR_Signer *signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer));
   1.478 +    if (signer == NULL)
   1.479 +	goto loser;
   1.480 +
   1.481 +    /* certs */
   1.482 +    signer->certs = ZZ_NewList();
   1.483 +    if (signer->certs == NULL)
   1.484 +	goto loser;
   1.485 +
   1.486 +    /* sf */
   1.487 +    signer->sf = ZZ_NewList();
   1.488 +    if (signer->sf == NULL)
   1.489 +	goto loser;
   1.490 +    return signer;
   1.491 +
   1.492 +loser:
   1.493 +    if (signer) {
   1.494 +	if (signer->certs)
   1.495 +	    ZZ_DestroyList (signer->certs);
   1.496 +	if (signer->sf)
   1.497 +	    ZZ_DestroyList (signer->sf);
   1.498 +	PORT_Free (signer);
   1.499 +    }
   1.500 +    return NULL;
   1.501 +}
   1.502 +
   1.503 +void 
   1.504 +JAR_destroy_signer(JAR_Signer *signer)
   1.505 +{
   1.506 +    if (signer) {
   1.507 +	if (signer->owner) 
   1.508 +	    PORT_Free (signer->owner);
   1.509 +	if (signer->digest) 
   1.510 +	    PORT_Free (signer->digest);
   1.511 +	jar_destroy_list (signer->sf);
   1.512 +	ZZ_DestroyList (signer->sf);
   1.513 +	jar_destroy_list (signer->certs);
   1.514 +	ZZ_DestroyList (signer->certs);
   1.515 +	PORT_Free (signer);
   1.516 +    }
   1.517 +}
   1.518 +
   1.519 +JAR_Signer *
   1.520 +jar_get_signer(JAR *jar, char *basename)
   1.521 +{
   1.522 +    JAR_Item *it;
   1.523 +    JAR_Context *ctx = JAR_find (jar, NULL, jarTypeOwner);
   1.524 +    JAR_Signer *candidate;
   1.525 +    JAR_Signer *signer = NULL;
   1.526 +
   1.527 +    if (ctx == NULL)
   1.528 +	return NULL;
   1.529 +
   1.530 +    while (JAR_find_next (ctx, &it) >= 0) {
   1.531 +	candidate = (JAR_Signer *) it->data;
   1.532 +	if (*basename == '*' || !PORT_Strcmp (candidate->owner, basename)) {
   1.533 +	    signer = candidate;
   1.534 +	    break;
   1.535 +	}
   1.536 +    }
   1.537 +    JAR_find_end (ctx);
   1.538 +    return signer;
   1.539 +}
   1.540 +
   1.541 +/*
   1.542 + *  J A R _ g e t _ f i l e n a m e
   1.543 + *
   1.544 + *  Returns the filename associated with
   1.545 + *  a JAR structure.
   1.546 + *
   1.547 + */
   1.548 +char *
   1.549 +JAR_get_filename(JAR *jar)
   1.550 +{
   1.551 +    return jar->filename;
   1.552 +}
   1.553 +
   1.554 +/*
   1.555 + *  J A R _ g e t _ u r l
   1.556 + *
   1.557 + *  Returns the URL associated with
   1.558 + *  a JAR structure. Nobody really uses this now.
   1.559 + *
   1.560 + */
   1.561 +char *
   1.562 +JAR_get_url(JAR *jar)
   1.563 +{
   1.564 +    return jar->url;
   1.565 +}
   1.566 +
   1.567 +/*
   1.568 + *  J A R _ s e t _ c a l l b a c k
   1.569 + *
   1.570 + *  Register some manner of callback function for this jar.
   1.571 + *
   1.572 + */
   1.573 +int 
   1.574 +JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn)
   1.575 +{
   1.576 +    if (type == JAR_CB_SIGNAL) {
   1.577 +	jar->signal = fn;
   1.578 +	return 0;
   1.579 +    }
   1.580 +    return -1;
   1.581 +}
   1.582 +
   1.583 +/*
   1.584 + *  Callbacks
   1.585 + *
   1.586 + */
   1.587 +
   1.588 +/* To return an error string */
   1.589 +char *(*jar_fn_GetString) (int) = NULL;
   1.590 +
   1.591 +/* To return an MWContext for Java */
   1.592 +void *(*jar_fn_FindSomeContext) (void) = NULL;
   1.593 +
   1.594 +/* To fabricate an MWContext for FE_GetPassword */
   1.595 +void *(*jar_fn_GetInitContext) (void) = NULL;
   1.596 +
   1.597 +void
   1.598 +JAR_init_callbacks(char *(*string_cb)(int), 
   1.599 +                   void *(*find_cx)(void),
   1.600 +                   void *(*init_cx)(void))
   1.601 +{
   1.602 +    jar_fn_GetString = string_cb;
   1.603 +    jar_fn_FindSomeContext = find_cx;
   1.604 +    jar_fn_GetInitContext = init_cx;
   1.605 +}
   1.606 +
   1.607 +/*
   1.608 + *  J A R _ g e t _ e r r o r
   1.609 + *
   1.610 + *  This is provided to map internal JAR errors to strings for
   1.611 + *  the Java console. Also, a DLL may call this function if it does
   1.612 + *  not have access to the XP_GetString function.
   1.613 + *
   1.614 + *  These strings aren't UI, since they are Java console only.
   1.615 + *
   1.616 + */
   1.617 +char *
   1.618 +JAR_get_error(int status)
   1.619 +{
   1.620 +    char *errstring = NULL;
   1.621 +
   1.622 +    switch (status) {
   1.623 +    case JAR_ERR_GENERAL:
   1.624 +	errstring = "General JAR file error";
   1.625 +	break;
   1.626 +
   1.627 +    case JAR_ERR_FNF:
   1.628 +	errstring = "JAR file not found";
   1.629 +	break;
   1.630 +
   1.631 +    case JAR_ERR_CORRUPT:
   1.632 +	errstring = "Corrupt JAR file";
   1.633 +	break;
   1.634 +
   1.635 +    case JAR_ERR_MEMORY:
   1.636 +	errstring = "Out of memory";
   1.637 +	break;
   1.638 +
   1.639 +    case JAR_ERR_DISK:
   1.640 +	errstring = "Disk error (perhaps out of space)";
   1.641 +	break;
   1.642 +
   1.643 +    case JAR_ERR_ORDER:
   1.644 +	errstring = "Inconsistent files in META-INF directory";
   1.645 +	break;
   1.646 +
   1.647 +    case JAR_ERR_SIG:
   1.648 +	errstring = "Invalid digital signature file";
   1.649 +	break;
   1.650 +
   1.651 +    case JAR_ERR_METADATA:
   1.652 +	errstring = "JAR metadata failed verification";
   1.653 +	break;
   1.654 +
   1.655 +    case JAR_ERR_ENTRY:
   1.656 +	errstring = "No Manifest entry for this JAR entry";
   1.657 +	break;
   1.658 +
   1.659 +    case JAR_ERR_HASH:
   1.660 +	errstring = "Invalid Hash of this JAR entry";
   1.661 +	break;
   1.662 +
   1.663 +    case JAR_ERR_PK7:
   1.664 +	errstring = "Strange PKCS7 or RSA failure";
   1.665 +	break;
   1.666 +
   1.667 +    case JAR_ERR_PNF:
   1.668 +	errstring = "Path not found inside JAR file";
   1.669 +	break;
   1.670 +
   1.671 +    default:
   1.672 +	if (jar_fn_GetString) {
   1.673 +	    errstring = jar_fn_GetString (status);
   1.674 +	} else {
   1.675 +	    /* this is not a normal situation, and would only be
   1.676 +	       called in cases of improper initialization */
   1.677 +	    char *err = (char*)PORT_Alloc (40);
   1.678 +	    if (err)
   1.679 +		PR_snprintf (err, 39,  "Error %d\n", status); /* leak me! */
   1.680 +	    else
   1.681 +		err = "Error! Bad! Out of memory!";
   1.682 +	    return err;
   1.683 +	}
   1.684 +	break;
   1.685 +    }
   1.686 +    return errstring;
   1.687 +}

mercurial