/************************************************************************* * * V e r i f y J a r */ int VerifyJar(char *filename) { FILE *fp; int ret; int status; int failed = 0; char *err; JAR *jar; JAR_Context *ctx; JAR_Item *it; jar = JAR_new(); if ((fp = fopen(filename, "r")) == NULL) { perror(filename); exit(ERRX); } else fclose(fp); JAR_set_callback(JAR_CB_SIGNAL, jar, jar_cb); status = JAR_pass_archive(jar, jarArchGuess, filename, "some-url"); if (status < 0 || jar->valid < 0) { failed = 1; PR_fprintf(outputFD, "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n", filename); if (status < 0) { const char *errtext; if (status >= JAR_BASE && status <= JAR_BASE_END) { errtext = JAR_get_error(status); } else { errtext = SECU_Strerror(PORT_GetError()); } PR_fprintf(outputFD, " (reported reason: %s)\n\n", errtext); /* corrupt files should not have their contents listed */ if (status == JAR_ERR_CORRUPT) return -1; } PR_fprintf(outputFD, "entries shown below will have their digests checked only.\n"); jar->valid = 0; } else PR_fprintf(outputFD, "archive \"%s\" has passed crypto verification.\n", filename); if (verify_global(jar)) failed = 1; PR_fprintf(outputFD, "\n"); PR_fprintf(outputFD, "%16s %s\n", "status", "path"); PR_fprintf(outputFD, "%16s %s\n", "------------", "-------------------"); ctx = JAR_find(jar, NULL, jarTypeMF); while (JAR_find_next(ctx, &it) >= 0) { if (it && it->pathname) { rm_dash_r(TMP_OUTPUT); ret = JAR_verified_extract(jar, it->pathname, TMP_OUTPUT); /* if (ret < 0) printf ("error %d on %s\n", ret, it->pathname); */ if (ret < 0) failed = 1; if (ret == JAR_ERR_PNF) err = "NOT PRESENT"; else if (ret == JAR_ERR_HASH) err = "HASH FAILED"; else err = "NOT VERIFIED"; PR_fprintf(outputFD, "%16s %s\n", ret >= 0 ? "verified" : err, it->pathname); if (ret != 0 && ret != JAR_ERR_PNF && ret != JAR_ERR_HASH) PR_fprintf(outputFD, " (reason: %s)\n", JAR_get_error(ret)); } } JAR_find_end(ctx); if (status < 0 || jar->valid < 0) { failed = 1; PR_fprintf(outputFD, "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n", filename); give_help(status); } JAR_destroy(jar); if (failed) return -1; return 0; }
/************************************************************************ * * J a r W h o */ int JarWho(char *filename) { FILE *fp; JAR *jar; JAR_Context *ctx; int status; int retval = 0; JAR_Item *it; JAR_Cert *fing; CERTCertificate *cert, *prev = NULL; jar = JAR_new(); if ((fp = fopen(filename, "r")) == NULL) { perror(filename); exit(ERRX); } fclose(fp); status = JAR_pass_archive(jar, jarArchGuess, filename, "some-url"); if (status < 0 || jar->valid < 0) { PR_fprintf(outputFD, "NOTE -- \"%s\" archive DID NOT PASS crypto verification.\n", filename); retval = -1; if (jar->valid < 0 || status != -1) { const char *errtext; if (status >= JAR_BASE && status <= JAR_BASE_END) { errtext = JAR_get_error(status); } else { errtext = SECU_Strerror(PORT_GetError()); } PR_fprintf(outputFD, " (reported reason: %s)\n\n", errtext); } } PR_fprintf(outputFD, "\nSigner information:\n\n"); ctx = JAR_find(jar, NULL, jarTypeSign); while (JAR_find_next(ctx, &it) >= 0) { fing = (JAR_Cert *)it->data; cert = fing->cert; if (cert) { if (prev == cert) break; if (cert->nickname) PR_fprintf(outputFD, "nickname: %s\n", cert->nickname); if (cert->subjectName) PR_fprintf(outputFD, "subject name: %s\n", cert->subjectName); if (cert->issuerName) PR_fprintf(outputFD, "issuer name: %s\n", cert->issuerName); } else { PR_fprintf(outputFD, "no certificate could be found\n"); retval = -1; } prev = cert; } JAR_find_end(ctx); JAR_destroy(jar); return retval; }
/************************************************************************* * * P k 1 1 I n s t a l l _ D o I n s t a l l * * jarFile is the path of a JAR in the PKCS #11 module JAR format. * installDir is the directory relative to which files will be * installed. */ Pk11Install_Error Pk11Install_DoInstall(char *jarFile, const char *installDir, const char *tempDir, PRFileDesc *feedback, short force, PRBool noverify) { JAR *jar; char *installer; unsigned long installer_len; int status; Pk11Install_Error ret; PRBool made_temp_file; Pk11Install_Info installInfo; Pk11Install_Platform *platform; char *errMsg; char sysname[SYS_INFO_BUFFER_LENGTH], release[SYS_INFO_BUFFER_LENGTH], arch[SYS_INFO_BUFFER_LENGTH]; char *myPlatform; jar = NULL; ret = PK11_INSTALL_UNSPECIFIED; made_temp_file = PR_FALSE; errMsg = NULL; Pk11Install_Info_init(&installInfo); /* printf("Inside DoInstall, jarFile=%s, installDir=%s, tempDir=%s\n", jarFile, installDir, tempDir); */ /* * Check out jarFile and installDir for validity */ if (PR_Access(installDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { error(PK11_INSTALL_DIR_DOESNT_EXIST, installDir); return PK11_INSTALL_DIR_DOESNT_EXIST; } if (!tempDir) { tempDir = "."; } if (PR_Access(tempDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { error(PK11_INSTALL_DIR_DOESNT_EXIST, tempDir); return PK11_INSTALL_DIR_DOESNT_EXIST; } if (PR_Access(tempDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) { error(PK11_INSTALL_DIR_NOT_WRITEABLE, tempDir); return PK11_INSTALL_DIR_NOT_WRITEABLE; } if ((PR_Access(jarFile, PR_ACCESS_EXISTS) != PR_SUCCESS)) { error(PK11_INSTALL_FILE_DOESNT_EXIST, jarFile); return PK11_INSTALL_FILE_DOESNT_EXIST; } if (PR_Access(jarFile, PR_ACCESS_READ_OK) != PR_SUCCESS) { error(PK11_INSTALL_FILE_NOT_READABLE, jarFile); return PK11_INSTALL_FILE_NOT_READABLE; } /* * Extract the JAR file */ jar = JAR_new(); JAR_set_callback(JAR_CB_SIGNAL, jar, jar_callback); if (noverify) { status = JAR_pass_archive_unverified(jar, jarArchGuess, jarFile, "url"); } else { status = JAR_pass_archive(jar, jarArchGuess, jarFile, "url"); } if ((status < 0) || (jar->valid < 0)) { if (status >= JAR_BASE && status <= JAR_BASE_END) { error(PK11_INSTALL_JAR_ERROR, jarFile, JAR_get_error(status)); } else { error(PK11_INSTALL_JAR_ERROR, jarFile, mySECU_ErrorString(PORT_GetError())); } ret = PK11_INSTALL_JAR_ERROR; goto loser; } /*printf("passed the archive\n");*/ /* * Show the user security information, allow them to abort or continue */ if (Pk11Install_UserVerifyJar(jar, PR_STDOUT, force ? PR_FALSE : PR_TRUE) && !force) { if (feedback) { PR_fprintf(feedback, msgStrings[USER_ABORT]); } ret = PK11_INSTALL_USER_ABORT; goto loser; } /* * Get the name of the installation file */ if (JAR_get_metainfo(jar, NULL, INSTALL_METAINFO_TAG, (void **)&installer, (unsigned long *)&installer_len)) { error(PK11_INSTALL_NO_INSTALLER_SCRIPT); ret = PK11_INSTALL_NO_INSTALLER_SCRIPT; goto loser; } if (feedback) { PR_fprintf(feedback, msgStrings[INSTALLER_SCRIPT_NAME], installer); } /* * Extract the installation file */ if (PR_Access(SCRIPT_TEMP_FILE, PR_ACCESS_EXISTS) == PR_SUCCESS) { if (PR_Delete(SCRIPT_TEMP_FILE) != PR_SUCCESS) { error(PK11_INSTALL_DELETE_TEMP_FILE, SCRIPT_TEMP_FILE); ret = PK11_INSTALL_DELETE_TEMP_FILE; goto loser; } } if (noverify) { status = JAR_extract(jar, installer, SCRIPT_TEMP_FILE); } else { status = JAR_verified_extract(jar, installer, SCRIPT_TEMP_FILE); } if (status) { if (status >= JAR_BASE && status <= JAR_BASE_END) { error(PK11_INSTALL_JAR_EXTRACT, installer, JAR_get_error(status)); } else { error(PK11_INSTALL_JAR_EXTRACT, installer, mySECU_ErrorString(PORT_GetError())); } ret = PK11_INSTALL_JAR_EXTRACT; goto loser; } else { made_temp_file = PR_TRUE; } /* * Parse the installation file into a syntax tree */ Pk11Install_FD = PR_Open(SCRIPT_TEMP_FILE, PR_RDONLY, 0); if (!Pk11Install_FD) { error(PK11_INSTALL_OPEN_SCRIPT_FILE, SCRIPT_TEMP_FILE); ret = PK11_INSTALL_OPEN_SCRIPT_FILE; goto loser; } if (Pk11Install_yyparse()) { error(PK11_INSTALL_SCRIPT_PARSE, installer, Pk11Install_yyerrstr ? Pk11Install_yyerrstr : ""); ret = PK11_INSTALL_SCRIPT_PARSE; goto loser; } #if 0 /* for debugging */ Pk11Install_valueList->Print(0); #endif /* * From the syntax tree, build a semantic structure */ errMsg = Pk11Install_Info_Generate(&installInfo, Pk11Install_valueList); if (errMsg) { error(PK11_INSTALL_SEMANTIC, errMsg); ret = PK11_INSTALL_SEMANTIC; goto loser; } #if 0 installInfo.Print(0); #endif if (feedback) { PR_fprintf(feedback, msgStrings[PARSED_INSTALL_SCRIPT]); } /* * Figure out which platform to use */ { sysname[0] = release[0] = arch[0] = '\0'; if ((PR_GetSystemInfo(PR_SI_SYSNAME, sysname, SYS_INFO_BUFFER_LENGTH) != PR_SUCCESS) || (PR_GetSystemInfo(PR_SI_RELEASE, release, SYS_INFO_BUFFER_LENGTH) != PR_SUCCESS) || (PR_GetSystemInfo(PR_SI_ARCHITECTURE, arch, SYS_INFO_BUFFER_LENGTH) != PR_SUCCESS)) { error(PK11_INSTALL_SYSINFO); ret = PK11_INSTALL_SYSINFO; goto loser; } myPlatform = PR_smprintf("%s:%s:%s", sysname, release, arch); platform = Pk11Install_Info_GetBestPlatform(&installInfo, myPlatform); if (!platform) { error(PK11_INSTALL_NO_PLATFORM, myPlatform); PR_smprintf_free(myPlatform); ret = PK11_INSTALL_NO_PLATFORM; goto loser; } if (feedback) { PR_fprintf(feedback, msgStrings[MY_PLATFORM_IS], myPlatform); PR_fprintf(feedback, msgStrings[USING_PLATFORM], Pk11Install_PlatformName_GetString(&platform->name)); } PR_smprintf_free(myPlatform); } /* Run the install for that platform */ ret = DoInstall(jar, installDir, tempDir, platform, feedback, noverify); if (ret) { goto loser; } ret = PK11_INSTALL_SUCCESS; loser: if (Pk11Install_valueList) { Pk11Install_ValueList_delete(Pk11Install_valueList); PR_Free(Pk11Install_valueList); Pk11Install_valueList = NULL; } if (jar) { JAR_destroy(jar); } if (made_temp_file) { PR_Delete(SCRIPT_TEMP_FILE); } if (errMsg) { PR_smprintf_free(errMsg); } return ret; }