jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java
author redestad
Thu, 21 Apr 2016 13:39:53 +0200
changeset 37593 824750ada3d6
parent 32032 22badc53802f
child 37781 71ed5645f17c
permissions -rw-r--r--
8154231: Simplify access to System properties from JDK code Reviewed-by: rriggs, chegar, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     1
/*
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     4
 *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    10
 *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    15
 * accompanied this code).
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    16
 *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    20
 *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    23
 * questions.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    24
 */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    25
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    26
package sun.security.ssl;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    27
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    28
import java.io.IOException;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    29
import java.net.URI;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    30
import java.net.URISyntaxException;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    31
import java.security.AccessController;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    32
import java.security.cert.X509Certificate;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    33
import java.security.cert.Extension;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    34
import java.util.*;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    35
import java.util.concurrent.*;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    36
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    37
import sun.security.provider.certpath.CertId;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    38
import sun.security.provider.certpath.OCSP;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    39
import sun.security.provider.certpath.OCSPResponse;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    40
import sun.security.provider.certpath.ResponderId;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    41
import sun.security.util.Cache;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    42
import sun.security.x509.PKIXExtensions;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    43
import sun.security.x509.SerialNumber;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    44
import sun.security.action.GetBooleanAction;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    45
import sun.security.action.GetIntegerAction;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    46
import sun.security.action.GetPropertyAction;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    47
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    48
final class StatusResponseManager {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    49
    private static final int DEFAULT_CORE_THREADS = 8;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    50
    private static final int DEFAULT_CACHE_SIZE = 256;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    51
    private static final int DEFAULT_CACHE_LIFETIME = 3600;         // seconds
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    52
    private static final Debug debug = Debug.getInstance("ssl");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    53
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    54
    private final ScheduledThreadPoolExecutor threadMgr;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    55
    private final Cache<CertId, ResponseCacheEntry> responseCache;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    56
    private final URI defaultResponder;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    57
    private final boolean respOverride;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    58
    private final int cacheCapacity;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    59
    private final int cacheLifetime;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    60
    private final boolean ignoreExtensions;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    61
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    62
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    63
     * Create a StatusResponseManager with default parameters.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    64
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    65
    StatusResponseManager() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    66
        int cap = AccessController.doPrivileged(
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    67
                new GetIntegerAction("jdk.tls.stapling.cacheSize",
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    68
                    DEFAULT_CACHE_SIZE));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    69
        cacheCapacity = cap > 0 ? cap : 0;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    70
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    71
        int life = AccessController.doPrivileged(
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    72
                new GetIntegerAction("jdk.tls.stapling.cacheLifetime",
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    73
                    DEFAULT_CACHE_LIFETIME));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    74
        cacheLifetime = life > 0 ? life : 0;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    75
37593
824750ada3d6 8154231: Simplify access to System properties from JDK code
redestad
parents: 32032
diff changeset
    76
        String uriStr =
824750ada3d6 8154231: Simplify access to System properties from JDK code
redestad
parents: 32032
diff changeset
    77
                GetPropertyAction.getProperty("jdk.tls.stapling.responderURI");
32032
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    78
        URI tmpURI;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    79
        try {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    80
            tmpURI = ((uriStr != null && !uriStr.isEmpty()) ?
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    81
                    new URI(uriStr) : null);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    82
        } catch (URISyntaxException urise) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    83
            tmpURI = null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    84
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    85
        defaultResponder = tmpURI;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    86
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    87
        respOverride = AccessController.doPrivileged(
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    88
                new GetBooleanAction("jdk.tls.stapling.responderOverride"));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    89
        ignoreExtensions = AccessController.doPrivileged(
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    90
                new GetBooleanAction("jdk.tls.stapling.ignoreExtensions"));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    91
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    92
        threadMgr = new ScheduledThreadPoolExecutor(DEFAULT_CORE_THREADS,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    93
                new ThreadFactory() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    94
            @Override
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    95
            public Thread newThread(Runnable r) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    96
                Thread t = Executors.defaultThreadFactory().newThread(r);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    97
                t.setDaemon(true);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    98
                return t;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
    99
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   100
        });
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   101
        threadMgr.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   102
        threadMgr.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   103
        threadMgr.setKeepAliveTime(5000, TimeUnit.MILLISECONDS);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   104
        responseCache = Cache.newSoftMemoryCache(cacheCapacity, cacheLifetime);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   105
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   106
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   107
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   108
     * Get the current cache lifetime setting
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   109
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   110
     * @return the current cache lifetime value
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   111
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   112
    int getCacheLifetime() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   113
        return cacheLifetime;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   114
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   115
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   116
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   117
     * Get the current maximum cache size.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   118
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   119
     * @return the current maximum cache size
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   120
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   121
    int getCacheCapacity() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   122
        return cacheCapacity;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   123
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   124
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   125
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   126
     * Get the default OCSP responder URI, if previously set.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   127
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   128
     * @return the current default OCSP responder URI, or {@code null} if
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   129
     *      it has not been set.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   130
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   131
    URI getDefaultResponder() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   132
        return defaultResponder;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   133
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   134
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   135
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   136
     * Get the URI override setting
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   137
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   138
     * @return {@code true} if URI override has been set, {@code false}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   139
     * otherwise.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   140
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   141
    boolean getURIOverride() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   142
        return respOverride;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   143
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   144
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   145
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   146
     * Get the ignore extensions setting.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   147
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   148
     * @return {@code true} if the {@code StatusResponseManager} will not
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   149
     * pass OCSP Extensions in the TLS {@code status_request[_v2]} extensions,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   150
     * {@code false} if extensions will be passed (the default).
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   151
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   152
    boolean getIgnoreExtensions() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   153
        return ignoreExtensions;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   154
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   155
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   156
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   157
     * Clear the status response cache
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   158
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   159
    void clear() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   160
        debugLog("Clearing response cache");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   161
        responseCache.clear();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   162
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   163
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   164
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   165
     * Returns the number of currently valid objects in the response cache.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   166
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   167
     * @return the number of valid objects in the response cache.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   168
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   169
    int size() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   170
        return responseCache.size();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   171
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   172
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   173
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   174
     * Obtain the URI use by the {@code StatusResponseManager} during lookups.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   175
     * This method takes into account not only the AIA extension from a
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   176
     * certificate to be checked, but also any default URI and possible
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   177
     * override settings for the response manager.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   178
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   179
     * @param cert the subject to get the responder URI from
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   180
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   181
     * @return a {@code URI} containing the address to the OCSP responder, or
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   182
     *      {@code null} if no AIA extension exists in the certificate and no
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   183
     *      default responder has been configured.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   184
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   185
     * @throws NullPointerException if {@code cert} is {@code null}.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   186
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   187
    URI getURI(X509Certificate cert) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   188
        Objects.requireNonNull(cert);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   189
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   190
        if (cert.getExtensionValue(
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   191
                PKIXExtensions.OCSPNoCheck_Id.toString()) != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   192
            debugLog("OCSP NoCheck extension found.  OCSP will be skipped");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   193
            return null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   194
        } else if (defaultResponder != null && respOverride) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   195
            debugLog("Responder override: URI is " + defaultResponder);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   196
            return defaultResponder;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   197
        } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   198
            URI certURI = OCSP.getResponderURI(cert);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   199
            return (certURI != null ? certURI : defaultResponder);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   200
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   201
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   202
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   203
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   204
     * Shutdown the thread pool
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   205
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   206
    void shutdown() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   207
        debugLog("Shutting down " + threadMgr.getActiveCount() +
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   208
                " active threads");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   209
        threadMgr.shutdown();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   210
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   211
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   212
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   213
     * Get a list of responses for a chain of certificates.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   214
     * This will find OCSP responses from the cache, or failing that, directly
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   215
     * contact the OCSP responder.  It is assumed that the certificates in
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   216
     * the provided chain are in their proper order (from end-entity to
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   217
     * trust anchor).
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   218
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   219
     * @param type the type of request being made of the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   220
     *      {@code StatusResponseManager}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   221
     * @param request the {@code StatusRequest} from the status_request or
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   222
     *      status_request_v2 ClientHello extension.  A value of {@code null}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   223
     *      is interpreted as providing no responder IDs or extensions.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   224
     * @param chain an array of 2 or more certificates.  Each certificate must
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   225
     *      be issued by the next certificate in the chain.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   226
     * @param delay the number of time units to delay before returning
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   227
     *      responses.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   228
     * @param unit the unit of time applied to the {@code delay} parameter
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   229
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   230
     * @return an unmodifiable {@code Map} containing the certificate and
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   231
     *      its usually
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   232
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   233
     * @throws SSLHandshakeException if an unsupported {@code StatusRequest}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   234
     *      is provided.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   235
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   236
    Map<X509Certificate, byte[]> get(StatusRequestType type,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   237
            StatusRequest request, X509Certificate[] chain, long delay,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   238
            TimeUnit unit) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   239
        Map<X509Certificate, byte[]> responseMap = new HashMap<>();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   240
        List<OCSPFetchCall> requestList = new ArrayList<>();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   241
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   242
        debugLog("Beginning check: Type = " + type + ", Chain length = " +
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   243
                chain.length);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   244
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   245
        // It is assumed that the caller has ordered the certs in the chain
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   246
        // in the proper order (each certificate is issued by the next entry
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   247
        // in the provided chain).
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   248
        if (chain.length < 2) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   249
            return Collections.emptyMap();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   250
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   251
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   252
        if (type == StatusRequestType.OCSP) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   253
            try {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   254
                // For type OCSP, we only check the end-entity certificate
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   255
                OCSPStatusRequest ocspReq = (OCSPStatusRequest)request;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   256
                CertId cid = new CertId(chain[1],
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   257
                        new SerialNumber(chain[0].getSerialNumber()));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   258
                ResponseCacheEntry cacheEntry = getFromCache(cid, ocspReq);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   259
                if (cacheEntry != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   260
                    responseMap.put(chain[0], cacheEntry.ocspBytes);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   261
                } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   262
                    StatusInfo sInfo = new StatusInfo(chain[0], cid);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   263
                    requestList.add(new OCSPFetchCall(sInfo, ocspReq));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   264
                }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   265
            } catch (IOException exc) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   266
                debugLog("Exception during CertId creation: " + exc);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   267
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   268
        } else if (type == StatusRequestType.OCSP_MULTI) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   269
            // For type OCSP_MULTI, we check every cert in the chain that
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   270
            // has a direct issuer at the next index.  We won't have an issuer
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   271
            // certificate for the last certificate in the chain and will
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   272
            // not be able to create a CertId because of that.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   273
            OCSPStatusRequest ocspReq = (OCSPStatusRequest)request;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   274
            int ctr;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   275
            for (ctr = 0; ctr < chain.length - 1; ctr++) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   276
                try {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   277
                    // The cert at "ctr" is the subject cert, "ctr + 1" is the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   278
                    // issuer certificate.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   279
                    CertId cid = new CertId(chain[ctr + 1],
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   280
                            new SerialNumber(chain[ctr].getSerialNumber()));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   281
                    ResponseCacheEntry cacheEntry = getFromCache(cid, ocspReq);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   282
                    if (cacheEntry != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   283
                        responseMap.put(chain[ctr], cacheEntry.ocspBytes);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   284
                    } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   285
                        StatusInfo sInfo = new StatusInfo(chain[ctr], cid);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   286
                        requestList.add(new OCSPFetchCall(sInfo, ocspReq));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   287
                    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   288
                } catch (IOException exc) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   289
                    debugLog("Exception during CertId creation: " + exc);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   290
                }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   291
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   292
        } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   293
            debugLog("Unsupported status request type: " + type);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   294
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   295
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   296
        // If we were able to create one or more Fetches, go and run all
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   297
        // of them in separate threads.  For all the threads that completed
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   298
        // in the allotted time, put those status responses into the returned
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   299
        // Map.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   300
        if (!requestList.isEmpty()) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   301
            try {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   302
                // Set a bunch of threads to go do the fetching
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   303
                List<Future<StatusInfo>> resultList =
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   304
                        threadMgr.invokeAll(requestList, delay, unit);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   305
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   306
                // Go through the Futures and from any non-cancelled task,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   307
                // get the bytes and attach them to the responseMap.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   308
                for (Future<StatusInfo> task : resultList) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   309
                    if (task.isDone()) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   310
                        if (!task.isCancelled()) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   311
                            StatusInfo info = task.get();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   312
                            if (info != null && info.responseData != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   313
                                responseMap.put(info.cert,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   314
                                        info.responseData.ocspBytes);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   315
                            } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   316
                                debugLog("Completed task had no response data");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   317
                            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   318
                        } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   319
                            debugLog("Found cancelled task");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   320
                        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   321
                    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   322
                }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   323
            } catch (InterruptedException | ExecutionException exc) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   324
                // Not sure what else to do here
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   325
                debugLog("Exception when getting data: " + exc);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   326
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   327
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   328
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   329
        return Collections.unmodifiableMap(responseMap);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   330
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   331
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   332
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   333
     * Check the cache for a given {@code CertId}.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   334
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   335
     * @param cid the CertId of the response to look up
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   336
     * @param ocspRequest the OCSP request structure sent by the client
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   337
     *      in the TLS status_request[_v2] hello extension.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   338
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   339
     * @return the {@code ResponseCacheEntry} for a specific CertId, or
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   340
     *      {@code null} if it is not found or a nonce extension has been
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   341
     *      requested by the caller.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   342
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   343
    private ResponseCacheEntry getFromCache(CertId cid,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   344
            OCSPStatusRequest ocspRequest) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   345
        // Determine if the nonce extension is present in the request.  If
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   346
        // so, then do not attempt to retrieve the response from the cache.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   347
        for (Extension ext : ocspRequest.getExtensions()) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   348
            if (ext.getId().equals(PKIXExtensions.OCSPNonce_Id.toString())) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   349
                debugLog("Nonce extension found, skipping cache check");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   350
                return null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   351
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   352
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   353
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   354
        ResponseCacheEntry respEntry = responseCache.get(cid);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   355
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   356
        // If the response entry has a nextUpdate and it has expired
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   357
        // before the cache expiration, purge it from the cache
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   358
        // and do not return it as a cache hit.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   359
        if (respEntry != null && respEntry.nextUpdate != null &&
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   360
                respEntry.nextUpdate.before(new Date())) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   361
            debugLog("nextUpdate threshold exceeded, purging from cache");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   362
            respEntry = null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   363
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   364
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   365
        debugLog("Check cache for SN" + cid.getSerialNumber() + ": " +
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   366
                (respEntry != null ? "HIT" : "MISS"));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   367
        return respEntry;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   368
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   369
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   370
    @Override
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   371
    public String toString() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   372
        StringBuilder sb = new StringBuilder("StatusResponseManager: ");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   373
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   374
        sb.append("Core threads: ").append(threadMgr.getCorePoolSize());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   375
        sb.append(", Cache timeout: ");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   376
        if (cacheLifetime > 0) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   377
            sb.append(cacheLifetime).append(" seconds");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   378
        } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   379
            sb.append(" indefinite");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   380
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   381
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   382
        sb.append(", Cache MaxSize: ");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   383
        if (cacheCapacity > 0) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   384
            sb.append(cacheCapacity).append(" items");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   385
        } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   386
            sb.append(" unbounded");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   387
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   388
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   389
        sb.append(", Default URI: ");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   390
        if (defaultResponder != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   391
            sb.append(defaultResponder);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   392
        } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   393
            sb.append("NONE");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   394
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   395
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   396
        return sb.toString();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   397
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   398
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   399
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   400
     * Log messages through the SSL Debug facility.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   401
     *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   402
     * @param message the message to be displayed
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   403
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   404
    static void debugLog(String message) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   405
        if (debug != null && Debug.isOn("respmgr")) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   406
            StringBuilder sb = new StringBuilder();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   407
            sb.append("[").append(Thread.currentThread().getName());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   408
            sb.append("] ").append(message);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   409
            System.out.println(sb.toString());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   410
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   411
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   412
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   413
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   414
     * Inner class used to group request and response data.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   415
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   416
    class StatusInfo {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   417
        final X509Certificate cert;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   418
        final CertId cid;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   419
        final URI responder;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   420
        ResponseCacheEntry responseData;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   421
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   422
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   423
         * Create a StatusInfo object from certificate data.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   424
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   425
         * @param subjectCert the certificate to be checked for revocation
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   426
         * @param issuerCert the issuer of the {@code subjectCert}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   427
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   428
         * @throws IOException if CertId creation from the certificates fails
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   429
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   430
        StatusInfo(X509Certificate subjectCert, X509Certificate issuerCert)
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   431
                throws IOException {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   432
            this(subjectCert, new CertId(issuerCert,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   433
                    new SerialNumber(subjectCert.getSerialNumber())));
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   434
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   435
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   436
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   437
         * Create a StatusInfo object from an existing subject certificate
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   438
         * and its corresponding CertId.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   439
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   440
         * @param subjectCert the certificate to be checked for revocation
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   441
         * @param cid the CertId for {@code subjectCert}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   442
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   443
        StatusInfo(X509Certificate subjectCert, CertId certId) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   444
            cert = subjectCert;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   445
            cid = certId;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   446
            responder = getURI(cert);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   447
            responseData = null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   448
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   449
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   450
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   451
         * Copy constructor (used primarily for rescheduling).
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   452
         * This will do a member-wise copy with the exception of the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   453
         * responseData and extensions fields, which should not persist
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   454
         * in a rescheduled fetch.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   455
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   456
         * @param orig the original {@code StatusInfo}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   457
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   458
        StatusInfo(StatusInfo orig) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   459
            this.cert = orig.cert;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   460
            this.cid = orig.cid;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   461
            this.responder = orig.responder;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   462
            this.responseData = null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   463
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   464
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   465
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   466
         * Return a String representation of the {@code StatusInfo}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   467
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   468
         * @return a {@code String} representation of this object
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   469
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   470
        @Override
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   471
        public String toString() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   472
            StringBuilder sb = new StringBuilder("StatusInfo:");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   473
            sb.append("\n\tCert: ").append(this.cert.getSubjectX500Principal());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   474
            sb.append("\n\tSerial: ").append(this.cert.getSerialNumber());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   475
            sb.append("\n\tResponder: ").append(this.responder);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   476
            sb.append("\n\tResponse data: ").append(this.responseData != null ?
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   477
                    (this.responseData.ocspBytes.length + " bytes") : "<NULL>");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   478
            return sb.toString();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   479
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   480
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   481
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   482
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   483
     * Static nested class used as the data kept in the response cache.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   484
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   485
    static class ResponseCacheEntry {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   486
        final OCSPResponse.ResponseStatus status;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   487
        final byte[] ocspBytes;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   488
        final Date nextUpdate;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   489
        final OCSPResponse.SingleResponse singleResp;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   490
        final ResponderId respId;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   491
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   492
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   493
         * Create a new cache entry from the raw bytes of the response
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   494
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   495
         * @param responseBytes the DER encoding for the OCSP response
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   496
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   497
         * @throws IOException if an {@code OCSPResponse} cannot be created from
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   498
         *      the encoded bytes.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   499
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   500
        ResponseCacheEntry(byte[] responseBytes, CertId cid)
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   501
                throws IOException {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   502
            Objects.requireNonNull(responseBytes,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   503
                    "Non-null responseBytes required");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   504
            Objects.requireNonNull(cid, "Non-null Cert ID required");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   505
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   506
            ocspBytes = responseBytes.clone();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   507
            OCSPResponse oResp = new OCSPResponse(ocspBytes);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   508
            status = oResp.getResponseStatus();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   509
            respId = oResp.getResponderId();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   510
            singleResp = oResp.getSingleResponse(cid);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   511
            if (status == OCSPResponse.ResponseStatus.SUCCESSFUL) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   512
                if (singleResp != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   513
                    // Pull out the nextUpdate field in advance because the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   514
                    // Date is cloned.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   515
                    nextUpdate = singleResp.getNextUpdate();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   516
                } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   517
                    throw new IOException("Unable to find SingleResponse for " +
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   518
                            "SN " + cid.getSerialNumber());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   519
                }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   520
            } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   521
                nextUpdate = null;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   522
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   523
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   524
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   525
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   526
    /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   527
     * Inner Callable class that does the actual work of looking up OCSP
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   528
     * responses, first looking at the cache and doing OCSP requests if
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   529
     * a cache miss occurs.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   530
     */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   531
    class OCSPFetchCall implements Callable<StatusInfo> {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   532
        StatusInfo statInfo;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   533
        OCSPStatusRequest ocspRequest;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   534
        List<Extension> extensions;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   535
        List<ResponderId> responderIds;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   536
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   537
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   538
         * A constructor that builds the OCSPFetchCall from the provided
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   539
         * StatusInfo and information from the status_request[_v2] extension.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   540
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   541
         * @param info the {@code StatusInfo} containing the subject
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   542
         * certificate, CertId, and other supplemental info.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   543
         * @param request the {@code OCSPStatusRequest} containing any
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   544
         * responder IDs and extensions.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   545
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   546
        public OCSPFetchCall(StatusInfo info, OCSPStatusRequest request) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   547
            statInfo = Objects.requireNonNull(info,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   548
                    "Null StatusInfo not allowed");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   549
            ocspRequest = Objects.requireNonNull(request,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   550
                    "Null OCSPStatusRequest not allowed");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   551
            extensions = ocspRequest.getExtensions();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   552
            responderIds = ocspRequest.getResponderIds();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   553
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   554
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   555
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   556
         * Get an OCSP response, either from the cache or from a responder.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   557
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   558
         * @return The StatusInfo object passed into the {@code OCSPFetchCall}
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   559
         * constructor, with the {@code responseData} field filled in with the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   560
         * response or {@code null} if no response can be obtained.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   561
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   562
        @Override
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   563
        public StatusInfo call() {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   564
            debugLog("Starting fetch for SN " + statInfo.cid.getSerialNumber());
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   565
            try {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   566
                ResponseCacheEntry cacheEntry;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   567
                List<Extension> extsToSend;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   568
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   569
                if (statInfo.responder == null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   570
                    // If we have no URI then there's nothing to do but return
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   571
                    debugLog("Null URI detected, OCSP fetch aborted.");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   572
                    return statInfo;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   573
                } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   574
                    debugLog("Attempting fetch from " + statInfo.responder);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   575
                }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   576
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   577
                // If the StatusResponseManager has been configured to not
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   578
                // forward extensions, then set extensions to an empty list.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   579
                // We will forward the extensions unless one of two conditions
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   580
                // occur: (1) The jdk.tls.stapling.ignoreExtensions property is
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   581
                // true or (2) There is a non-empty ResponderId list.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   582
                // ResponderId selection is a feature that will be
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   583
                // supported in the future.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   584
                extsToSend = (ignoreExtensions || !responderIds.isEmpty()) ?
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   585
                        Collections.emptyList() : extensions;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   586
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   587
                byte[] respBytes = OCSP.getOCSPBytes(
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   588
                        Collections.singletonList(statInfo.cid),
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   589
                        statInfo.responder, extsToSend);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   590
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   591
                if (respBytes != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   592
                    // Place the data into the response cache
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   593
                    cacheEntry = new ResponseCacheEntry(respBytes,
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   594
                            statInfo.cid);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   595
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   596
                    // Get the response status and act on it appropriately
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   597
                    debugLog("OCSP Status: " + cacheEntry.status +
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   598
                            " (" + respBytes.length + " bytes)");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   599
                    if (cacheEntry.status ==
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   600
                            OCSPResponse.ResponseStatus.SUCCESSFUL) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   601
                        // Set the response in the returned StatusInfo
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   602
                        statInfo.responseData = cacheEntry;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   603
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   604
                        // Add the response to the cache (if applicable)
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   605
                        addToCache(statInfo.cid, cacheEntry);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   606
                    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   607
                } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   608
                    debugLog("No data returned from OCSP Responder");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   609
                }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   610
            } catch (IOException ioe) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   611
                debugLog("Caught exception: " + ioe);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   612
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   613
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   614
            return statInfo;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   615
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   616
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   617
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   618
         * Add a response to the cache.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   619
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   620
         * @param certId The {@code CertId} for the OCSP response
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   621
         * @param entry A cache entry containing the response bytes and
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   622
         *      the {@code OCSPResponse} built from those bytes.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   623
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   624
        private void addToCache(CertId certId, ResponseCacheEntry entry) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   625
            // If no cache lifetime has been set on entries then
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   626
            // don't cache this response if there is no nextUpdate field
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   627
            if (entry.nextUpdate == null && cacheLifetime == 0) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   628
                debugLog("Not caching this OCSP response");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   629
            } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   630
                responseCache.put(certId, entry);
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   631
                debugLog("Added response for SN " + certId.getSerialNumber() +
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   632
                        " to cache");
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   633
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   634
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   635
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   636
        /**
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   637
         * Determine the delay to use when scheduling the task that will
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   638
         * update the OCSP response.  This is the shorter time between the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   639
         * cache lifetime and the nextUpdate.  If no nextUpdate is present in
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   640
         * the response, then only the cache lifetime is used.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   641
         * If cache timeouts are disabled (a zero value) and there's no
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   642
         * nextUpdate, then the entry is not cached and no rescheduling will
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   643
         * take place.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   644
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   645
         * @param nextUpdate a {@code Date} object corresponding to the
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   646
         *      next update time from a SingleResponse.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   647
         *
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   648
         * @return the number of seconds of delay before the next fetch
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   649
         *      should be executed.  A zero value means that the fetch
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   650
         *      should happen immediately, while a value less than zero
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   651
         *      indicates no rescheduling should be done.
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   652
         */
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   653
        private long getNextTaskDelay(Date nextUpdate) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   654
            long delaySec;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   655
            int lifetime = getCacheLifetime();
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   656
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   657
            if (nextUpdate != null) {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   658
                long nuDiffSec = (nextUpdate.getTime() -
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   659
                        System.currentTimeMillis()) / 1000;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   660
                delaySec = lifetime > 0 ? Long.min(nuDiffSec, lifetime) :
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   661
                        nuDiffSec;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   662
            } else {
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   663
                delaySec = lifetime > 0 ? lifetime : -1;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   664
            }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   665
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   666
            return delaySec;
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   667
        }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   668
    }
22badc53802f 8046321: OCSP Stapling for TLS
jnimeh
parents:
diff changeset
   669
}