src/java.base/share/classes/sun/security/validator/PKIXValidator.java
author jnimeh
Thu, 22 Aug 2019 14:09:36 -0700
changeset 57849 e1269de19aa5
parent 51398 3c389a284345
permissions -rw-r--r--
8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag Reviewed-by: mullan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
     2
 * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4326
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4326
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4326
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4326
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4326
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.security.validator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.cert.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.security.auth.x500.X500Principal;
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    34
import sun.security.action.GetBooleanAction;
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    35
import sun.security.provider.certpath.AlgorithmChecker;
43701
fe8c324ba97c 8160655: Fix denyAfter and usage types for security properties
ascarpino
parents: 39465
diff changeset
    36
import sun.security.provider.certpath.PKIXExtendedParameters;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * Validator implementation built on the PKIX CertPath API. This
30374
2abaf49910ea 8079478: some docs cleanup for sun.security
avstepan
parents: 25859
diff changeset
    40
 * implementation will be emphasized going forward.
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    41
 * <p>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * Note that the validate() implementation tries to use a PKIX validator
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * if that appears possible and a PKIX builder otherwise. This increases
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * performance and currently also leads to better exception messages
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * in case of failures.
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    46
 * <p>
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    47
 * {@code PKIXValidator} objects are immutable once they have been created.
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    48
 * Please DO NOT add methods that can change the state of an instance once
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    49
 * it has been created.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * @author Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
