1 /* |
1 /* |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package sun.security.util; |
26 package sun.security.util; |
27 |
27 |
|
28 import java.io.ByteArrayInputStream; |
|
29 import java.io.IOException; |
|
30 import java.security.CodeSigner; |
|
31 import java.security.CryptoPrimitive; |
|
32 import java.security.MessageDigest; |
|
33 import java.security.NoSuchAlgorithmException; |
|
34 import java.security.SignatureException; |
28 import java.security.cert.CertPath; |
35 import java.security.cert.CertPath; |
29 import java.security.cert.X509Certificate; |
36 import java.security.cert.X509Certificate; |
30 import java.security.cert.CertificateException; |
37 import java.security.cert.CertificateException; |
31 import java.security.cert.CertificateFactory; |
38 import java.security.cert.CertificateFactory; |
32 import java.security.*; |
39 import java.util.ArrayList; |
33 import java.io.*; |
|
34 import java.util.*; |
|
35 import java.util.jar.*; |
|
36 |
|
37 import sun.security.pkcs.*; |
|
38 import java.util.Base64; |
40 import java.util.Base64; |
|
41 import java.util.Collections; |
|
42 import java.util.EnumSet; |
|
43 import java.util.HashMap; |
|
44 import java.util.Hashtable; |
|
45 import java.util.Iterator; |
|
46 import java.util.List; |
|
47 import java.util.Locale; |
|
48 import java.util.Map; |
|
49 import java.util.Set; |
|
50 import java.util.jar.Attributes; |
|
51 import java.util.jar.JarException; |
|
52 import java.util.jar.JarFile; |
|
53 import java.util.jar.Manifest; |
39 |
54 |
40 import sun.security.jca.Providers; |
55 import sun.security.jca.Providers; |
|
56 import sun.security.pkcs.PKCS7; |
|
57 import sun.security.pkcs.SignerInfo; |
41 |
58 |
42 public class SignatureFileVerifier { |
59 public class SignatureFileVerifier { |
43 |
60 |
44 /* Are we debugging ? */ |
61 /* Are we debugging ? */ |
45 private static final Debug debug = Debug.getInstance("jar"); |
62 private static final Debug debug = Debug.getInstance("jar"); |
46 |
63 |
47 /* cache of CodeSigner objects */ |
64 private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = |
|
65 Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST)); |
|
66 |
|
67 private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK = |
|
68 new DisabledAlgorithmConstraints( |
|
69 DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS); |
|
70 |
48 private ArrayList<CodeSigner[]> signerCache; |
71 private ArrayList<CodeSigner[]> signerCache; |
49 |
72 |
50 private static final String ATTR_DIGEST = |
73 private static final String ATTR_DIGEST = |
51 ("-DIGEST-" + ManifestDigester.MF_MAIN_ATTRS).toUpperCase |
74 ("-DIGEST-" + ManifestDigester.MF_MAIN_ATTRS).toUpperCase |
52 (Locale.ENGLISH); |
75 (Locale.ENGLISH); |
197 return false; |
220 return false; |
198 } |
221 } |
199 |
222 |
200 /** get digest from cache */ |
223 /** get digest from cache */ |
201 |
224 |
202 private MessageDigest getDigest(String algorithm) |
225 private MessageDigest getDigest(String algorithm) throws SignatureException { |
203 { |
226 // check that algorithm is not restricted |
|
227 if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) { |
|
228 SignatureException e = |
|
229 new SignatureException("SignatureFile check failed. " + |
|
230 "Disabled algorithm used: " + algorithm); |
|
231 throw e; |
|
232 } |
|
233 |
204 if (createdDigests == null) |
234 if (createdDigests == null) |
205 createdDigests = new HashMap<>(); |
235 createdDigests = new HashMap<>(); |
206 |
236 |
207 MessageDigest digest = createdDigests.get(algorithm); |
237 MessageDigest digest = createdDigests.get(algorithm); |
208 |
238 |
318 * See if the whole manifest was signed. |
348 * See if the whole manifest was signed. |
319 */ |
349 */ |
320 private boolean verifyManifestHash(Manifest sf, |
350 private boolean verifyManifestHash(Manifest sf, |
321 ManifestDigester md, |
351 ManifestDigester md, |
322 List<Object> manifestDigests) |
352 List<Object> manifestDigests) |
323 throws IOException |
353 throws IOException, SignatureException |
324 { |
354 { |
325 Attributes mattr = sf.getMainAttributes(); |
355 Attributes mattr = sf.getMainAttributes(); |
326 boolean manifestSigned = false; |
356 boolean manifestSigned = false; |
327 |
357 |
328 // go through all the attributes and process *-Digest-Manifest entries |
358 // go through all the attributes and process *-Digest-Manifest entries |
362 return manifestSigned; |
392 return manifestSigned; |
363 } |
393 } |
364 |
394 |
365 private boolean verifyManifestMainAttrs(Manifest sf, |
395 private boolean verifyManifestMainAttrs(Manifest sf, |
366 ManifestDigester md) |
396 ManifestDigester md) |
367 throws IOException |
397 throws IOException, SignatureException |
368 { |
398 { |
369 Attributes mattr = sf.getMainAttributes(); |
399 Attributes mattr = sf.getMainAttributes(); |
370 boolean attrsVerified = true; |
400 boolean attrsVerified = true; |
371 |
401 |
372 // go through all the attributes and process |
402 // go through all the attributes and process |
428 */ |
458 */ |
429 |
459 |
430 private boolean verifySection(Attributes sfAttr, |
460 private boolean verifySection(Attributes sfAttr, |
431 String name, |
461 String name, |
432 ManifestDigester md) |
462 ManifestDigester md) |
433 throws IOException |
463 throws IOException, SignatureException |
434 { |
464 { |
435 boolean oneDigestVerified = false; |
465 boolean oneDigestVerified = false; |
436 ManifestDigester.Entry mde = md.get(name,block.isOldStyle()); |
466 ManifestDigester.Entry mde = md.get(name,block.isOldStyle()); |
437 |
467 |
438 if (mde == null) { |
468 if (mde == null) { |
439 throw new SecurityException( |
469 throw new SecurityException( |
440 "no manifiest section for signature file entry "+name); |
470 "no manifest section for signature file entry "+name); |
441 } |
471 } |
442 |
472 |
443 if (sfAttr != null) { |
473 if (sfAttr != null) { |
444 |
474 |
445 //sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder(); |
475 //sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder(); |