All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.plugins.jarsigner.TsaSelector Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.maven.plugins.jarsigner;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Helper class to select a Time Stamping Authority (TSA) server along with parameters to send. The protocol is defined
 * in RFC 3161: Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP).
 *
 * From a jarsigner perspective there are two things that are important:
 * 1. Finding a TSA server URL
 * 2. What parameters to use for TSA server communication.
 *
 * Finding a URL can be done in two ways:
 * a) The end-user has specified an explicit URL (the most common way)
 * b) The end-user has specified a keystore alias that points to a certificate in the active keystore. From the
 *    certificate the X509v3 extension "Subject Information Access" field is examined to find the TSA server URL.
 *    Example:
 *    
 *    [vagrant@podmanhost ~]$ openssl x509 -noout -ext subjectInfoAccess -in tsa-server.crt
 *    Subject Information Access:
 *        AD Time Stamping - URI:http://timestamp.globalsign.com/tsa/r6advanced1
 *    
* * Each TSA server vendor typically has defined its own OID for what "policy" to use in the timestamping process. For * example GlobalSign might use 1.3.6.1.4.1.4146.2.3.1.2. A DigiCert TSA server would not accept this OID. In most cases * there is no need for the end-user to specify this because the TSA server will choose a default. * * jarsigner will send a message digest to the TSA server along with the message digest algorithm. For example * {@code SHA-384}. A TSA server might reject the chosen algorithm, but typically most TSA servers supports the "common" * ones (like SHA-256, SHA-384 and SHA-512). In most cases there is no need for the end-user to specify this because the * jarsigner tool choose a good default. */ class TsaSelector { /** The current TsaServer in use (if any). One per thread */ private final ThreadLocal currentTsaServer = new ThreadLocal<>(); /** List of TSA servers. Will at minimum contain a dummy/empty value */ private final List tsaServers; TsaSelector(String[] tsa, String[] tsacert, String[] tsapolicyid, String tsadigestalg) { List tsaServersTmp = new ArrayList<>(); for (int i = 0; i < Math.max(tsa.length, tsacert.length); i++) { String tsaUrl = i < tsa.length ? tsa[i] : null; String tsaAlias = i < tsacert.length ? tsacert[i] : null; String tsaPolicyId = i < tsapolicyid.length ? tsapolicyid[i] : null; tsaServersTmp.add(new TsaServer(tsaUrl, tsaAlias, tsaPolicyId, tsadigestalg)); } if (tsaServersTmp.isEmpty()) { tsaServersTmp.add(TsaServer.EMPTY); } this.tsaServers = Collections.unmodifiableList(tsaServersTmp); } /** * Gets the next "best" TSA server to use. * * Uses a "best effort" approach without any synchronization. It may not select the "snapshot-consistent" best TSA * server, but good enough. */ TsaServer getServer() { TsaServer best = tsaServers.get(0); for (int i = 1; i < tsaServers.size(); i++) { if (best.failureCount.get() > tsaServers.get(i).failureCount.get()) { best = tsaServers.get(i); } } currentTsaServer.set(best); return best; } /** * Register that the current used TsaServer was involved in a jarsigner execution that failed. This could be a * problem with the TsaServer, but it could also be other factors unrelated to the TsaServer. Regardless of the * cause of the failure it is registered as a failure for the current used TsaServer to be used when determining the * next TsaServer to try. */ void registerFailure() { if (currentTsaServer.get() != null) { currentTsaServer.get().failureCount.incrementAndGet(); } } /** Representation of a single TSA server and the parameters to use for it */ static class TsaServer { private static final TsaServer EMPTY = new TsaServer(null, null, null, null); private final AtomicInteger failureCount = new AtomicInteger(0); private final String tsaUrl; private final String tsaAlias; private final String tsaPolicyId; private final String tsaDigestAlt; private TsaServer(String tsaUrl, String tsaAlias, String tsaPolicyId, String tsaDigestAlt) { this.tsaUrl = tsaUrl; this.tsaAlias = tsaAlias; this.tsaPolicyId = tsaPolicyId; this.tsaDigestAlt = tsaDigestAlt; } String getTsaUrl() { return tsaUrl; } String getTsaAlias() { return tsaAlias; } String getTsaPolicyId() { return tsaPolicyId; } String getTsaDigestAlt() { return tsaDigestAlt; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy