jdk/src/share/classes/java/util/jar/JarVerifier.java
changeset 11841 38a39c748880
parent 11119 6ff03c1202ce
child 13795 73850c397272
equal deleted inserted replaced
11840:dfd8edddd85f 11841:38a39c748880
    46     /* Are we debugging ? */
    46     /* Are we debugging ? */
    47     static final Debug debug = Debug.getInstance("jar");
    47     static final Debug debug = Debug.getInstance("jar");
    48 
    48 
    49     /* a table mapping names to code signers, for jar entries that have
    49     /* a table mapping names to code signers, for jar entries that have
    50        had their actual hashes verified */
    50        had their actual hashes verified */
    51     private Hashtable verifiedSigners;
    51     private Hashtable<String, CodeSigner[]> verifiedSigners;
    52 
    52 
    53     /* a table mapping names to code signers, for jar entries that have
    53     /* a table mapping names to code signers, for jar entries that have
    54        passed the .SF/.DSA/.EC -> MANIFEST check */
    54        passed the .SF/.DSA/.EC -> MANIFEST check */
    55     private Hashtable sigFileSigners;
    55     private Hashtable<String, CodeSigner[]> sigFileSigners;
    56 
    56 
    57     /* a hash table to hold .SF bytes */
    57     /* a hash table to hold .SF bytes */
    58     private Hashtable sigFileData;
    58     private Hashtable<String, byte[]> sigFileData;
    59 
    59 
    60     /** "queue" of pending PKCS7 blocks that we couldn't parse
    60     /** "queue" of pending PKCS7 blocks that we couldn't parse
    61      *  until we parsed the .SF file */
    61      *  until we parsed the .SF file */
    62     private ArrayList pendingBlocks;
    62     private ArrayList<SignatureFileVerifier> pendingBlocks;
    63 
    63 
    64     /* cache of CodeSigner objects */
    64     /* cache of CodeSigner objects */
    65     private ArrayList signerCache;
    65     private ArrayList<CodeSigner[]> signerCache;
    66 
    66 
    67     /* Are we parsing a block? */
    67     /* Are we parsing a block? */
    68     private boolean parsingBlockOrSF = false;
    68     private boolean parsingBlockOrSF = false;
    69 
    69 
    70     /* Are we done parsing META-INF entries? */
    70     /* Are we done parsing META-INF entries? */
    92     /** collect -DIGEST-MANIFEST values for blacklist */
    92     /** collect -DIGEST-MANIFEST values for blacklist */
    93     private List<Object> manifestDigests;
    93     private List<Object> manifestDigests;
    94 
    94 
    95     public JarVerifier(byte rawBytes[]) {
    95     public JarVerifier(byte rawBytes[]) {
    96         manifestRawBytes = rawBytes;
    96         manifestRawBytes = rawBytes;
    97         sigFileSigners = new Hashtable();
    97         sigFileSigners = new Hashtable<>();
    98         verifiedSigners = new Hashtable();
    98         verifiedSigners = new Hashtable<>();
    99         sigFileData = new Hashtable(11);
    99         sigFileData = new Hashtable<>(11);
   100         pendingBlocks = new ArrayList();
   100         pendingBlocks = new ArrayList<>();
   101         baos = new ByteArrayOutputStream();
   101         baos = new ByteArrayOutputStream();
   102         manifestDigests = new ArrayList<>();
   102         manifestDigests = new ArrayList<>();
   103     }
   103     }
   104 
   104 
   105     /**
   105     /**
   246                     byte bytes[] = baos.toByteArray();
   246                     byte bytes[] = baos.toByteArray();
   247                     // add to sigFileData in case future blocks need it
   247                     // add to sigFileData in case future blocks need it
   248                     sigFileData.put(key, bytes);
   248                     sigFileData.put(key, bytes);
   249                     // check pending blocks, we can now process
   249                     // check pending blocks, we can now process
   250                     // anyone waiting for this .SF file
   250                     // anyone waiting for this .SF file
   251                     Iterator it = pendingBlocks.iterator();
   251                     Iterator<SignatureFileVerifier> it = pendingBlocks.iterator();
   252                     while (it.hasNext()) {
   252                     while (it.hasNext()) {
   253                         SignatureFileVerifier sfv =
   253                         SignatureFileVerifier sfv = it.next();
   254                             (SignatureFileVerifier) it.next();
       
   255                         if (sfv.needSignatureFile(key)) {
   254                         if (sfv.needSignatureFile(key)) {
   256                             if (debug != null) {
   255                             if (debug != null) {
   257                                 debug.println(
   256                                 debug.println(
   258                                  "processEntry: processing pending block");
   257                                  "processEntry: processing pending block");
   259                             }
   258                             }
   268                 // now we are parsing a signature block file
   267                 // now we are parsing a signature block file
   269 
   268 
   270                 String key = uname.substring(0, uname.lastIndexOf("."));
   269                 String key = uname.substring(0, uname.lastIndexOf("."));
   271 
   270 
   272                 if (signerCache == null)
   271                 if (signerCache == null)
   273                     signerCache = new ArrayList();
   272                     signerCache = new ArrayList<>();
   274 
   273 
   275                 if (manDig == null) {
   274                 if (manDig == null) {
   276                     synchronized(manifestRawBytes) {
   275                     synchronized(manifestRawBytes) {
   277                         if (manDig == null) {
   276                         if (manDig == null) {
   278                             manDig = new ManifestDigester(manifestRawBytes);
   277                             manDig = new ManifestDigester(manifestRawBytes);
   285                   new SignatureFileVerifier(signerCache,
   284                   new SignatureFileVerifier(signerCache,
   286                                             manDig, uname, baos.toByteArray());
   285                                             manDig, uname, baos.toByteArray());
   287 
   286 
   288                 if (sfv.needSignatureFileBytes()) {
   287                 if (sfv.needSignatureFileBytes()) {
   289                     // see if we have already parsed an external .SF file
   288                     // see if we have already parsed an external .SF file
   290                     byte[] bytes = (byte[]) sigFileData.get(key);
   289                     byte[] bytes = sigFileData.get(key);
   291 
   290 
   292                     if (bytes == null) {
   291                     if (bytes == null) {
   293                         // put this block on queue for later processing
   292                         // put this block on queue for later processing
   294                         // since we don't have the .SF bytes yet
   293                         // since we don't have the .SF bytes yet
   295                         // (uname, block);
   294                         // (uname, block);
   341      * the given file in the jar. this array is not cloned.
   340      * the given file in the jar. this array is not cloned.
   342      *
   341      *
   343      */
   342      */
   344     public CodeSigner[] getCodeSigners(String name)
   343     public CodeSigner[] getCodeSigners(String name)
   345     {
   344     {
   346         return (CodeSigner[])verifiedSigners.get(name);
   345         return verifiedSigners.get(name);
   347     }
   346     }
   348 
   347 
   349     public CodeSigner[] getCodeSigners(JarFile jar, JarEntry entry)
   348     public CodeSigner[] getCodeSigners(JarFile jar, JarEntry entry)
   350     {
   349     {
   351         String name = entry.getName();
   350         String name = entry.getName();
   374      */
   373      */
   375     private static java.security.cert.Certificate[] mapSignersToCertArray(
   374     private static java.security.cert.Certificate[] mapSignersToCertArray(
   376         CodeSigner[] signers) {
   375         CodeSigner[] signers) {
   377 
   376 
   378         if (signers != null) {
   377         if (signers != null) {
   379             ArrayList certChains = new ArrayList();
   378             ArrayList<java.security.cert.Certificate> certChains = new ArrayList<>();
   380             for (int i = 0; i < signers.length; i++) {
   379             for (int i = 0; i < signers.length; i++) {
   381                 certChains.addAll(
   380                 certChains.addAll(
   382                     signers[i].getSignerCertPath().getCertificates());
   381                     signers[i].getSignerCertPath().getCertificates());
   383             }
   382             }
   384 
   383 
   385             // Convert into a Certificate[]
   384             // Convert into a Certificate[]
   386             return (java.security.cert.Certificate[])
   385             return certChains.toArray(
   387                 certChains.toArray(
       
   388                     new java.security.cert.Certificate[certChains.size()]);
   386                     new java.security.cert.Certificate[certChains.size()]);
   389         }
   387         }
   390         return null;
   388         return null;
   391     }
   389     }
   392 
   390 
   416         signerCache = null;
   414         signerCache = null;
   417         manDig = null;
   415         manDig = null;
   418         // MANIFEST.MF is always treated as signed and verified,
   416         // MANIFEST.MF is always treated as signed and verified,
   419         // move its signers from sigFileSigners to verifiedSigners.
   417         // move its signers from sigFileSigners to verifiedSigners.
   420         if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) {
   418         if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) {
   421             verifiedSigners.put(JarFile.MANIFEST_NAME,
   419             CodeSigner[] codeSigners = sigFileSigners.remove(JarFile.MANIFEST_NAME);
   422                     sigFileSigners.remove(JarFile.MANIFEST_NAME));
   420             verifiedSigners.put(JarFile.MANIFEST_NAME, codeSigners);
   423         }
   421         }
   424     }
   422     }
   425 
   423 
   426     static class VerifierStream extends java.io.InputStream {
   424     static class VerifierStream extends java.io.InputStream {
   427 
   425 
   491 
   489 
   492     }
   490     }
   493 
   491 
   494     // Extended JavaUtilJarAccess CodeSource API Support
   492     // Extended JavaUtilJarAccess CodeSource API Support
   495 
   493 
   496     private Map urlToCodeSourceMap = new HashMap();
   494     private Map<URL, Map<CodeSigner[], CodeSource>> urlToCodeSourceMap = new HashMap<>();
   497     private Map signerToCodeSource = new HashMap();
   495     private Map<CodeSigner[], CodeSource> signerToCodeSource = new HashMap<>();
   498     private URL lastURL;
   496     private URL lastURL;
   499     private Map lastURLMap;
   497     private Map<CodeSigner[], CodeSource> lastURLMap;
   500 
   498 
   501     /*
   499     /*
   502      * Create a unique mapping from codeSigner cache entries to CodeSource.
   500      * Create a unique mapping from codeSigner cache entries to CodeSource.
   503      * In theory, multiple URLs origins could map to a single locally cached
   501      * In theory, multiple URLs origins could map to a single locally cached
   504      * and shared JAR file although in practice there will be a single URL in use.
   502      * and shared JAR file although in practice there will be a single URL in use.
   505      */
   503      */
   506     private synchronized CodeSource mapSignersToCodeSource(URL url, CodeSigner[] signers) {
   504     private synchronized CodeSource mapSignersToCodeSource(URL url, CodeSigner[] signers) {
   507         Map map;
   505         Map<CodeSigner[], CodeSource> map;
   508         if (url == lastURL) {
   506         if (url == lastURL) {
   509             map = lastURLMap;
   507             map = lastURLMap;
   510         } else {
   508         } else {
   511             map = (Map) urlToCodeSourceMap.get(url);
   509             map = urlToCodeSourceMap.get(url);
   512             if (map == null) {
   510             if (map == null) {
   513                 map = new HashMap();
   511                 map = new HashMap<>();
   514                 urlToCodeSourceMap.put(url, map);
   512                 urlToCodeSourceMap.put(url, map);
   515             }
   513             }
   516             lastURLMap = map;
   514             lastURLMap = map;
   517             lastURL = url;
   515             lastURL = url;
   518         }
   516         }
   519         CodeSource cs = (CodeSource) map.get(signers);
   517         CodeSource cs = map.get(signers);
   520         if (cs == null) {
   518         if (cs == null) {
   521             cs = new VerifierCodeSource(csdomain, url, signers);
   519             cs = new VerifierCodeSource(csdomain, url, signers);
   522             signerToCodeSource.put(signers, cs);
   520             signerToCodeSource.put(signers, cs);
   523         }
   521         }
   524         return cs;
   522         return cs;
   525     }
   523     }
   526 
   524 
   527     private CodeSource[] mapSignersToCodeSources(URL url, List signers, boolean unsigned) {
   525     private CodeSource[] mapSignersToCodeSources(URL url, List<CodeSigner[]> signers, boolean unsigned) {
   528         List sources = new ArrayList();
   526         List<CodeSource> sources = new ArrayList<>();
   529 
   527 
   530         for (int i = 0; i < signers.size(); i++) {
   528         for (int i = 0; i < signers.size(); i++) {
   531             sources.add(mapSignersToCodeSource(url, (CodeSigner[]) signers.get(i)));
   529             sources.add(mapSignersToCodeSource(url, signers.get(i)));
   532         }
   530         }
   533         if (unsigned) {
   531         if (unsigned) {
   534             sources.add(mapSignersToCodeSource(url, null));
   532             sources.add(mapSignersToCodeSource(url, null));
   535         }
   533         }
   536         return (CodeSource[]) sources.toArray(new CodeSource[sources.size()]);
   534         return sources.toArray(new CodeSource[sources.size()]);
   537     }
   535     }
   538     private CodeSigner[] emptySigner = new CodeSigner[0];
   536     private CodeSigner[] emptySigner = new CodeSigner[0];
   539 
   537 
   540     /*
   538     /*
   541      * Match CodeSource to a CodeSigner[] in the signer cache.
   539      * Match CodeSource to a CodeSigner[] in the signer cache.
   551         /*
   549         /*
   552          * In practice signers should always be optimized above
   550          * In practice signers should always be optimized above
   553          * but this handles a CodeSource of any type, just in case.
   551          * but this handles a CodeSource of any type, just in case.
   554          */
   552          */
   555         CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
   553         CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
   556         List sourceList = new ArrayList();
   554         List<CodeSource> sourceList = new ArrayList<>();
   557         for (int i = 0; i < sources.length; i++) {
   555         for (int i = 0; i < sources.length; i++) {
   558             sourceList.add(sources[i]);
   556             sourceList.add(sources[i]);
   559         }
   557         }
   560         int j = sourceList.indexOf(cs);
   558         int j = sourceList.indexOf(cs);
   561         if (j != -1) {
   559         if (j != -1) {
   572     /*
   570     /*
   573      * Instances of this class hold uncopied references to internal
   571      * Instances of this class hold uncopied references to internal
   574      * signing data that can be compared by object reference identity.
   572      * signing data that can be compared by object reference identity.
   575      */
   573      */
   576     private static class VerifierCodeSource extends CodeSource {
   574     private static class VerifierCodeSource extends CodeSource {
       
   575         private static final long serialVersionUID = -9047366145967768825L;
   577 
   576 
   578         URL vlocation;
   577         URL vlocation;
   579         CodeSigner[] vsigners;
   578         CodeSigner[] vsigners;
   580         java.security.cert.Certificate[] vcerts;
   579         java.security.cert.Certificate[] vcerts;
   581         Object csdomain;
   580         Object csdomain;
   639 
   638 
   640         private java.security.cert.Certificate[] getPrivateCertificates() {
   639         private java.security.cert.Certificate[] getPrivateCertificates() {
   641             return vcerts;
   640             return vcerts;
   642         }
   641         }
   643     }
   642     }
   644     private Map signerMap;
   643     private Map<String, CodeSigner[]> signerMap;
   645 
   644 
   646     private synchronized Map signerMap() {
   645     private synchronized Map<String, CodeSigner[]> signerMap() {
   647         if (signerMap == null) {
   646         if (signerMap == null) {
   648             /*
   647             /*
   649              * Snapshot signer state so it doesn't change on us. We care
   648              * Snapshot signer state so it doesn't change on us. We care
   650              * only about the asserted signatures. Verification of
   649              * only about the asserted signatures. Verification of
   651              * signature validity happens via the JarEntry apis.
   650              * signature validity happens via the JarEntry apis.
   652              */
   651              */
   653             signerMap = new HashMap(verifiedSigners.size() + sigFileSigners.size());
   652             signerMap = new HashMap<>(verifiedSigners.size() + sigFileSigners.size());
   654             signerMap.putAll(verifiedSigners);
   653             signerMap.putAll(verifiedSigners);
   655             signerMap.putAll(sigFileSigners);
   654             signerMap.putAll(sigFileSigners);
   656         }
   655         }
   657         return signerMap;
   656         return signerMap;
   658     }
   657     }
   659 
   658 
   660     public synchronized Enumeration<String> entryNames(JarFile jar, final CodeSource[] cs) {
   659     public synchronized Enumeration<String> entryNames(JarFile jar, final CodeSource[] cs) {
   661         final Map map = signerMap();
   660         final Map<String, CodeSigner[]> map = signerMap();
   662         final Iterator itor = map.entrySet().iterator();
   661         final Iterator<Map.Entry<String, CodeSigner[]>> itor = map.entrySet().iterator();
   663         boolean matchUnsigned = false;
   662         boolean matchUnsigned = false;
   664 
   663 
   665         /*
   664         /*
   666          * Grab a single copy of the CodeSigner arrays. Check
   665          * Grab a single copy of the CodeSigner arrays. Check
   667          * to see if we can optimize CodeSigner equality test.
   666          * to see if we can optimize CodeSigner equality test.
   668          */
   667          */
   669         List req = new ArrayList(cs.length);
   668         List<CodeSigner[]> req = new ArrayList<>(cs.length);
   670         for (int i = 0; i < cs.length; i++) {
   669         for (int i = 0; i < cs.length; i++) {
   671             CodeSigner[] match = findMatchingSigners(cs[i]);
   670             CodeSigner[] match = findMatchingSigners(cs[i]);
   672             if (match != null) {
   671             if (match != null) {
   673                 if (match.length > 0) {
   672                 if (match.length > 0) {
   674                     req.add(match);
   673                     req.add(match);
   676                     matchUnsigned = true;
   675                     matchUnsigned = true;
   677                 }
   676                 }
   678             }
   677             }
   679         }
   678         }
   680 
   679 
   681         final List signersReq = req;
   680         final List<CodeSigner[]> signersReq = req;
   682         final Enumeration enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
   681         final Enumeration<String> enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
   683 
   682 
   684         return new Enumeration<String>() {
   683         return new Enumeration<String>() {
   685 
   684 
   686             String name;
   685             String name;
   687 
   686 
   689                 if (name != null) {
   688                 if (name != null) {
   690                     return true;
   689                     return true;
   691                 }
   690                 }
   692 
   691 
   693                 while (itor.hasNext()) {
   692                 while (itor.hasNext()) {
   694                     Map.Entry e = (Map.Entry) itor.next();
   693                     Map.Entry<String, CodeSigner[]> e = itor.next();
   695                     if (signersReq.contains((CodeSigner[]) e.getValue())) {
   694                     if (signersReq.contains(e.getValue())) {
   696                         name = (String) e.getKey();
   695                         name = e.getKey();
   697                         return true;
   696                         return true;
   698                     }
   697                     }
   699                 }
   698                 }
   700                 while (enum2.hasMoreElements()) {
   699                 while (enum2.hasMoreElements()) {
   701                     name = (String) enum2.nextElement();
   700                     name = enum2.nextElement();
   702                     return true;
   701                     return true;
   703                 }
   702                 }
   704                 return false;
   703                 return false;
   705             }
   704             }
   706 
   705 
   717 
   716 
   718     /*
   717     /*
   719      * Like entries() but screens out internal JAR mechanism entries
   718      * Like entries() but screens out internal JAR mechanism entries
   720      * and includes signed entries with no ZIP data.
   719      * and includes signed entries with no ZIP data.
   721      */
   720      */
   722     public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration e) {
   721     public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<? extends ZipEntry> e) {
   723         final Map map = new HashMap();
   722         final Map<String, CodeSigner[]> map = new HashMap<>();
   724         map.putAll(signerMap());
   723         map.putAll(signerMap());
   725         final Enumeration enum_ = e;
   724         final Enumeration<? extends ZipEntry> enum_ = e;
   726         return new Enumeration<JarEntry>() {
   725         return new Enumeration<JarEntry>() {
   727 
   726 
   728             Enumeration signers = null;
   727             Enumeration<String> signers = null;
   729             JarEntry entry;
   728             JarEntry entry;
   730 
   729 
   731             public boolean hasMoreElements() {
   730             public boolean hasMoreElements() {
   732                 if (entry != null) {
   731                 if (entry != null) {
   733                     return true;
   732                     return true;
   734                 }
   733                 }
   735                 while (enum_.hasMoreElements()) {
   734                 while (enum_.hasMoreElements()) {
   736                     ZipEntry ze = (ZipEntry) enum_.nextElement();
   735                     ZipEntry ze = enum_.nextElement();
   737                     if (JarVerifier.isSigningRelated(ze.getName())) {
   736                     if (JarVerifier.isSigningRelated(ze.getName())) {
   738                         continue;
   737                         continue;
   739                     }
   738                     }
   740                     entry = jar.newEntry(ze);
   739                     entry = jar.newEntry(ze);
   741                     return true;
   740                     return true;
   742                 }
   741                 }
   743                 if (signers == null) {
   742                 if (signers == null) {
   744                     signers = Collections.enumeration(map.keySet());
   743                     signers = Collections.enumeration(map.keySet());
   745                 }
   744                 }
   746                 while (signers.hasMoreElements()) {
   745                 while (signers.hasMoreElements()) {
   747                     String name = (String) signers.nextElement();
   746                     String name = signers.nextElement();
   748                     entry = jar.newEntry(new ZipEntry(name));
   747                     entry = jar.newEntry(new ZipEntry(name));
   749                     return true;
   748                     return true;
   750                 }
   749                 }
   751 
   750 
   752                 // Any map entries left?
   751                 // Any map entries left?
   762                 }
   761                 }
   763                 throw new NoSuchElementException();
   762                 throw new NoSuchElementException();
   764             }
   763             }
   765         };
   764         };
   766     }
   765     }
   767     private Enumeration emptyEnumeration = new Enumeration<String>() {
   766     private Enumeration<String> emptyEnumeration = new Enumeration<String>() {
   768 
   767 
   769         public boolean hasMoreElements() {
   768         public boolean hasMoreElements() {
   770             return false;
   769             return false;
   771         }
   770         }
   772 
   771 
   795         }
   794         }
   796         return false;
   795         return false;
   797     }
   796     }
   798 
   797 
   799     private Enumeration<String> unsignedEntryNames(JarFile jar) {
   798     private Enumeration<String> unsignedEntryNames(JarFile jar) {
   800         final Map map = signerMap();
   799         final Map<String, CodeSigner[]> map = signerMap();
   801         final Enumeration entries = jar.entries();
   800         final Enumeration<JarEntry> entries = jar.entries();
   802         return new Enumeration<String>() {
   801         return new Enumeration<String>() {
   803 
   802 
   804             String name;
   803             String name;
   805 
   804 
   806             /*
   805             /*
   811                 if (name != null) {
   810                 if (name != null) {
   812                     return true;
   811                     return true;
   813                 }
   812                 }
   814                 while (entries.hasMoreElements()) {
   813                 while (entries.hasMoreElements()) {
   815                     String value;
   814                     String value;
   816                     ZipEntry e = (ZipEntry) entries.nextElement();
   815                     ZipEntry e = entries.nextElement();
   817                     value = e.getName();
   816                     value = e.getName();
   818                     if (e.isDirectory() || isSigningRelated(value)) {
   817                     if (e.isDirectory() || isSigningRelated(value)) {
   819                         continue;
   818                         continue;
   820                     }
   819                     }
   821                     if (map.get(value) == null) {
   820                     if (map.get(value) == null) {
   834                 }
   833                 }
   835                 throw new NoSuchElementException();
   834                 throw new NoSuchElementException();
   836             }
   835             }
   837         };
   836         };
   838     }
   837     }
   839     private List jarCodeSigners;
   838     private List<CodeSigner[]> jarCodeSigners;
   840 
   839 
   841     private synchronized List getJarCodeSigners() {
   840     private synchronized List<CodeSigner[]> getJarCodeSigners() {
   842         CodeSigner[] signers;
   841         CodeSigner[] signers;
   843         if (jarCodeSigners == null) {
   842         if (jarCodeSigners == null) {
   844             HashSet set = new HashSet();
   843             HashSet<CodeSigner[]> set = new HashSet<>();
   845             set.addAll(signerMap().values());
   844             set.addAll(signerMap().values());
   846             jarCodeSigners = new ArrayList();
   845             jarCodeSigners = new ArrayList<>();
   847             jarCodeSigners.addAll(set);
   846             jarCodeSigners.addAll(set);
   848         }
   847         }
   849         return jarCodeSigners;
   848         return jarCodeSigners;
   850     }
   849     }
   851 
   850 
   856     }
   855     }
   857 
   856 
   858     public CodeSource getCodeSource(URL url, String name) {
   857     public CodeSource getCodeSource(URL url, String name) {
   859         CodeSigner[] signers;
   858         CodeSigner[] signers;
   860 
   859 
   861         signers = (CodeSigner[]) signerMap().get(name);
   860         signers = signerMap().get(name);
   862         return mapSignersToCodeSource(url, signers);
   861         return mapSignersToCodeSource(url, signers);
   863     }
   862     }
   864 
   863 
   865     public CodeSource getCodeSource(URL url, JarFile jar, JarEntry je) {
   864     public CodeSource getCodeSource(URL url, JarFile jar, JarEntry je) {
   866         CodeSigner[] signers;
   865         CodeSigner[] signers;