jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java
changeset 41580 cc479488428c
parent 34687 d302ed125dc9
child 41582 246512d81eba
equal deleted inserted replaced
41579:c0fe2e6364d9 41580:cc479488428c
     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 
   389                                                  + "cannot be used for "
   436                                                  + "cannot be used for "
   390                                                  + "digital signatures");
   437                                                  + "digital signatures");
   391                 }
   438                 }
   392             }
   439             }
   393 
   440 
   394             PublicKey key = cert.getPublicKey();
   441             Signature sig = Signature.getInstance(algname);
   395             sig.initVerify(key);
   442             sig.initVerify(key);
   396 
       
   397             sig.update(dataSigned);
   443             sig.update(dataSigned);
   398 
       
   399             if (sig.verify(encryptedDigest)) {
   444             if (sig.verify(encryptedDigest)) {
   400                 return this;
   445                 return this;
   401             }
   446             }
   402 
   447 
   403         } catch (IOException e) {
   448         } catch (IOException e) {
   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 (#" +