security/nss/lib/jar/jar.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 * JAR.C
michael@0 7 *
michael@0 8 * Jarnature.
michael@0 9 * Routines common to signing and validating.
michael@0 10 *
michael@0 11 */
michael@0 12
michael@0 13 #include "jar.h"
michael@0 14 #include "jarint.h"
michael@0 15 #include "portreg.h"
michael@0 16
michael@0 17 static void
michael@0 18 jar_destroy_list (ZZList *list);
michael@0 19
michael@0 20 static int
michael@0 21 jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it);
michael@0 22
michael@0 23 /*
michael@0 24 * J A R _ n e w
michael@0 25 *
michael@0 26 * Create a new instantiation of a manifest representation.
michael@0 27 * Use this as a token to any calls to this API.
michael@0 28 *
michael@0 29 */
michael@0 30 JAR *
michael@0 31 JAR_new(void)
michael@0 32 {
michael@0 33 JAR *jar;
michael@0 34
michael@0 35 if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL)
michael@0 36 goto loser;
michael@0 37 if ((jar->manifest = ZZ_NewList()) == NULL)
michael@0 38 goto loser;
michael@0 39 if ((jar->hashes = ZZ_NewList()) == NULL)
michael@0 40 goto loser;
michael@0 41 if ((jar->phy = ZZ_NewList()) == NULL)
michael@0 42 goto loser;
michael@0 43 if ((jar->metainfo = ZZ_NewList()) == NULL)
michael@0 44 goto loser;
michael@0 45 if ((jar->signers = ZZ_NewList()) == NULL)
michael@0 46 goto loser;
michael@0 47 return jar;
michael@0 48
michael@0 49 loser:
michael@0 50 if (jar) {
michael@0 51 if (jar->manifest)
michael@0 52 ZZ_DestroyList (jar->manifest);
michael@0 53 if (jar->hashes)
michael@0 54 ZZ_DestroyList (jar->hashes);
michael@0 55 if (jar->phy)
michael@0 56 ZZ_DestroyList (jar->phy);
michael@0 57 if (jar->metainfo)
michael@0 58 ZZ_DestroyList (jar->metainfo);
michael@0 59 if (jar->signers)
michael@0 60 ZZ_DestroyList (jar->signers);
michael@0 61 PORT_Free (jar);
michael@0 62 }
michael@0 63 return NULL;
michael@0 64 }
michael@0 65
michael@0 66 /*
michael@0 67 * J A R _ d e s t r o y
michael@0 68 */
michael@0 69 void PR_CALLBACK
michael@0 70 JAR_destroy(JAR *jar)
michael@0 71 {
michael@0 72 PORT_Assert( jar != NULL );
michael@0 73
michael@0 74 if (jar == NULL)
michael@0 75 return;
michael@0 76
michael@0 77 if (jar->fp)
michael@0 78 JAR_FCLOSE ((PRFileDesc*)jar->fp);
michael@0 79 if (jar->url)
michael@0 80 PORT_Free (jar->url);
michael@0 81 if (jar->filename)
michael@0 82 PORT_Free (jar->filename);
michael@0 83
michael@0 84 /* Free the linked list elements */
michael@0 85 jar_destroy_list (jar->manifest);
michael@0 86 ZZ_DestroyList (jar->manifest);
michael@0 87 jar_destroy_list (jar->hashes);
michael@0 88 ZZ_DestroyList (jar->hashes);
michael@0 89 jar_destroy_list (jar->phy);
michael@0 90 ZZ_DestroyList (jar->phy);
michael@0 91 jar_destroy_list (jar->metainfo);
michael@0 92 ZZ_DestroyList (jar->metainfo);
michael@0 93 jar_destroy_list (jar->signers);
michael@0 94 ZZ_DestroyList (jar->signers);
michael@0 95 PORT_Free (jar);
michael@0 96 }
michael@0 97
michael@0 98 static void
michael@0 99 jar_destroy_list(ZZList *list)
michael@0 100 {
michael@0 101 ZZLink *link, *oldlink;
michael@0 102 JAR_Item *it;
michael@0 103 JAR_Physical *phy;
michael@0 104 JAR_Digest *dig;
michael@0 105 JAR_Cert *fing;
michael@0 106 JAR_Metainfo *met;
michael@0 107 JAR_Signer *signer;
michael@0 108
michael@0 109 if (list && !ZZ_ListEmpty (list)) {
michael@0 110 link = ZZ_ListHead (list);
michael@0 111 while (!ZZ_ListIterDone (list, link)) {
michael@0 112 it = link->thing;
michael@0 113 if (!it)
michael@0 114 goto next;
michael@0 115 if (it->pathname)
michael@0 116 PORT_Free (it->pathname);
michael@0 117
michael@0 118 switch (it->type) {
michael@0 119 case jarTypeMeta:
michael@0 120 met = (JAR_Metainfo *) it->data;
michael@0 121 if (met) {
michael@0 122 if (met->header)
michael@0 123 PORT_Free (met->header);
michael@0 124 if (met->info)
michael@0 125 PORT_Free (met->info);
michael@0 126 PORT_Free (met);
michael@0 127 }
michael@0 128 break;
michael@0 129
michael@0 130 case jarTypePhy:
michael@0 131 phy = (JAR_Physical *) it->data;
michael@0 132 if (phy)
michael@0 133 PORT_Free (phy);
michael@0 134 break;
michael@0 135
michael@0 136 case jarTypeSign:
michael@0 137 fing = (JAR_Cert *) it->data;
michael@0 138 if (fing) {
michael@0 139 if (fing->cert)
michael@0 140 CERT_DestroyCertificate (fing->cert);
michael@0 141 if (fing->key)
michael@0 142 PORT_Free (fing->key);
michael@0 143 PORT_Free (fing);
michael@0 144 }
michael@0 145 break;
michael@0 146
michael@0 147 case jarTypeSect:
michael@0 148 case jarTypeMF:
michael@0 149 case jarTypeSF:
michael@0 150 dig = (JAR_Digest *) it->data;
michael@0 151 if (dig) {
michael@0 152 PORT_Free (dig);
michael@0 153 }
michael@0 154 break;
michael@0 155
michael@0 156 case jarTypeOwner:
michael@0 157 signer = (JAR_Signer *) it->data;
michael@0 158 if (signer)
michael@0 159 JAR_destroy_signer (signer);
michael@0 160 break;
michael@0 161
michael@0 162 default:
michael@0 163 /* PORT_Assert( 1 != 2 ); */
michael@0 164 break;
michael@0 165 }
michael@0 166 PORT_Free (it);
michael@0 167
michael@0 168 next:
michael@0 169 oldlink = link;
michael@0 170 link = link->next;
michael@0 171 ZZ_DestroyLink (oldlink);
michael@0 172 }
michael@0 173 }
michael@0 174 }
michael@0 175
michael@0 176 /*
michael@0 177 * J A R _ g e t _ m e t a i n f o
michael@0 178 *
michael@0 179 * Retrieve meta information from the manifest file.
michael@0 180 * It doesn't matter whether it's from .MF or .SF, does it?
michael@0 181 *
michael@0 182 */
michael@0 183
michael@0 184 int
michael@0 185 JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
michael@0 186 unsigned long *length)
michael@0 187 {
michael@0 188 JAR_Item *it;
michael@0 189 ZZLink *link;
michael@0 190 ZZList *list;
michael@0 191
michael@0 192 PORT_Assert( jar != NULL && header != NULL );
michael@0 193
michael@0 194 if (jar == NULL || header == NULL)
michael@0 195 return JAR_ERR_PNF;
michael@0 196
michael@0 197 list = jar->metainfo;
michael@0 198
michael@0 199 if (ZZ_ListEmpty (list))
michael@0 200 return JAR_ERR_PNF;
michael@0 201
michael@0 202 for (link = ZZ_ListHead (list);
michael@0 203 !ZZ_ListIterDone (list, link);
michael@0 204 link = link->next) {
michael@0 205 it = link->thing;
michael@0 206 if (it->type == jarTypeMeta) {
michael@0 207 JAR_Metainfo *met;
michael@0 208
michael@0 209 if ((name && !it->pathname) || (!name && it->pathname))
michael@0 210 continue;
michael@0 211 if (name && it->pathname && strcmp (it->pathname, name))
michael@0 212 continue;
michael@0 213 met = (JAR_Metainfo *) it->data;
michael@0 214 if (!PORT_Strcasecmp (met->header, header)) {
michael@0 215 *info = PORT_Strdup (met->info);
michael@0 216 *length = PORT_Strlen (met->info);
michael@0 217 return 0;
michael@0 218 }
michael@0 219 }
michael@0 220 }
michael@0 221 return JAR_ERR_PNF;
michael@0 222 }
michael@0 223
michael@0 224 /*
michael@0 225 * J A R _ f i n d
michael@0 226 *
michael@0 227 * Establish the search pattern for use
michael@0 228 * by JAR_find_next, to traverse the filenames
michael@0 229 * or certificates in the JAR structure.
michael@0 230 *
michael@0 231 * See jar.h for a description on how to use.
michael@0 232 *
michael@0 233 */
michael@0 234 JAR_Context *
michael@0 235 JAR_find (JAR *jar, char *pattern, jarType type)
michael@0 236 {
michael@0 237 JAR_Context *ctx;
michael@0 238
michael@0 239 PORT_Assert( jar != NULL );
michael@0 240
michael@0 241 if (!jar)
michael@0 242 return NULL;
michael@0 243
michael@0 244 ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context));
michael@0 245 if (ctx == NULL)
michael@0 246 return NULL;
michael@0 247
michael@0 248 ctx->jar = jar;
michael@0 249 if (pattern) {
michael@0 250 if ((ctx->pattern = PORT_Strdup (pattern)) == NULL) {
michael@0 251 PORT_Free (ctx);
michael@0 252 return NULL;
michael@0 253 }
michael@0 254 }
michael@0 255 ctx->finding = type;
michael@0 256
michael@0 257 switch (type) {
michael@0 258 case jarTypeMF:
michael@0 259 ctx->next = ZZ_ListHead (jar->hashes);
michael@0 260 break;
michael@0 261
michael@0 262 case jarTypeSF:
michael@0 263 case jarTypeSign:
michael@0 264 ctx->next = NULL;
michael@0 265 ctx->nextsign = ZZ_ListHead (jar->signers);
michael@0 266 break;
michael@0 267
michael@0 268 case jarTypeSect:
michael@0 269 ctx->next = ZZ_ListHead (jar->manifest);
michael@0 270 break;
michael@0 271
michael@0 272 case jarTypePhy:
michael@0 273 ctx->next = ZZ_ListHead (jar->phy);
michael@0 274 break;
michael@0 275
michael@0 276 case jarTypeOwner:
michael@0 277 if (jar->signers)
michael@0 278 ctx->next = ZZ_ListHead (jar->signers);
michael@0 279 else
michael@0 280 ctx->next = NULL;
michael@0 281 break;
michael@0 282
michael@0 283 case jarTypeMeta:
michael@0 284 ctx->next = ZZ_ListHead (jar->metainfo);
michael@0 285 break;
michael@0 286
michael@0 287 default:
michael@0 288 PORT_Assert( 1 != 2);
michael@0 289 break;
michael@0 290 }
michael@0 291 return ctx;
michael@0 292 }
michael@0 293
michael@0 294 /*
michael@0 295 * J A R _ f i n d _ e n d
michael@0 296 *
michael@0 297 * Destroy the find iterator context.
michael@0 298 *
michael@0 299 */
michael@0 300 void
michael@0 301 JAR_find_end (JAR_Context *ctx)
michael@0 302 {
michael@0 303 PORT_Assert( ctx != NULL );
michael@0 304 if (ctx) {
michael@0 305 if (ctx->pattern)
michael@0 306 PORT_Free (ctx->pattern);
michael@0 307 PORT_Free (ctx);
michael@0 308 }
michael@0 309 }
michael@0 310
michael@0 311 /*
michael@0 312 * J A R _ f i n d _ n e x t
michael@0 313 *
michael@0 314 * Return the next item of the given type
michael@0 315 * from one of the JAR linked lists.
michael@0 316 *
michael@0 317 */
michael@0 318
michael@0 319 int JAR_find_next (JAR_Context *ctx, JAR_Item **it)
michael@0 320 {
michael@0 321 JAR *jar;
michael@0 322 ZZList *list = NULL;
michael@0 323 int finding;
michael@0 324 JAR_Signer *signer = NULL;
michael@0 325
michael@0 326 PORT_Assert( ctx != NULL );
michael@0 327 PORT_Assert( ctx->jar != NULL );
michael@0 328
michael@0 329 jar = ctx->jar;
michael@0 330
michael@0 331 /* Internally, convert jarTypeSign to jarTypeSF, and return
michael@0 332 the actual attached certificate later */
michael@0 333 finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding;
michael@0 334 if (ctx->nextsign) {
michael@0 335 if (ZZ_ListIterDone (jar->signers, ctx->nextsign)) {
michael@0 336 *it = NULL;
michael@0 337 return -1;
michael@0 338 }
michael@0 339 PORT_Assert (ctx->nextsign->thing != NULL);
michael@0 340 signer = (JAR_Signer*)ctx->nextsign->thing->data;
michael@0 341 }
michael@0 342
michael@0 343 /* Find out which linked list to traverse. Then if
michael@0 344 necessary, advance to the next linked list. */
michael@0 345 while (1) {
michael@0 346 switch (finding) {
michael@0 347 case jarTypeSign: /* not any more */
michael@0 348 PORT_Assert( finding != jarTypeSign );
michael@0 349 list = signer->certs;
michael@0 350 break;
michael@0 351
michael@0 352 case jarTypeSect:
michael@0 353 list = jar->manifest;
michael@0 354 break;
michael@0 355
michael@0 356 case jarTypePhy:
michael@0 357 list = jar->phy;
michael@0 358 break;
michael@0 359
michael@0 360 case jarTypeSF: /* signer, not jar */
michael@0 361 PORT_Assert( signer != NULL );
michael@0 362 list = signer ? signer->sf : NULL;
michael@0 363 break;
michael@0 364
michael@0 365 case jarTypeMF:
michael@0 366 list = jar->hashes;
michael@0 367 break;
michael@0 368
michael@0 369 case jarTypeOwner:
michael@0 370 list = jar->signers;
michael@0 371 break;
michael@0 372
michael@0 373 case jarTypeMeta:
michael@0 374 list = jar->metainfo;
michael@0 375 break;
michael@0 376
michael@0 377 default:
michael@0 378 PORT_Assert( 1 != 2 );
michael@0 379 list = NULL;
michael@0 380 break;
michael@0 381 }
michael@0 382 if (list == NULL) {
michael@0 383 *it = NULL;
michael@0 384 return -1;
michael@0 385 }
michael@0 386 /* When looping over lists of lists, advance to the next signer.
michael@0 387 This is done when multiple signers are possible. */
michael@0 388 if (ZZ_ListIterDone (list, ctx->next)) {
michael@0 389 if (ctx->nextsign && jar->signers) {
michael@0 390 ctx->nextsign = ctx->nextsign->next;
michael@0 391 if (!ZZ_ListIterDone (jar->signers, ctx->nextsign)) {
michael@0 392 PORT_Assert (ctx->nextsign->thing != NULL);
michael@0 393 signer = (JAR_Signer*)ctx->nextsign->thing->data;
michael@0 394 PORT_Assert( signer != NULL );
michael@0 395 ctx->next = NULL;
michael@0 396 continue;
michael@0 397 }
michael@0 398 }
michael@0 399 *it = NULL;
michael@0 400 return -1;
michael@0 401 }
michael@0 402
michael@0 403 /* if the signer changed, still need to fill in the "next" link */
michael@0 404 if (ctx->nextsign && ctx->next == NULL) {
michael@0 405 switch (finding) {
michael@0 406 case jarTypeSF:
michael@0 407 ctx->next = ZZ_ListHead (signer->sf);
michael@0 408 break;
michael@0 409
michael@0 410 case jarTypeSign:
michael@0 411 ctx->next = ZZ_ListHead (signer->certs);
michael@0 412 break;
michael@0 413 }
michael@0 414 }
michael@0 415 PORT_Assert( ctx->next != NULL );
michael@0 416 if (ctx->next == NULL) {
michael@0 417 *it = NULL;
michael@0 418 return -1;
michael@0 419 }
michael@0 420 while (!ZZ_ListIterDone (list, ctx->next)) {
michael@0 421 *it = ctx->next->thing;
michael@0 422 ctx->next = ctx->next->next;
michael@0 423 if (!*it || (*it)->type != finding)
michael@0 424 continue;
michael@0 425 if (ctx->pattern && *ctx->pattern) {
michael@0 426 if (PORT_RegExpSearch ((*it)->pathname, ctx->pattern))
michael@0 427 continue;
michael@0 428 }
michael@0 429 /* We have a valid match. If this is a jarTypeSign
michael@0 430 return the certificate instead.. */
michael@0 431 if (ctx->finding == jarTypeSign) {
michael@0 432 JAR_Item *itt;
michael@0 433
michael@0 434 /* just the first one for now */
michael@0 435 if (jar_find_first_cert (signer, jarTypeSign, &itt) >= 0) {
michael@0 436 *it = itt;
michael@0 437 return 0;
michael@0 438 }
michael@0 439 continue;
michael@0 440 }
michael@0 441 return 0;
michael@0 442 }
michael@0 443 } /* end while */
michael@0 444 }
michael@0 445
michael@0 446 static int
michael@0 447 jar_find_first_cert (JAR_Signer *signer, int type, JAR_Item **it)
michael@0 448 {
michael@0 449 ZZLink *link;
michael@0 450 ZZList *list = signer->certs;
michael@0 451 int status = JAR_ERR_PNF;
michael@0 452
michael@0 453 *it = NULL;
michael@0 454 if (ZZ_ListEmpty (list)) {
michael@0 455 /* empty list */
michael@0 456 return JAR_ERR_PNF;
michael@0 457 }
michael@0 458
michael@0 459 for (link = ZZ_ListHead (list);
michael@0 460 !ZZ_ListIterDone (list, link);
michael@0 461 link = link->next) {
michael@0 462 if (link->thing->type == type) {
michael@0 463 *it = link->thing;
michael@0 464 status = 0;
michael@0 465 break;
michael@0 466 }
michael@0 467 }
michael@0 468 return status;
michael@0 469 }
michael@0 470
michael@0 471 JAR_Signer *
michael@0 472 JAR_new_signer (void)
michael@0 473 {
michael@0 474 JAR_Signer *signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer));
michael@0 475 if (signer == NULL)
michael@0 476 goto loser;
michael@0 477
michael@0 478 /* certs */
michael@0 479 signer->certs = ZZ_NewList();
michael@0 480 if (signer->certs == NULL)
michael@0 481 goto loser;
michael@0 482
michael@0 483 /* sf */
michael@0 484 signer->sf = ZZ_NewList();
michael@0 485 if (signer->sf == NULL)
michael@0 486 goto loser;
michael@0 487 return signer;
michael@0 488
michael@0 489 loser:
michael@0 490 if (signer) {
michael@0 491 if (signer->certs)
michael@0 492 ZZ_DestroyList (signer->certs);
michael@0 493 if (signer->sf)
michael@0 494 ZZ_DestroyList (signer->sf);
michael@0 495 PORT_Free (signer);
michael@0 496 }
michael@0 497 return NULL;
michael@0 498 }
michael@0 499
michael@0 500 void
michael@0 501 JAR_destroy_signer(JAR_Signer *signer)
michael@0 502 {
michael@0 503 if (signer) {
michael@0 504 if (signer->owner)
michael@0 505 PORT_Free (signer->owner);
michael@0 506 if (signer->digest)
michael@0 507 PORT_Free (signer->digest);
michael@0 508 jar_destroy_list (signer->sf);
michael@0 509 ZZ_DestroyList (signer->sf);
michael@0 510 jar_destroy_list (signer->certs);
michael@0 511 ZZ_DestroyList (signer->certs);
michael@0 512 PORT_Free (signer);
michael@0 513 }
michael@0 514 }
michael@0 515
michael@0 516 JAR_Signer *
michael@0 517 jar_get_signer(JAR *jar, char *basename)
michael@0 518 {
michael@0 519 JAR_Item *it;
michael@0 520 JAR_Context *ctx = JAR_find (jar, NULL, jarTypeOwner);
michael@0 521 JAR_Signer *candidate;
michael@0 522 JAR_Signer *signer = NULL;
michael@0 523
michael@0 524 if (ctx == NULL)
michael@0 525 return NULL;
michael@0 526
michael@0 527 while (JAR_find_next (ctx, &it) >= 0) {
michael@0 528 candidate = (JAR_Signer *) it->data;
michael@0 529 if (*basename == '*' || !PORT_Strcmp (candidate->owner, basename)) {
michael@0 530 signer = candidate;
michael@0 531 break;
michael@0 532 }
michael@0 533 }
michael@0 534 JAR_find_end (ctx);
michael@0 535 return signer;
michael@0 536 }
michael@0 537
michael@0 538 /*
michael@0 539 * J A R _ g e t _ f i l e n a m e
michael@0 540 *
michael@0 541 * Returns the filename associated with
michael@0 542 * a JAR structure.
michael@0 543 *
michael@0 544 */
michael@0 545 char *
michael@0 546 JAR_get_filename(JAR *jar)
michael@0 547 {
michael@0 548 return jar->filename;
michael@0 549 }
michael@0 550
michael@0 551 /*
michael@0 552 * J A R _ g e t _ u r l
michael@0 553 *
michael@0 554 * Returns the URL associated with
michael@0 555 * a JAR structure. Nobody really uses this now.
michael@0 556 *
michael@0 557 */
michael@0 558 char *
michael@0 559 JAR_get_url(JAR *jar)
michael@0 560 {
michael@0 561 return jar->url;
michael@0 562 }
michael@0 563
michael@0 564 /*
michael@0 565 * J A R _ s e t _ c a l l b a c k
michael@0 566 *
michael@0 567 * Register some manner of callback function for this jar.
michael@0 568 *
michael@0 569 */
michael@0 570 int
michael@0 571 JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn)
michael@0 572 {
michael@0 573 if (type == JAR_CB_SIGNAL) {
michael@0 574 jar->signal = fn;
michael@0 575 return 0;
michael@0 576 }
michael@0 577 return -1;
michael@0 578 }
michael@0 579
michael@0 580 /*
michael@0 581 * Callbacks
michael@0 582 *
michael@0 583 */
michael@0 584
michael@0 585 /* To return an error string */
michael@0 586 char *(*jar_fn_GetString) (int) = NULL;
michael@0 587
michael@0 588 /* To return an MWContext for Java */
michael@0 589 void *(*jar_fn_FindSomeContext) (void) = NULL;
michael@0 590
michael@0 591 /* To fabricate an MWContext for FE_GetPassword */
michael@0 592 void *(*jar_fn_GetInitContext) (void) = NULL;
michael@0 593
michael@0 594 void
michael@0 595 JAR_init_callbacks(char *(*string_cb)(int),
michael@0 596 void *(*find_cx)(void),
michael@0 597 void *(*init_cx)(void))
michael@0 598 {
michael@0 599 jar_fn_GetString = string_cb;
michael@0 600 jar_fn_FindSomeContext = find_cx;
michael@0 601 jar_fn_GetInitContext = init_cx;
michael@0 602 }
michael@0 603
michael@0 604 /*
michael@0 605 * J A R _ g e t _ e r r o r
michael@0 606 *
michael@0 607 * This is provided to map internal JAR errors to strings for
michael@0 608 * the Java console. Also, a DLL may call this function if it does
michael@0 609 * not have access to the XP_GetString function.
michael@0 610 *
michael@0 611 * These strings aren't UI, since they are Java console only.
michael@0 612 *
michael@0 613 */
michael@0 614 char *
michael@0 615 JAR_get_error(int status)
michael@0 616 {
michael@0 617 char *errstring = NULL;
michael@0 618
michael@0 619 switch (status) {
michael@0 620 case JAR_ERR_GENERAL:
michael@0 621 errstring = "General JAR file error";
michael@0 622 break;
michael@0 623
michael@0 624 case JAR_ERR_FNF:
michael@0 625 errstring = "JAR file not found";
michael@0 626 break;
michael@0 627
michael@0 628 case JAR_ERR_CORRUPT:
michael@0 629 errstring = "Corrupt JAR file";
michael@0 630 break;
michael@0 631
michael@0 632 case JAR_ERR_MEMORY:
michael@0 633 errstring = "Out of memory";
michael@0 634 break;
michael@0 635
michael@0 636 case JAR_ERR_DISK:
michael@0 637 errstring = "Disk error (perhaps out of space)";
michael@0 638 break;
michael@0 639
michael@0 640 case JAR_ERR_ORDER:
michael@0 641 errstring = "Inconsistent files in META-INF directory";
michael@0 642 break;
michael@0 643
michael@0 644 case JAR_ERR_SIG:
michael@0 645 errstring = "Invalid digital signature file";
michael@0 646 break;
michael@0 647
michael@0 648 case JAR_ERR_METADATA:
michael@0 649 errstring = "JAR metadata failed verification";
michael@0 650 break;
michael@0 651
michael@0 652 case JAR_ERR_ENTRY:
michael@0 653 errstring = "No Manifest entry for this JAR entry";
michael@0 654 break;
michael@0 655
michael@0 656 case JAR_ERR_HASH:
michael@0 657 errstring = "Invalid Hash of this JAR entry";
michael@0 658 break;
michael@0 659
michael@0 660 case JAR_ERR_PK7:
michael@0 661 errstring = "Strange PKCS7 or RSA failure";
michael@0 662 break;
michael@0 663
michael@0 664 case JAR_ERR_PNF:
michael@0 665 errstring = "Path not found inside JAR file";
michael@0 666 break;
michael@0 667
michael@0 668 default:
michael@0 669 if (jar_fn_GetString) {
michael@0 670 errstring = jar_fn_GetString (status);
michael@0 671 } else {
michael@0 672 /* this is not a normal situation, and would only be
michael@0 673 called in cases of improper initialization */
michael@0 674 char *err = (char*)PORT_Alloc (40);
michael@0 675 if (err)
michael@0 676 PR_snprintf (err, 39, "Error %d\n", status); /* leak me! */
michael@0 677 else
michael@0 678 err = "Error! Bad! Out of memory!";
michael@0 679 return err;
michael@0 680 }
michael@0 681 break;
michael@0 682 }
michael@0 683 return errstring;
michael@0 684 }

mercurial