[ 
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)

Reply via email to