1 /* |
1 /* |
2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1996, 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 |
26 package sun.security.pkcs; |
26 package sun.security.pkcs; |
27 |
27 |
28 import java.io.OutputStream; |
28 import java.io.OutputStream; |
29 import java.io.IOException; |
29 import java.io.IOException; |
30 import java.math.BigInteger; |
30 import java.math.BigInteger; |
|
31 import java.security.CryptoPrimitive; |
|
32 import java.security.InvalidKeyException; |
|
33 import java.security.MessageDigest; |
|
34 import java.security.NoSuchAlgorithmException; |
|
35 import java.security.Principal; |
|
36 import java.security.PublicKey; |
|
37 import java.security.Signature; |
|
38 import java.security.SignatureException; |
|
39 import java.security.Timestamp; |
31 import java.security.cert.CertificateException; |
40 import java.security.cert.CertificateException; |
32 import java.security.cert.CertificateFactory; |
41 import java.security.cert.CertificateFactory; |
33 import java.security.cert.CertPath; |
42 import java.security.cert.CertPath; |
34 import java.security.cert.X509Certificate; |
43 import java.security.cert.X509Certificate; |
35 import java.security.*; |
|
36 import java.util.ArrayList; |
44 import java.util.ArrayList; |
37 import java.util.Arrays; |
45 import java.util.Arrays; |
|
46 import java.util.Collections; |
|
47 import java.util.EnumSet; |
|
48 import java.util.Set; |
38 |
49 |
39 import sun.security.timestamp.TimestampToken; |
50 import sun.security.timestamp.TimestampToken; |
40 import sun.security.util.*; |
51 import sun.security.util.Debug; |
|
52 import sun.security.util.DerEncoder; |
|
53 import sun.security.util.DerInputStream; |
|
54 import sun.security.util.DerOutputStream; |
|
55 import sun.security.util.DerValue; |
|
56 import sun.security.util.DisabledAlgorithmConstraints; |
|
57 import sun.security.util.HexDumpEncoder; |
|
58 import sun.security.util.ObjectIdentifier; |
41 import sun.security.x509.AlgorithmId; |
59 import sun.security.x509.AlgorithmId; |
42 import sun.security.x509.X500Name; |
60 import sun.security.x509.X500Name; |
43 import sun.security.x509.KeyUsageExtension; |
61 import sun.security.x509.KeyUsageExtension; |
44 import sun.security.util.HexDumpEncoder; |
|
45 |
62 |
46 /** |
63 /** |
47 * A SignerInfo, as defined in PKCS#7's signedData type. |
64 * A SignerInfo, as defined in PKCS#7's signedData type. |
48 * |
65 * |
49 * @author Benjamin Renaud |
66 * @author Benjamin Renaud |
50 */ |
67 */ |
51 public class SignerInfo implements DerEncoder { |
68 public class SignerInfo implements DerEncoder { |
|
69 |
|
70 // Digest and Signature restrictions |
|
71 private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = |
|
72 Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST)); |
|
73 |
|
74 private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = |
|
75 Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE)); |
|
76 |
|
77 private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK = |
|
78 new DisabledAlgorithmConstraints( |
|
79 DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS); |
52 |
80 |
53 BigInteger version; |
81 BigInteger version; |
54 X500Name issuerName; |
82 X500Name issuerName; |
55 BigInteger certificateSerialNumber; |
83 BigInteger certificateSerialNumber; |
56 AlgorithmId digestAlgorithmId; |
84 AlgorithmId digestAlgorithmId; |
316 PKCS9Attribute.MESSAGE_DIGEST_OID); |
344 PKCS9Attribute.MESSAGE_DIGEST_OID); |
317 |
345 |
318 if (messageDigest == null) // fail if there is no message digest |
346 if (messageDigest == null) // fail if there is no message digest |
319 return null; |
347 return null; |
320 |
348 |
|
349 // check that algorithm is not restricted |
|
350 if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, |
|
351 digestAlgname, null)) { |
|
352 throw new SignatureException("Digest check failed. " + |
|
353 "Disabled algorithm used: " + digestAlgname); |
|
354 } |
|
355 |
321 MessageDigest md = MessageDigest.getInstance(digestAlgname); |
356 MessageDigest md = MessageDigest.getInstance(digestAlgname); |
322 byte[] computedMessageDigest = md.digest(data); |
357 byte[] computedMessageDigest = md.digest(data); |
323 |
358 |
324 if (messageDigest.length != computedMessageDigest.length) |
359 if (messageDigest.length != computedMessageDigest.length) |
325 return null; |
360 return null; |
347 String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); |
382 String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); |
348 if (tmp != null) encryptionAlgname = tmp; |
383 if (tmp != null) encryptionAlgname = tmp; |
349 String algname = AlgorithmId.makeSigAlg( |
384 String algname = AlgorithmId.makeSigAlg( |
350 digestAlgname, encryptionAlgname); |
385 digestAlgname, encryptionAlgname); |
351 |
386 |
352 Signature sig = Signature.getInstance(algname); |
387 // check that algorithm is not restricted |
|
388 if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) { |
|
389 throw new SignatureException("Signature check failed. " + |
|
390 "Disabled algorithm used: " + algname); |
|
391 } |
|
392 |
353 X509Certificate cert = getCertificate(block); |
393 X509Certificate cert = getCertificate(block); |
354 |
394 PublicKey key = cert.getPublicKey(); |
355 if (cert == null) { |
395 if (cert == null) { |
356 return null; |
396 return null; |
357 } |
397 } |
|
398 |
|
399 // check if the public key is restricted |
|
400 if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { |
|
401 throw new SignatureException("Public key check failed. " + |
|
402 "Disabled algorithm used: " + key.getAlgorithm()); |
|
403 } |
|
404 |
358 if (cert.hasUnsupportedCriticalExtension()) { |
405 if (cert.hasUnsupportedCriticalExtension()) { |
359 throw new SignatureException("Certificate has unsupported " |
406 throw new SignatureException("Certificate has unsupported " |
360 + "critical extension(s)"); |
407 + "critical extension(s)"); |
361 } |
408 } |
362 |
409 |
513 * Match the hash present in the signature timestamp token against the hash |
558 * Match the hash present in the signature timestamp token against the hash |
514 * of this signature. |
559 * of this signature. |
515 */ |
560 */ |
516 private void verifyTimestamp(TimestampToken token) |
561 private void verifyTimestamp(TimestampToken token) |
517 throws NoSuchAlgorithmException, SignatureException { |
562 throws NoSuchAlgorithmException, SignatureException { |
|
563 String digestAlgname = token.getHashAlgorithm().getName(); |
|
564 // check that algorithm is not restricted |
|
565 if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname, |
|
566 null)) { |
|
567 throw new SignatureException("Timestamp token digest check failed. " + |
|
568 "Disabled algorithm used: " + digestAlgname); |
|
569 } |
518 |
570 |
519 MessageDigest md = |
571 MessageDigest md = |
520 MessageDigest.getInstance(token.getHashAlgorithm().getName()); |
572 MessageDigest.getInstance(digestAlgname); |
521 |
573 |
522 if (!Arrays.equals(token.getHashedMessage(), |
574 if (!Arrays.equals(token.getHashedMessage(), |
523 md.digest(encryptedDigest))) { |
575 md.digest(encryptedDigest))) { |
524 |
576 |
525 throw new SignatureException("Signature timestamp (#" + |
577 throw new SignatureException("Signature timestamp (#" + |