From df6b4f161f24423be15db87751ef75ee16d5c6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Wed, 12 Apr 2023 04:55:21 +0200 Subject: [PATCH 01/13] initial test at signing with sigstore --- pom.xml | 37 ++- .../plugins/gpg/GpgSignAttachedMojo.java | 5 +- .../plugins/gpg/SigstoreSignAttachedMojo.java | 228 ++++++++++++++++++ 3 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java diff --git a/pom.xml b/pom.xml index a0aabc8..34643ae 100644 --- a/pom.xml +++ b/pom.xml @@ -63,12 +63,18 @@ under the License. 3.2.5 - 8 + 11 + ${javaVersion} 2021-05-05T16:39:01Z @ + + dev.sigstore + sigstore-java + 0.4.0 + org.apache.maven maven-plugin-api @@ -282,5 +288,34 @@ under the License. + + + apache-release + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${project.version} + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sigstore-sign-release-artifacts + + sigstore + + + + + + + diff --git a/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java index 98b600a..db6e31c 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java @@ -50,7 +50,7 @@ public class GpgSignAttachedMojo { private static final String DEFAULT_EXCLUDES[] = - new String[] { "**/*.md5", "**/*.sha1", "**/*.sha256", "**/*.sha512", "**/*.asc" }; + new String[] { "**/*.md5", "**/*.sha1", "**/*.sha256", "**/*.sha512", "**/*.asc", "**/*.sigstore" }; /** * Skip doing the gpg signing. @@ -60,7 +60,8 @@ public class GpgSignAttachedMojo /** * A list of files to exclude from being signed. Can contain Ant-style wildcards and double wildcards. The default - * excludes are **/*.md5 **/*.sha1 **/*.sha256 **/*.sha512 **/*.asc. + * excludes are **/*.md5 **/*.sha1 **/*.sha256 **/*.sha512 + * **/*.asc **/*.sigstore. * * @since 1.0-alpha-4 */ diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java new file mode 100644 index 0000000..ea6978c --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java @@ -0,0 +1,228 @@ +package org.apache.maven.plugins.gpg; + +/* + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.SelectorUtils; + +import dev.sigstore.KeylessSignature; +import dev.sigstore.KeylessSigner; +import dev.sigstore.bundle.BundleFactory; + +/** + * Sign project artifact, the POM, and attached artifacts with sigstore for deployment. + * + * @since 3.1.0 + */ +@Mojo( name = "sigstore", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true ) +public class SigstoreSignAttachedMojo + extends AbstractMojo +{ + + private static final String DEFAULT_EXCLUDES[] = + new String[] { "**/*.md5", "**/*.sha1", "**/*.sha256", "**/*.sha512", "**/*.asc", "**/*.sigstore" }; + + /** + * Skip doing the gpg signing. + */ + @Parameter( property = "sigstore.skip", defaultValue = "false" ) + private boolean skip; + + /** + * A list of files to exclude from being signed. Can contain Ant-style wildcards and double wildcards. The default + * excludes are **/*.md5 **/*.sha1 **/*.sha256 **/*.sha512 + * **/*.asc **/*.sigstore. + */ + @Parameter + private String[] excludes; + + /** + * The Maven project. + */ + @Parameter( defaultValue = "${project}", readonly = true, required = true ) + protected MavenProject project; + + /** + * Maven ProjectHelper + */ + @Component + private MavenProjectHelper projectHelper; + + @Override + public void execute() + throws MojoExecutionException, MojoFailureException + { + if ( skip ) + { + // We're skipping the signing stuff + return; + } + + if ( excludes == null || excludes.length == 0 ) + { + excludes = DEFAULT_EXCLUDES; + } + String newExcludes[] = new String[excludes.length]; + for ( int i = 0; i < excludes.length; i++ ) + { + String pattern; + pattern = excludes[i].trim().replace( '/', File.separatorChar ).replace( '\\', File.separatorChar ); + if ( pattern.endsWith( File.separator ) ) + { + pattern += "**"; + } + newExcludes[i] = pattern; + } + excludes = newExcludes; + + List filesToSign = new ArrayList<>(); + + if ( !"pom".equals( project.getPackaging() ) ) + { + // ---------------------------------------------------------------------------- + // Project artifact + // ---------------------------------------------------------------------------- + + Artifact artifact = project.getArtifact(); + + File file = artifact.getFile(); + + if ( file != null && file.isFile() ) + { + filesToSign.add( new SigningBundle( artifact.getArtifactHandler().getExtension(), file ) ); + } + else if ( project.getAttachedArtifacts().isEmpty() ) + { + throw new MojoFailureException( "The project artifact has not been assembled yet. " + + "Please do not invoke this goal before the lifecycle phase \"package\"." ); + } + else + { + getLog().debug( "Main artifact not assembled, skipping signature generation" ); + } + } + + // ---------------------------------------------------------------------------- + // POM + // ---------------------------------------------------------------------------- + + File pomToSign = new File( project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".pom" ); + + try + { + FileUtils.copyFile( project.getFile(), pomToSign ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Error copying POM for signing.", e ); + } + + filesToSign.add( new SigningBundle( "pom", pomToSign ) ); + + // ---------------------------------------------------------------------------- + // Attached artifacts + // ---------------------------------------------------------------------------- + + for ( Object o : project.getAttachedArtifacts() ) + { + Artifact artifact = (Artifact) o; + + File file = artifact.getFile(); + + if ( isExcluded( artifact ) ) + { + getLog().debug( "Skipping generation of signature for excluded " + file ); + continue; + } + + filesToSign.add( new SigningBundle( artifact.getArtifactHandler().getExtension(), + artifact.getClassifier(), file ) ); + } + + // ---------------------------------------------------------------------------- + // Sign the filesToSign and attach all the signatures + // ---------------------------------------------------------------------------- + + try + { + KeylessSigner signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); + for ( SigningBundle bundleToSign : filesToSign ) + { + File fileToSign = bundleToSign.getSignature(); // reusing original GPG implementation where it's the signature: TODO change + + KeylessSignature signature = signer.signFile( fileToSign.toPath() ); + + // sigstore signature in bundle format (json string) + String sigstoreBundle = BundleFactory.createBundle( signature ); + + File signatureFile = new File( fileToSign + ".sigstore" ); + FileUtils.fileWrite( signatureFile, "UTF-8", sigstoreBundle ); + + projectHelper.attachArtifact( project, bundleToSign.getExtension() + ".sigstore", + bundleToSign.getClassifier(), signatureFile ); + } + } + catch ( Exception e ) + { + throw new MojoExecutionException( "Error while signing with sigstore", e ); + } + } + + /** + * Tests whether or not a name matches against at least one exclude pattern. + * + * @param artifact The artifact to match. Must not be null. + * @return true when the name matches against at least one exclude pattern, or false + * otherwise. + */ + protected boolean isExcluded( Artifact artifact ) + { + final Path projectBasePath = project.getBasedir().toPath(); + final Path artifactPath = artifact.getFile().toPath(); + final String relativeArtifactPath = projectBasePath.relativize( artifactPath ).toString(); + + for ( String exclude : excludes ) + { + if ( SelectorUtils.matchPath( exclude, relativeArtifactPath ) ) + { + return true; + } + } + + return false; + } + +} From c290e8028d6366a5898b4ef340126e85928a9251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Fri, 14 Apr 2023 19:53:58 +0200 Subject: [PATCH 02/13] fix protobuff dependency discrepency between java and java-util --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 34643ae..8b1fab4 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,12 @@ under the License. sigstore-java 0.4.0 + + com.google.protobuf + protobuf-java + 3.22.0 + runtime + org.apache.maven maven-plugin-api From 8aa9dc1f143d22d9adc5eb436aa057c4555ca4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Mon, 17 Apr 2023 08:38:07 +0200 Subject: [PATCH 03/13] add optional wait time before signing a file --- .../maven/plugins/gpg/SigstoreSignAttachedMojo.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java index ea6978c..6a30b6b 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java @@ -75,6 +75,12 @@ public class SigstoreSignAttachedMojo @Parameter( defaultValue = "${project}", readonly = true, required = true ) protected MavenProject project; + /** + * PoC: wait time before each file signature (in seconds) + */ + @Parameter( property = "sigstore.wait", defaultValue = "0" ) + private long wait; + /** * Maven ProjectHelper */ @@ -181,6 +187,12 @@ else if ( project.getAttachedArtifacts().isEmpty() ) KeylessSigner signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); for ( SigningBundle bundleToSign : filesToSign ) { + if ( wait > 0 ) + { + getLog().info( "waiting for " + wait + " seconds before signing" ); + Thread.sleep( wait * 1000 ); + } + File fileToSign = bundleToSign.getSignature(); // reusing original GPG implementation where it's the signature: TODO change KeylessSignature signature = signer.signFile( fileToSign.toPath() ); From 7256c182cac61fee2d387a6d641ce621bceabb0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Mon, 17 Apr 2023 09:13:06 +0200 Subject: [PATCH 04/13] add sigstore.duration to ease tests --- .../plugins/gpg/SigstoreSignAttachedMojo.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java index 6a30b6b..90db4c8 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -81,6 +82,12 @@ public class SigstoreSignAttachedMojo @Parameter( property = "sigstore.wait", defaultValue = "0" ) private long wait; + /** + * PoC: certificate duration (in min) + */ + @Parameter( property = "sigstore.duration", defaultValue = "-1" ) + private long duration; + /** * Maven ProjectHelper */ @@ -185,6 +192,13 @@ else if ( project.getAttachedArtifacts().isEmpty() ) try { KeylessSigner signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); + if ( duration > -1 ) + { + getLog().info( "updating certificate duration to " + duration + " min" ); + signer = KeylessSigner.builder().sigstoreStagingDefaults() + .minSigningCertificateLifetime( Duration.ofMinutes( duration ) ).build(); + } + for ( SigningBundle bundleToSign : filesToSign ) { if ( wait > 0 ) From 561734899c4ca62fb1b704247530afe1131290dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Tue, 18 Apr 2023 19:41:14 +0200 Subject: [PATCH 05/13] improve messages --- .../plugins/gpg/SigstoreSignAttachedMojo.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java index 90db4c8..0f2f6b1 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java @@ -194,21 +194,28 @@ else if ( project.getAttachedArtifacts().isEmpty() ) KeylessSigner signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); if ( duration > -1 ) { - getLog().info( "updating certificate duration to " + duration + " min" ); - signer = KeylessSigner.builder().sigstoreStagingDefaults() +< getLog().info( "updating certificate minimum remaining duration to " + duration + " min" ); +> signer = KeylessSigner.builder().sigstoreStagingDefaults() .minSigningCertificateLifetime( Duration.ofMinutes( duration ) ).build(); } + boolean first = true; for ( SigningBundle bundleToSign : filesToSign ) { - if ( wait > 0 ) + if ( first ) { - getLog().info( "waiting for " + wait + " seconds before signing" ); + first = false; + } + else if ( wait > 0 ) + { + getLog().info( "waiting for " + wait + " seconds before signing next = " + + bundleToSign.getSignature() ); Thread.sleep( wait * 1000 ); } File fileToSign = bundleToSign.getSignature(); // reusing original GPG implementation where it's the signature: TODO change + getLog().info( "Signing " + fileToSign ); KeylessSignature signature = signer.signFile( fileToSign.toPath() ); // sigstore signature in bundle format (json string) From c4ff760789648333ecfd1bb2de0809fa879e5163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Thu, 27 Apr 2023 09:22:11 +0200 Subject: [PATCH 06/13] [MGPG-96] add INFO message --- .../java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java | 3 +++ .../org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java index b5e8cbb..e8b7a62 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/GpgSignAttachedMojo.java @@ -98,6 +98,9 @@ public void execute() throws MojoExecutionException, MojoFailureException { signer.setBuildDirectory(new File(project.getBuild().getDirectory())); signer.setBaseDirectory(project.getBasedir()); + getLog().info("Signing " + items.size() + " file" + ((items.size() > 1) ? "s" : "") + " with " + + ((signer.keyname == null) ? "default" : signer.keyname) + " secret key."); + for (FilesCollector.Item item : items) { getLog().debug("Generating signature for " + item.getFile()); diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java index 6ef20bf..01876bf 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java @@ -118,6 +118,8 @@ public void execute() throws MojoExecutionException, MojoFailureException { // Sign the filesToSign and attach all the signatures // ---------------------------------------------------------------------------- + getLog().info("Signing " + items.size() + " file" + ((items.size() > 1) ? "s" : "") + "."); + try { KeylessSigner signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); From c3e3b2091b9166e8962cf75af049a9b312d26ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Thu, 27 Apr 2023 10:01:33 +0200 Subject: [PATCH 07/13] [MGPG-97] use gpgverify plugin to check dependencies signatures --- pgp-keys-map.list | 59 +++++++++++++++++++++++++++++++++++++++++++++++ pom.xml | 19 +++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 pgp-keys-map.list diff --git a/pgp-keys-map.list b/pgp-keys-map.list new file mode 100644 index 0000000..be8f7ab --- /dev/null +++ b/pgp-keys-map.list @@ -0,0 +1,59 @@ +# 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. + +commons-io:commons-io = 0xCD5464315F0B98C77E6E8ECD9DAADC1C9FCC82D0 +junit:junit = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51 +org.apache.maven.resolver = 0x522CA055B326A636D833EF6A0551FD3684FCBBB7 +org.apache.maven.shared:maven-artifact-transfer = 0x6A814B1F869C2BBEAB7CB7271A2A1C94BDE89688 +org.apache.maven.shared:maven-common-artifact-filters = 0xB02137D875D833D9B23392ECAE5A7FB608A0221C +org.apache.maven.shared:maven-invoker = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1 +org.apache.maven.shared:maven-shared-utils = 0x82C9EC0E52C47A936A849E0113D979595E6D01E1 +org.codehaus.plexus:plexus-classworlds = 0xFB11D4BB7B244678337AAD8BC7BF26D0BB617866 +org.codehaus.plexus:plexus-component-annotations = 0xBA926F64CA647B6D853A38672E2010F8A7FF4A41 +org.codehaus.plexus:plexus-utils = 0x6A814B1F869C2BBEAB7CB7271A2A1C94BDE89688 +org.eclipse.aether:aether-api = 0xBA926F64CA647B6D853A38672E2010F8A7FF4A41 +org.eclipse.aether:aether-util = 0xFB11D4BB7B244678337AAD8BC7BF26D0BB617866 +org.hamcrest:hamcrest = 0xE3A9F95079E84CE201F7CF60BEDE11EAF1164480 +org.hamcrest:hamcrest-core = 0xE3A9F95079E84CE201F7CF60BEDE11EAF1164480 +org.slf4j:slf4j-api = 0x475F3B8E59E6E63AA78067482C7B12F2A511E325 +org.sonatype.plexus:plexus-cipher = 0x9FFED7A118D45A44E4A1E47130E6F80434A72A7F +org.sonatype.plexus:plexus-sec-dispatcher = 0x2BCBDD0F23EA1CAFCC11D4860374CF2E8DD1BDFD +org.sonatype.sisu = 0xBA926F64CA647B6D853A38672E2010F8A7FF4A41 + +dev.sigstore = 0xF6B17CDEEE2BB5BB7D04667D4BE41A4907BCD034 +com.google.http-client = 0x47504B76CF89C15C0512D9AFE16AB52D79FD224F +io.opencensus = 0x600EA202B1EC682F4A788E5AAC7A514BC9F9BB70 +commons-logging:commons-logging = 0x0CC641C3A62453AB390066C4A41F13C999945293 +org.apache.httpcomponents = 0x0785B3EFF60B1B1BEA94E0BB7C25280EAE63EBE5 +io.github.erdtman:java-json-canonicalization = 0x4556208EBE484FBA3984DC3D3D4FA1A9DB2FB4F4 +com.google.api.grpc:proto-google-common-protos = 0x47504B76CF89C15C0512D9AFE16AB52D79FD224F +com.google.protobuf = 0x2E5B73C6EFD2EB453104C2EAE6EC76B4C6D3AE8E +com.google.code.findbugs = 0x7616EB882DAF57A11477AAF559A252FB1199D873 +com.google.errorprone:error_prone_annotations = 0xE77417AC194160A3FABD04969A259C7EE636C5ED +com.google.guava:guava = 0xBDB5FA4FE719D787FB3D3197F6D4A1D411E9D1AE +com.google.guava:failureaccess = 0x56ED3B4843DAACC79DE555557457CA33C3CE9E15 +com.google.guava:listenablefuture = 0xBDB5FA4FE719D787FB3D3197F6D4A1D411E9D1AE +org.checkerframework:checker-qual = 0x19BEAB2D799C020F17C69126B16698A4ADF4D638 +com.google.j2objc:j2objc-annotations = 0xB801E2F8EF035068EC1139CC29579F18FA8FD93B +io.grpc = 0xB02335AA54CCF21E52BBF9ABD9C565AA72BA2FDD +commons-codec:commons-codec = 0xBC87A3FD0A54480F0BADBEBD21939FF0CA2A6567 +com.google.code.gson:gson = 0xC7BE5BCC9FEC15518CFDA882B0F3710FA64900E7 +org.bouncycastle = 0x08F0AAB4D0C1A4BDDE340765B341DDB020FCB6AB +com.google.oauth-client = 0x47504B76CF89C15C0512D9AFE16AB52D79FD224F +io.perfmark:perfmark-api = 0xC6F7D1C804C821F49AF3BFC13AD93C3C677A106E +com.google.android:annotations = 0x0F07D1201BDDAB67CFB84EB479752DB6C966F0B8 +org.codehaus.mojo:animal-sniffer-annotations = 0xF254B35617DC255D9344BCFA873A8E86B4372146 diff --git a/pom.xml b/pom.xml index 52b1fae..b3e6752 100644 --- a/pom.xml +++ b/pom.xml @@ -206,6 +206,14 @@ under the License. maven-invoker-plugin 3.5.1 + + org.simplify4u.plugins + pgpverify-maven-plugin + 1.11.0 + + ${project.basedir}/pgp-keys-map.list + + @@ -242,6 +250,17 @@ under the License. + + org.simplify4u.plugins + pgpverify-maven-plugin + + + + check + + + + From d39b0784794d902a7804bb924544116a6ca04fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Fri, 28 Apr 2023 14:00:52 +0100 Subject: [PATCH 08/13] add sigstore library sigstore signature details --- pgp-keys-map.list | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pgp-keys-map.list b/pgp-keys-map.list index be8f7ab..7e322a7 100644 --- a/pgp-keys-map.list +++ b/pgp-keys-map.list @@ -35,6 +35,13 @@ org.sonatype.plexus:plexus-sec-dispatcher = 0x2BCBDD0F23EA1CAFCC11D4860374CF2E8D org.sonatype.sisu = 0xBA926F64CA647B6D853A38672E2010F8A7FF4A41 dev.sigstore = 0xF6B17CDEEE2BB5BB7D04667D4BE41A4907BCD034 +# sigstore signature https://repo.maven.apache.org/maven2/dev/sigstore/sigstore-java/0.4.0/sigstore-java-0.4.0.jar.sigstore +# decoded with https://search.sigstore.dev/?logIndex=16039467 +# Subject Alternative Name (critical): +# email: +# - appu@google.com +# OIDC Issuer: https://accounts.google.com + com.google.http-client = 0x47504B76CF89C15C0512D9AFE16AB52D79FD224F io.opencensus = 0x600EA202B1EC682F4A788E5AAC7A514BC9F9BB70 commons-logging:commons-logging = 0x0CC641C3A62453AB390066C4A41F13C999945293 From 8dc196db04fdb31d0d406b18f50028f611cbec81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Sat, 29 Apr 2023 11:43:40 +0200 Subject: [PATCH 09/13] display time to get rekorded signature --- .../plugins/gpg/SigstoreSignAttachedMojo.java | 34 +++---------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java index 01876bf..f89c3ca 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java @@ -38,7 +38,6 @@ */ import java.io.File; -import java.time.Duration; import java.util.List; import dev.sigstore.KeylessSignature; @@ -82,18 +81,6 @@ public class SigstoreSignAttachedMojo extends AbstractMojo { @Parameter(defaultValue = "${project}", readonly = true, required = true) protected MavenProject project; - /** - * PoC: wait time before each file signature (in seconds) - */ - @Parameter(property = "sigstore.wait", defaultValue = "0") - private long wait; - - /** - * PoC: certificate duration (in min) - */ - @Parameter(property = "sigstore.duration", defaultValue = "-1") - private long duration; - /** * Maven ProjectHelper */ @@ -123,28 +110,12 @@ public void execute() throws MojoExecutionException, MojoFailureException { try { KeylessSigner signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); - if (duration > -1) { - getLog().info("updating certificate minimum remaining duration to " + duration + " min"); - signer = KeylessSigner.builder() - .sigstoreStagingDefaults() - .minSigningCertificateLifetime(Duration.ofMinutes(duration)) - .build(); - } - boolean first = true; for (FilesCollector.Item item : items) { - getLog().debug("Generating signature for " + item.getFile()); - - if (first) { - first = false; - } else if (wait > 0) { - getLog().info("waiting for " + wait + " seconds before signing next = " + item.getFile()); - Thread.sleep(wait * 1000); - } - File fileToSign = item.getFile(); getLog().info("Signing " + fileToSign); + long start = System.currentTimeMillis(); KeylessSignature signature = signer.signFile(fileToSign.toPath()); // sigstore signature in bundle format (json string) @@ -153,6 +124,9 @@ public void execute() throws MojoExecutionException, MojoFailureException { File signatureFile = new File(fileToSign + ".sigstore"); FileUtils.fileWrite(signatureFile, "UTF-8", sigstoreBundle); + long duration = System.currentTimeMillis() - start; + getLog().info(" > " + signatureFile.getName() + " in " + duration + " ms"); + projectHelper.attachArtifact( project, item.getExtension() + ".sigstore", item.getClassifier(), signatureFile); } From 3b186f1e8c3bcfc01fa21cec988de73fced70a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Sun, 30 Apr 2023 16:48:49 +0200 Subject: [PATCH 10/13] ignore checksum for .signature, waiting for MNG-7776 --- .mvn/maven.config | 1 + pom.xml | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 .mvn/maven.config diff --git a/.mvn/maven.config b/.mvn/maven.config new file mode 100644 index 0000000..a274581 --- /dev/null +++ b/.mvn/maven.config @@ -0,0 +1 @@ +-Daether.checksums.omitChecksumsForExtensions=.asc,.sigstore \ No newline at end of file diff --git a/pom.xml b/pom.xml index 42a5def..973834d 100644 --- a/pom.xml +++ b/pom.xml @@ -261,6 +261,15 @@ under the License. + + org.apache.rat + apache-rat-plugin + + + .mvn/maven.config + + + From 902799981807159ca0ec12cf3fafb67ce2b23d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Sun, 7 May 2023 10:44:44 +0200 Subject: [PATCH 11/13] move sigstore sign mojo to its own java package --- .../plugins/{gpg => sigstore}/SigstoreSignAttachedMojo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/main/java/org/apache/maven/plugins/{gpg => sigstore}/SigstoreSignAttachedMojo.java (98%) diff --git a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java similarity index 98% rename from src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java rename to src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java index f89c3ca..040ead2 100644 --- a/src/main/java/org/apache/maven/plugins/gpg/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.plugins.gpg; +package org.apache.maven.plugins.sigstore; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -50,6 +50,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.gpg.FilesCollector; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.util.FileUtils; From 5e997d328b6a2613a0c2e60f569b734e4310d3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Sun, 7 May 2023 18:28:59 +0200 Subject: [PATCH 12/13] support public default in addition to staging --- pom.xml | 3 +++ .../sigstore/SigstoreSignAttachedMojo.java | 21 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 05c17ad..f48e827 100644 --- a/pom.xml +++ b/pom.xml @@ -343,6 +343,9 @@ under the License. org.apache.maven.plugins maven-gpg-plugin + + true + sigstore-sign-release-artifacts diff --git a/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java index 040ead2..0c24883 100644 --- a/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java @@ -58,7 +58,7 @@ /** * Sign project artifact, the POM, and attached artifacts with sigstore for deployment. * - * @since 3.1.0 + * @since 3.1.1 */ @Mojo(name = "sigstore", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true) public class SigstoreSignAttachedMojo extends AbstractMojo { @@ -76,11 +76,17 @@ public class SigstoreSignAttachedMojo extends AbstractMojo { @Parameter private String[] excludes; + /** + * Use public staging {@code sigstage.dev} instead of public default {@code sigstore.dev}. + */ + @Parameter(defaultValue = "false", property = "public-staging") + private boolean publicStaging; + /** * The Maven project. */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - protected MavenProject project; + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; /** * Maven ProjectHelper @@ -109,8 +115,13 @@ public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("Signing " + items.size() + " file" + ((items.size() > 1) ? "s" : "") + "."); try { - KeylessSigner signer = - KeylessSigner.builder().sigstoreStagingDefaults().build(); + KeylessSigner signer; + + if (publicStaging) { + signer = KeylessSigner.builder().sigstoreStagingDefaults().build(); + } else { + signer = KeylessSigner.builder().sigstorePublicDefaults().build(); + } for (FilesCollector.Item item : items) { File fileToSign = item.getFile(); From d093dca517ed50090522b3b7f92d687b39b2e078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Sun, 7 May 2023 19:14:23 +0200 Subject: [PATCH 13/13] display key info on signature (PoC) --- .../maven/plugins/sigstore/SigstoreSignAttachedMojo.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java b/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java index 0c24883..b26826a 100644 --- a/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java +++ b/src/main/java/org/apache/maven/plugins/sigstore/SigstoreSignAttachedMojo.java @@ -38,6 +38,7 @@ */ import java.io.File; +import java.security.cert.X509Certificate; import java.util.List; import dev.sigstore.KeylessSignature; @@ -141,6 +142,13 @@ public void execute() throws MojoExecutionException, MojoFailureException { projectHelper.attachArtifact( project, item.getExtension() + ".sigstore", item.getClassifier(), signatureFile); + + getLog().info(" Rekor logIndex: " + + signature.getEntry().get().getLogIndex()); + X509Certificate cert = (X509Certificate) + signature.getCertPath().getCertificates().get(0); + getLog().info(" Certificate Issuer DN: " + cert.getIssuerDN()); + getLog().info(" Subject Alternative Names: " + cert.getSubjectAlternativeNames()); } } catch (Exception e) { throw new MojoExecutionException("Error while signing with sigstore", e);