698
699 // changes the basename, returns "this"
700 JarFileEntry withBasename(String name) {
701 basename = name;
702 return this;
703 }
704 }
705
706 /*
707 * Ensures that the JarVerifier has been created if one is
708 * necessary (i.e., the jar appears to be signed.) This is done as
709 * a quick check to avoid processing of the manifest for unsigned
710 * jars.
711 */
712 private void maybeInstantiateVerifier() throws IOException {
713 if (jv != null) {
714 return;
715 }
716
717 if (verify) {
718 String[] names = JUZFA.getMetaInfEntryNames(this);
719 if (names != null) {
720 for (String nameLower : names) {
721 String name = nameLower.toUpperCase(Locale.ENGLISH);
722 if (name.endsWith(".DSA") ||
723 name.endsWith(".RSA") ||
724 name.endsWith(".EC") ||
725 name.endsWith(".SF")) {
726 // Assume since we found a signature-related file
727 // that the jar is signed and that we therefore
728 // need a JarVerifier and Manifest
729 getManifest();
730 return;
731 }
732 }
733 }
734 // No signature-related files; don't instantiate a
735 // verifier
736 verify = false;
737 }
738 }
739
740 /*
741 * Initializes the verifier object by reading all the manifest
742 * entries and passing them to the verifier.
743 */
744 private void initializeVerifier() {
745 ManifestEntryVerifier mev = null;
746
747 // Verify "META-INF/" entries...
748 try {
749 String[] names = JUZFA.getMetaInfEntryNames(this);
750 if (names != null) {
751 for (String name : names) {
752 String uname = name.toUpperCase(Locale.ENGLISH);
753 if (MANIFEST_NAME.equals(uname)
754 || SignatureFileVerifier.isBlockOrSF(uname)) {
755 JarEntry e = getJarEntry(name);
756 if (e == null) {
757 throw new JarException("corrupted jar file");
758 }
759 if (mev == null) {
760 mev = new ManifestEntryVerifier
761 (getManifestFromReference());
762 }
763 byte[] b = getBytes(e);
764 if (b != null && b.length > 0) {
765 jv.beginEntry(e, mev);
766 jv.update(b.length, b, 0, b.length, mev);
767 jv.update(-1, null, 0, 0, mev);
768 }
769 }
770 }
771 }
772 } catch (IOException ex) {
773 // if we had an error parsing any blocks, just
774 // treat the jar file as being unsigned
775 jv = null;
776 verify = false;
777 if (JarVerifier.debug != null) {
778 JarVerifier.debug.println("jarfile parsing error!");
779 ex.printStackTrace();
780 }
781 }
782
783 // if after initializing the verifier we have nothing
784 // signed, we null it out.
785
786 if (jv != null) {
787
788 jv.doneWithMeta();
789 if (JarVerifier.debug != null) {
790 JarVerifier.debug.println("done with meta!");
791 }
923 MULTIRELEASE_LASTOCC[(int)':' - 32] = 14;
924 MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15;
925 MULTIRELEASE_LASTOCC[(int)'T' - 32] = 16;
926 MULTIRELEASE_LASTOCC[(int)'R' - 32] = 17;
927 MULTIRELEASE_LASTOCC[(int)'U' - 32] = 18;
928 MULTIRELEASE_LASTOCC[(int)'E' - 32] = 19;
929 for (int i = 0; i < 17; i++) {
930 MULTIRELEASE_OPTOSFT[i] = 19;
931 }
932 MULTIRELEASE_OPTOSFT[17] = 6;
933 MULTIRELEASE_OPTOSFT[18] = 1;
934 }
935
936 private JarEntry getManEntry() {
937 if (manEntry == null) {
938 // First look up manifest entry using standard name
939 JarEntry manEntry = getEntry0(MANIFEST_NAME);
940 if (manEntry == null) {
941 // If not found, then iterate through all the "META-INF/"
942 // entries to find a match.
943 String[] names = JUZFA.getMetaInfEntryNames(this);
944 if (names != null) {
945 for (String name : names) {
946 if (MANIFEST_NAME.equals(name.toUpperCase(Locale.ENGLISH))) {
947 manEntry = getEntry0(name);
948 break;
949 }
950 }
951 }
952 }
953 this.manEntry = manEntry;
954 }
955 return manEntry;
956 }
957
958 /**
959 * Returns {@code true} iff this JAR file has a manifest with the
960 * Class-Path attribute
961 */
962 boolean hasClassPathAttribute() throws IOException {
963 checkForSpecialAttributes();
964 return hasClassPathAttribute;
965 }
966
967 /**
968 * Returns true if the pattern {@code src} is found in {@code b}.
969 * The {@code lastOcc} array is the precomputed bad character shifts.
970 * Since there are no repeated substring in our search strings,
1196 return true;
1197 }
1198 return false;
1199 }
1200
1201 public String nextElement() {
1202 if (hasMoreElements()) {
1203 String value = name;
1204 name = null;
1205 return value;
1206 }
1207 throw new NoSuchElementException();
1208 }
1209 };
1210 }
1211
1212 CodeSource getCodeSource(URL url, String name) {
1213 ensureInitialization();
1214 if (jv != null) {
1215 if (jv.eagerValidation) {
1216 CodeSource cs = null;
1217 JarEntry je = getJarEntry(name);
1218 if (je != null) {
1219 cs = jv.getCodeSource(url, this, je);
1220 } else {
1221 cs = jv.getCodeSource(url, name);
1222 }
1223 return cs;
1224 } else {
1225 return jv.getCodeSource(url, name);
1226 }
1227 }
1228
1229 return JarVerifier.getUnsignedCS(url);
1230 }
1231
1232 void setEagerValidation(boolean eager) {
1233 try {
1234 maybeInstantiateVerifier();
1235 } catch (IOException e) {
1236 throw new RuntimeException(e);
|
698
699 // changes the basename, returns "this"
700 JarFileEntry withBasename(String name) {
701 basename = name;
702 return this;
703 }
704 }
705
706 /*
707 * Ensures that the JarVerifier has been created if one is
708 * necessary (i.e., the jar appears to be signed.) This is done as
709 * a quick check to avoid processing of the manifest for unsigned
710 * jars.
711 */
712 private void maybeInstantiateVerifier() throws IOException {
713 if (jv != null) {
714 return;
715 }
716
717 if (verify) {
718 // Gets the manifest name, but only if there are
719 // signature-related files. If so we can assume
720 // that the jar is signed and that we therefore
721 // need a JarVerifier and Manifest
722 String name = JUZFA.getManifestName(this, true);
723 if (name != null) {
724 manEntry = getEntry0(name);
725 getManifest();
726 return;
727 }
728 // No signature-related files; don't instantiate a
729 // verifier
730 verify = false;
731 }
732 }
733
734
735 /*
736 * Initializes the verifier object by reading all the manifest
737 * entries and passing them to the verifier.
738 */
739 private void initializeVerifier() {
740 ManifestEntryVerifier mev = null;
741
742 // Verify "META-INF/" entries...
743 try {
744 List<String> names = JUZFA.getManifestAndSignatureRelatedFiles(this);
745 for (String name : names) {
746 JarEntry e = getJarEntry(name);
747 if (e == null) {
748 throw new JarException("corrupted jar file");
749 }
750 if (mev == null) {
751 mev = new ManifestEntryVerifier
752 (getManifestFromReference());
753 }
754 byte[] b = getBytes(e);
755 if (b != null && b.length > 0) {
756 jv.beginEntry(e, mev);
757 jv.update(b.length, b, 0, b.length, mev);
758 jv.update(-1, null, 0, 0, mev);
759 }
760 }
761 } catch (IOException ex) {
762 // if we had an error parsing any blocks, just
763 // treat the jar file as being unsigned
764 jv = null;
765 verify = false;
766 if (JarVerifier.debug != null) {
767 JarVerifier.debug.println("jarfile parsing error!");
768 ex.printStackTrace();
769 }
770 }
771
772 // if after initializing the verifier we have nothing
773 // signed, we null it out.
774
775 if (jv != null) {
776
777 jv.doneWithMeta();
778 if (JarVerifier.debug != null) {
779 JarVerifier.debug.println("done with meta!");
780 }
912 MULTIRELEASE_LASTOCC[(int)':' - 32] = 14;
913 MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15;
914 MULTIRELEASE_LASTOCC[(int)'T' - 32] = 16;
915 MULTIRELEASE_LASTOCC[(int)'R' - 32] = 17;
916 MULTIRELEASE_LASTOCC[(int)'U' - 32] = 18;
917 MULTIRELEASE_LASTOCC[(int)'E' - 32] = 19;
918 for (int i = 0; i < 17; i++) {
919 MULTIRELEASE_OPTOSFT[i] = 19;
920 }
921 MULTIRELEASE_OPTOSFT[17] = 6;
922 MULTIRELEASE_OPTOSFT[18] = 1;
923 }
924
925 private JarEntry getManEntry() {
926 if (manEntry == null) {
927 // First look up manifest entry using standard name
928 JarEntry manEntry = getEntry0(MANIFEST_NAME);
929 if (manEntry == null) {
930 // If not found, then iterate through all the "META-INF/"
931 // entries to find a match.
932 String name = JUZFA.getManifestName(this, false);
933 if (name != null) {
934 manEntry = getEntry0(name);
935 }
936 }
937 this.manEntry = manEntry;
938 }
939 return manEntry;
940 }
941
942 /**
943 * Returns {@code true} iff this JAR file has a manifest with the
944 * Class-Path attribute
945 */
946 boolean hasClassPathAttribute() throws IOException {
947 checkForSpecialAttributes();
948 return hasClassPathAttribute;
949 }
950
951 /**
952 * Returns true if the pattern {@code src} is found in {@code b}.
953 * The {@code lastOcc} array is the precomputed bad character shifts.
954 * Since there are no repeated substring in our search strings,
1180 return true;
1181 }
1182 return false;
1183 }
1184
1185 public String nextElement() {
1186 if (hasMoreElements()) {
1187 String value = name;
1188 name = null;
1189 return value;
1190 }
1191 throw new NoSuchElementException();
1192 }
1193 };
1194 }
1195
1196 CodeSource getCodeSource(URL url, String name) {
1197 ensureInitialization();
1198 if (jv != null) {
1199 if (jv.eagerValidation) {
1200 CodeSource cs;
1201 JarEntry je = getJarEntry(name);
1202 if (je != null) {
1203 cs = jv.getCodeSource(url, this, je);
1204 } else {
1205 cs = jv.getCodeSource(url, name);
1206 }
1207 return cs;
1208 } else {
1209 return jv.getCodeSource(url, name);
1210 }
1211 }
1212
1213 return JarVerifier.getUnsignedCS(url);
1214 }
1215
1216 void setEagerValidation(boolean eager) {
1217 try {
1218 maybeInstantiateVerifier();
1219 } catch (IOException e) {
1220 throw new RuntimeException(e);
|