[ https://issues.apache.org/jira/browse/MJARSIGNER-74?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17879032#comment-17879032 ]
ASF GitHub Bot commented on MJARSIGNER-74: ------------------------------------------ pzygielo commented on code in PR #19: URL: https://github.com/apache/maven-jarsigner-plugin/pull/19#discussion_r1742709870 ########## src/main/java/org/apache/maven/plugins/jarsigner/TsaSelector.java: ########## @@ -0,0 +1,140 @@ +/* + * 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: + * <pre> + * [vagrant@podmanhost ~]$ openssl x509 -noout -ext subjectInfoAccess -in tsa-server.crt + * Subject Information Access: + * AD Time Stamping - URI:http://timestamp.globalsign.com/tsa/r6advanced1 + * </pre> + * + * 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<TsaServer> currentTsaServer = new ThreadLocal<>(); + + /** List of TSA servers. Will at minimum contain a dummy/empty value */ + private final List<TsaServer> tsaServers; + + TsaSelector(String[] tsa, String[] tsacert, String[] tsapolicyid, String tsadigestalg) { + List<TsaServer> 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; Review Comment: I think it's very internal usage of package-visible only class. No need to cancel vote, as this is not exposed anywhere. This might be updated anytime later. > Allow usage of multiple Time Stamping Authority (TSA) servers > ------------------------------------------------------------- > > Key: MJARSIGNER-74 > URL: https://issues.apache.org/jira/browse/MJARSIGNER-74 > Project: Maven Jar Signer Plugin > Issue Type: New Feature > Affects Versions: 3.0.0 > Reporter: Lennart Schedin > Assignee: Slawomir Jaranowski > Priority: Minor > Fix For: 3.1.0 > > > h3. Background > A Timestamping Authority (TSA) server is used to add a timestamp to the > digital signature. This timestamp indicates when the code was signed and > helps prevent issues that may arise if a certificate used for code signing > expires. > The jarsigner command has 4 parameters relating to TSA (see > [https://docs.oracle.com/en/java/javase/17/docs/specs/man/jarsigner.html):] > 1. {{-tsa url}} > 2. {{-tsacert alias}} > 3. {{-tsapolicyid policyid}} > 4. {{-tsadigestalg algorithm}} > The maven-jarsigner-plugin currently has support to set {{-tsa}} and > {{-tsacert}} (the same goes for the library JarSignerSignRequest in the > [https://github.com/apache/maven-jarsigner] project). > h3. Feature requested > Allow usage of multiple TSA servers when signing. This could be useful for: > 1. Better stability if one TSA server is down. > 2. Better stability if a TSA server has imposed a rate-limit when signing > many jar files at the same time. > This feature has both been suggested by Thorsten Meinl as a patch to > [https://issues.apache.org/jira/projects/MJARSIGNER/issues/MJARSIGNER-59] and > also by @jcompagner in > [https://github.com/apache/maven-jarsigner-plugin/pull/1#issuecomment-1412344998]. > But since those suggestions were not tied to a direct ticket, I felt it > would be good to collect their feature requests as a separate dedicated > ticket. > h3. Implementation suggestions > I don’t plan to implement this feature myself. But since I have analyzed the > issue, I can give my suggestions on how to implement it: > # The {{-tsapolicyid}} parameter is currently missing in the maven-jarsigner > project. Consider adding support for this while implementing this ticket. > # Since {{{}-tsa{}}}, {{{}-tsacert{}}}, {{-tsapolicyid}} all belong > together, I would recommend making a list of all 3. > # If the user specifies 3 tsa URLs but only 1 tsacert it gets a bit tricky. > The easiest way to handle this is to use validateParameters() (see > [https://github.com/apache/maven-jarsigner-plugin/pull/13/]) and throw a > MojoExecutionException if this happens. > # I recommend using a comma as separator for the items in the list. This way > it would be possible to change the data type from String to String[] and > Maven will itself handle the splitting on the comma (if using the command > format) or mangling of nested XML tags into a String[] (if using nested XML > format). Thus, the JarsignerSignMojo would not need to do any String > splitting. > -- This message was sent by Atlassian Jira (v8.20.10#820010)