public final class PKIXValidator extends Validator {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    55
    /**
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    56
     * Flag indicating whether to enable revocation check for the PKIX trust
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    57
     * manager. Typically, this will only work if the PKIX implementation
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    58
     * supports CRL distribution points as we do not manually setup CertStores.
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    59
     */
51398
3c389a284345 8209416: Refactoring GetPropertyAction calls in security libs
weijun
parents: 47216
diff changeset
    60
    private static final boolean checkTLSRevocation = GetBooleanAction
3c389a284345 8209416: Refactoring GetPropertyAction calls in security libs
weijun
parents: 47216
diff changeset
    61
            .privilegedGetProperty("com.sun.net.ssl.checkRevocation");
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    62
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    private final Set<X509Certificate> trustedCerts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    private final PKIXBuilderParameters parameterTemplate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private int certPathLength = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    // needed only for the validator
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    68
    private final Map<X500Principal, List<PublicKey>> trustedSubjects;
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    69
    private final CertificateFactory factory;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
    71
    private final boolean plugin;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    PKIXValidator(String variant, Collection<X509Certificate> trustedCerts) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        super(TYPE_PKIX, variant);
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    75
        this.trustedCerts = (trustedCerts instanceof Set) ?
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    76
                            (Set<X509Certificate>)trustedCerts :
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    77
                            new HashSet<X509Certificate>(trustedCerts);
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    78
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    79
        Set<TrustAnchor> trustAnchors = new HashSet<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        for (X509Certificate cert : trustedCerts) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
            trustAnchors.add(new TrustAnchor(cert, null));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        }
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    83
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            parameterTemplate = new PKIXBuilderParameters(trustAnchors, null);
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    86
            factory = CertificateFactory.getInstance("X.509");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        } catch (InvalidAlgorithmParameterException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
            throw new RuntimeException("Unexpected error: " + e.toString(), e);
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
    89
        } catch (CertificateException e) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
    90
            throw new RuntimeException("Internal error", e);
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
    91
        }
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    92
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    93
        setDefaultParameters(variant);
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
    94
        plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    95
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
    96
        trustedSubjects = setTrustedSubjects();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    PKIXValidator(String variant, PKIXBuilderParameters params) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        super(TYPE_PKIX, variant);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        trustedCerts = new HashSet<X509Certificate>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        for (TrustAnchor anchor : params.getTrustAnchors()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            X509Certificate cert = anchor.getTrustedCert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            if (cert != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                trustedCerts.add(cert);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        parameterTemplate = params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   110
        try {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   111
            factory = CertificateFactory.getInstance("X.509");
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   112
        } catch (CertificateException e) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   113
            throw new RuntimeException("Internal error", e);
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   114
        }
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   115
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   116
        plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   117
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   118
        trustedSubjects = setTrustedSubjects();
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   119
    }
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   120
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   121
    /**
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   122
     * Populate the trustedSubjects Map using the DN and public keys from
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   123
     * the list of trusted certificates
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   124
     *
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   125
     * @return Map containing each subject DN and one or more public keys
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   126
     *    tied to those DNs.
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   127
     */
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   128
    private Map<X500Principal, List<PublicKey>> setTrustedSubjects() {
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   129
        Map<X500Principal, List<PublicKey>> subjectMap = new HashMap<>();
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   130
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   131
        for (X509Certificate cert : trustedCerts) {
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   132
            X500Principal dn = cert.getSubjectX500Principal();
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   133
            List<PublicKey> keys;
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   134
            if (subjectMap.containsKey(dn)) {
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   135
                keys = subjectMap.get(dn);
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   136
            } else {
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   137
                keys = new ArrayList<PublicKey>();
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   138
                subjectMap.put(dn, keys);
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   139
            }
24370
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   140
            keys.add(cert.getPublicKey());
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   141
        }
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   142
1398d972eef1 6996377: shrink duplicate code in the constructor of PKIXValidator
mullan
parents: 14342
diff changeset
   143
        return subjectMap;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   146
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    public Collection<X509Certificate> getTrustedCertificates() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        return trustedCerts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * Returns the length of the last certification path that is validated by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * CertPathValidator. This is intended primarily as a callback mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * for PKIXCertPathCheckers to determine the length of the certification
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * path that is being validated. It is necessary since engineValidate()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * may modify the length of the path.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * @return the length of the last certification path passed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     *   CertPathValidator.validate, or -1 if it has not been invoked yet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     */
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   161
    public int getCertPathLength() { // mutable, should be private
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        return certPathLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * Set J2SE global default PKIX parameters. Currently, hardcoded to disable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * revocation checking. In the future, this should be configurable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    private void setDefaultParameters(String variant) {
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   170
        if ((variant == Validator.VAR_TLS_SERVER) ||
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   171
                (variant == Validator.VAR_TLS_CLIENT)) {
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   172
            parameterTemplate.setRevocationEnabled(checkTLSRevocation);
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   173
        } else {
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   174
            parameterTemplate.setRevocationEnabled(false);
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   175
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     * Return the PKIX parameters used by this instance. An application may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     * modify the parameters but must make sure not to perform any concurrent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * validations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     */
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   183
    public PKIXBuilderParameters getParameters() { // mutable, should be private
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        return parameterTemplate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   187
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    X509Certificate[] engineValidate(X509Certificate[] chain,
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   189
            Collection<X509Certificate> otherCerts,
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   190
            List<byte[]> responseList,
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   191
            AlgorithmConstraints constraints,
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   192
            Object parameter) throws CertificateException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        if ((chain == null) || (chain.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            throw new CertificateException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                ("null or zero-length certificate chain");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        }
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   197
44158
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   198
        // Use PKIXExtendedParameters for timestamp and variant additions
39465
8c06651d9138 8154015: Apply algorithm constraints to timestamped code
ascarpino
parents: 32649
diff changeset
   199
        PKIXBuilderParameters pkixParameters = null;
44158
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   200
        try {
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   201
            pkixParameters = new PKIXExtendedParameters(
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   202
                    (PKIXBuilderParameters) parameterTemplate.clone(),
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   203
                    (parameter instanceof Timestamp) ?
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   204
                            (Timestamp) parameter : null,
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   205
                    variant);
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   206
        } catch (InvalidAlgorithmParameterException e) {
49deb8a1ed3f 8176350: Usage constraints don't take effect when using PKIX
ascarpino
parents: 43701
diff changeset
   207
            // ignore exception
39465
8c06651d9138 8154015: Apply algorithm constraints to timestamped code
ascarpino
parents: 32649
diff changeset
   208
        }
8c06651d9138 8154015: Apply algorithm constraints to timestamped code
ascarpino
parents: 32649
diff changeset
   209
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   210
        // add new algorithm constraints checker
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   211
        if (constraints != null) {
43701
fe8c324ba97c 8160655: Fix denyAfter and usage types for security properties
ascarpino
parents: 39465
diff changeset
   212
            pkixParameters.addCertPathChecker(
fe8c324ba97c 8160655: Fix denyAfter and usage types for security properties
ascarpino
parents: 39465
diff changeset
   213
                    new AlgorithmChecker(constraints, null, variant));
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   214
        }
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   215
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   216
        // attach it to the PKIXBuilderParameters.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   217
        if (!responseList.isEmpty()) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   218
            addResponses(pkixParameters, chain, responseList);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   219
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   220
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   221
        // check that chain is in correct order and check if chain contains
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   222
        // trust anchor
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   223
        X500Principal prevIssuer = null;
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   224
        for (int i = 0; i < chain.length; i++) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   225
            X509Certificate cert = chain[i];
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   226
            X500Principal dn = cert.getSubjectX500Principal();
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   227
            if (i != 0 && !dn.equals(prevIssuer)) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   228
                // chain is not ordered correctly, call builder instead
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   229
                return doBuild(chain, otherCerts, pkixParameters);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   232
            // Check if chain[i] is already trusted. It may be inside
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   233
            // trustedCerts, or has the same dn and public key as a cert
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   234
            // inside trustedCerts. The latter happens when a CA has
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   235
            // updated its cert with a stronger signature algorithm in JRE
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   236
            // but the weak one is still in circulation.
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   237
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   238
            if (trustedCerts.contains(cert) ||          // trusted cert
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   239
                    (trustedSubjects.containsKey(dn) && // replacing ...
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   240
                     trustedSubjects.get(dn).contains(  // ... weak cert
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   241
                        cert.getPublicKey()))) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   242
                if (i == 0) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   243
                    return new X509Certificate[] {chain[0]};
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   244
                }
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   245
                // Remove and call validator on partial chain [0 .. i-1]
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   246
                X509Certificate[] newChain = new X509Certificate[i];
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   247
                System.arraycopy(chain, 0, newChain, 0, i);
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   248
                return doValidate(newChain, pkixParameters);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            }
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   250
            prevIssuer = cert.getIssuerX500Principal();
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   251
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   253
        // apparently issued by trust anchor?
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   254
        X509Certificate last = chain[chain.length - 1];
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   255
        X500Principal issuer = last.getIssuerX500Principal();
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   256
        X500Principal subject = last.getSubjectX500Principal();
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   257
        if (trustedSubjects.containsKey(issuer) &&
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   258
                isSignatureValid(trustedSubjects.get(issuer), last)) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   259
            return doValidate(chain, pkixParameters);
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   260
        }
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   261
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   262
        // don't fallback to builder if called from plugin/webstart
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   263
        if (plugin) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   264
            // Validate chain even if no trust anchor is found. This
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   265
            // allows plugin/webstart to make sure the chain is
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   266
            // otherwise valid
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   267
            if (chain.length > 1) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   268
                X509Certificate[] newChain =
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   269
                    new X509Certificate[chain.length-1];
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   270
                System.arraycopy(chain, 0, newChain, 0, newChain.length);
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   271
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   272
                // temporarily set last cert as sole trust anchor
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   273
                try {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   274
                    pkixParameters.setTrustAnchors
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   275
                        (Collections.singleton(new TrustAnchor
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   276
                            (chain[chain.length-1], null)));
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   277
                } catch (InvalidAlgorithmParameterException iape) {
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   278
                    // should never occur, but ...
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   279
                    throw new CertificateException(iape);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                }
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   281
                doValidate(newChain, pkixParameters);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            }
24704
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   283
            // if the rest of the chain is valid, throw exception
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   284
            // indicating no trust anchor was found
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   285
            throw new ValidatorException
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   286
                (ValidatorException.T_NO_TRUST_ANCHOR);
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   287
        }
76581302d209 8044771: PKIXValidator indent cleanup
xuelei
parents: 24370
diff changeset
   288
        // otherwise, fall back to builder
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   290
        return doBuild(chain, otherCerts, pkixParameters);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   293
    private boolean isSignatureValid(List<PublicKey> keys,
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   294
            X509Certificate sub) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        if (plugin) {
5782
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   296
            for (PublicKey key: keys) {
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   297
                try {
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   298
                    sub.verify(key);
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   299
                    return true;
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   300
                } catch (Exception ex) {
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   301
                    continue;
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   302
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            }
5782
50575882b36f 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn
weijun
parents: 5627
diff changeset
   304
            return false;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        return true; // only check if PLUGIN is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    private static X509Certificate[] toArray(CertPath path, TrustAnchor anchor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            throws CertificateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        List<? extends java.security.cert.Certificate> list =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                                                path.getCertificates();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        X509Certificate[] chain = new X509Certificate[list.size() + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        list.toArray(chain);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        X509Certificate trustedCert = anchor.getTrustedCert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        if (trustedCert == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            throw new ValidatorException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                ("TrustAnchor must be specified as certificate");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        chain[chain.length - 1] = trustedCert;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        return chain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * Set the check date (for debugging).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    private void setDate(PKIXBuilderParameters params) {
10709
d865c9f21240 7092375: Security Libraries don't build with javac -Werror
xuelei
parents: 7040
diff changeset
   328
        @SuppressWarnings("deprecation")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        Date date = validationDate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        if (date != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            params.setDate(date);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    private X509Certificate[] doValidate(X509Certificate[] chain,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            PKIXBuilderParameters params) throws CertificateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            setDate(params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            // do the validation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            CertPathValidator validator = CertPathValidator.getInstance("PKIX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            CertPath path = factory.generateCertPath(Arrays.asList(chain));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            certPathLength = chain.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            PKIXCertPathValidatorResult result =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                (PKIXCertPathValidatorResult)validator.validate(path, params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            return toArray(path, result.getTrustAnchor());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            throw new ValidatorException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                ("PKIX path validation failed: " + e.toString(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    private X509Certificate[] doBuild(X509Certificate[] chain,
7040
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   355
        Collection<X509Certificate> otherCerts,
659824c2a550 6792180: Enhance to reject weak algorithms or conform to crypto recommendations
xuelei
parents: 5782
diff changeset
   356
        PKIXBuilderParameters params) throws CertificateException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            setDate(params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            // setup target constraints
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            X509CertSelector selector = new X509CertSelector();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            selector.setCertificate(chain[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            params.setTargetCertConstraints(selector);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            // setup CertStores
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            Collection<X509Certificate> certs =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                                        new ArrayList<X509Certificate>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            certs.addAll(Arrays.asList(chain));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            if (otherCerts != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                certs.addAll(otherCerts);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            CertStore store = CertStore.getInstance("Collection",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                                new CollectionCertStoreParameters(certs));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            params.addCertStore(store);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            // do the build
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            PKIXCertPathBuilderResult result =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                (PKIXCertPathBuilderResult)builder.build(params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            return toArray(result.getCertPath(), result.getTrustAnchor());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            throw new ValidatorException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                ("PKIX path building failed: " + e.toString(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    }
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   388
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   389
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   390
     * For OCSP Stapling, add responses that came in during the handshake
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   391
     * into a {@code PKIXRevocationChecker} so we can evaluate them.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   392
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   393
     * @param pkixParams the pkixParameters object that will be used in
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   394
     * path validation.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   395
     * @param chain the chain of certificates to verify
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   396
     * @param responseList a {@code List} of zero or more byte arrays, each
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   397
     * one being a DER-encoded OCSP response (per RFC 6960).  Entries
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   398
     * in the List must match the order of the certificates in the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   399
     * chain parameter.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   400
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   401
    private static void addResponses(PKIXBuilderParameters pkixParams,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   402
            X509Certificate[] chain, List<byte[]> responseList) {
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   403
        try {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   404
            boolean createdRevChk = false;
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   405
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   406
            // Obtain the current CertPathChecker list
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   407
            PKIXRevocationChecker revChecker = null;
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   408
            List<PKIXCertPathChecker> checkerList =
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   409
                    pkixParams.getCertPathCheckers();
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   410
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   411
            // Find the first PKIXRevocationChecker in the list
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   412
            for (PKIXCertPathChecker checker : checkerList) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   413
                if (checker instanceof PKIXRevocationChecker) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   414
                    revChecker = (PKIXRevocationChecker)checker;
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   415
                    break;
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   416
                }
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   417
            }
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   418
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   419
            // If we still haven't found one, make one, unless revocation
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   420
            // is disabled - then there's no point adding OCSP responses.
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   421
            // If a PKIXRevocationChecker was added externally, then we
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   422
            // must add the responses since revocation checking is performed
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   423
            // independent of the revocation flag (per the
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   424
            // PKIXRevocationChecker spec).
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   425
            if (revChecker == null) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   426
                if (pkixParams.isRevocationEnabled()) {
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   427
                    revChecker = (PKIXRevocationChecker)CertPathValidator.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   428
                            getInstance("PKIX").getRevocationChecker();
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   429
                    createdRevChk = true;
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   430
                } else {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   431
                    return;
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   432
                }
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   433
            }
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   434
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   435
            // Each response in the list should be in parallel with
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   436
            // the certificate list.  If there is a zero-length response
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   437
            // treat it as being absent.  If the user has provided their
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   438
            // own PKIXRevocationChecker with pre-populated responses, do
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   439
            // not overwrite them with the ones from the handshake.
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   440
            Map<X509Certificate, byte[]> responseMap =
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   441
                    revChecker.getOcspResponses();
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   442
            int limit = Integer.min(chain.length, responseList.size());
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   443
            for (int idx = 0; idx < limit; idx++) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   444
                byte[] respBytes = responseList.get(idx);
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   445
                if (respBytes != null && respBytes.length > 0 &&
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   446
                        !responseMap.containsKey(chain[idx])) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   447
                    responseMap.put(chain[idx], respBytes);
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   448
                }
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   449
            }
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   450
            revChecker.setOcspResponses(responseMap);
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   451
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   452
            // Add the responses and push it all back into the
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   453
            // PKIXBuilderParameters
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   454
            if (createdRevChk) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   455
                pkixParams.addCertPathChecker(revChecker);
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   456
            } else {
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   457
                pkixParams.setCertPathCheckers(checkerList);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   458
            }
57849
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   459
        } catch (NoSuchAlgorithmException exc) {
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   460
            // This should not occur, but if it does happen then
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   461
            // stapled OCSP responses won't be part of revocation checking.
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   462
            // Clients can still fall back to other means of revocation
e1269de19aa5 8225436: Stapled OCSPResponses should be added to PKIXRevocationChecker irrespective of revocationEnabled flag
jnimeh
parents: 51398
diff changeset
   463
            // checking.
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   464
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents: 30374
diff changeset
   465
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
}