From 4da410a4b84c06c610d48d282cbc5e3c1c3eed9e Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Mon, 1 Apr 2024 00:01:07 +0200 Subject: [PATCH] Support for new algorithm in ShowMojo --- .../java/org/simplify4u/plugins/ShowMojo.java | 10 +-- .../plugins/pgp/SignatureUtils.java | 83 +++++++++++++------ .../org/simplify4u/plugins/ShowMojoTest.java | 27 +++--- .../plugins/pgp/SignatureUtilsTest.java | 25 +++++- 4 files changed, 99 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/simplify4u/plugins/ShowMojo.java b/src/main/java/org/simplify4u/plugins/ShowMojo.java index 427a0c63..8ba2e5ea 100644 --- a/src/main/java/org/simplify4u/plugins/ShowMojo.java +++ b/src/main/java/org/simplify4u/plugins/ShowMojo.java @@ -15,13 +15,13 @@ */ package org.simplify4u.plugins; +import javax.inject.Inject; + import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; -import javax.inject.Inject; -import io.vavr.control.Try; import lombok.AccessLevel; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -31,7 +31,6 @@ import org.apache.maven.repository.RepositorySystem; import org.apache.maven.shared.utils.logging.MessageBuilder; import org.apache.maven.shared.utils.logging.MessageUtils; -import org.bouncycastle.openpgp.PGPUtil; import org.simplify4u.plugins.pgp.ArtifactInfo; import org.simplify4u.plugins.pgp.KeyInfo; import org.simplify4u.plugins.pgp.SignatureCheckResult; @@ -130,9 +129,8 @@ private boolean processArtifact(Map.Entry artifactEntry) { messageBuilder.a("PGP signature:").newline(); messageBuilder.a("\tversion: ").strong(signature.getVersion()).newline(); messageBuilder.a("\talgorithm: ") - .strong(Try.of(() -> - PGPUtil.getSignatureName(signature.getKeyAlgorithm(), signature.getHashAlgorithm())).get()) - .newline(); + .strong(signatureUtils.digestName(signature.getHashAlgorithm()) + " with " + + signatureUtils.keyAlgorithmName(signature.getKeyAlgorithm())).newline(); messageBuilder.a("\tkeyId: ").strong(signature.getKeyId()).newline(); messageBuilder.a("\tcreate date: ").strong(signature.getDate()).newline(); messageBuilder.a("\tstatus: "); diff --git a/src/main/java/org/simplify4u/plugins/pgp/SignatureUtils.java b/src/main/java/org/simplify4u/plugins/pgp/SignatureUtils.java index d053c2b3..3eb01b12 100644 --- a/src/main/java/org/simplify4u/plugins/pgp/SignatureUtils.java +++ b/src/main/java/org/simplify4u/plugins/pgp/SignatureUtils.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.math.BigInteger; import java.util.Optional; + import javax.inject.Named; import javax.inject.Singleton; @@ -60,7 +61,6 @@ public class SignatureUtils { * Check PGP signature for bad algorithms. * * @param hashAlgorithm PGP signature hashAlgorithm - * * @return Returns null if no bad algorithms used, or algorithm name if used. */ public String checkWeakHashAlgorithm(int hashAlgorithm) { @@ -97,9 +97,7 @@ public String checkWeakHashAlgorithm(int hashAlgorithm) { * Load PGPSignature from input stream. * * @param input the input stream having PGPSignature content - * * @return Returns the (first) read PGP signature. - * * @throws SignatureException In case of failure loading signature. */ public PGPSignature loadSignature(InputStream input) throws SignatureException { @@ -140,11 +138,9 @@ public PGPSignature loadSignature(InputStream input) throws SignatureException { * Load PGPSignature from file. * * @param file the file having PGPSignature content - * * @return Returns the (first) read PGP signature. - * * @throws SignatureException In case of failure loading signature. - * @throws IOException In case of IO failures. + * @throws IOException In case of IO failures. */ public PGPSignature loadSignature(File file) throws IOException, SignatureException { try (InputStream in = new FileInputStream(file)) { @@ -157,7 +153,6 @@ public PGPSignature loadSignature(File file) throws IOException, SignatureExcept * * @param signature the PGP signature instance. The instance is expected to be initialized. * @param file the file to read - * * @throws IOException In case of failure to open the file or failure while reading its content. */ public void readFileContentInto(final PGPSignature signature, final File file) throws IOException { @@ -174,9 +169,7 @@ public void readFileContentInto(final PGPSignature signature, final File file) t * Retrieve Key Id from signature ISSUER_FINGERPRINT subpackage or standard keyId. * * @param signature the PGP signature instance - * * @return Returns the keyId from signature - * * @throws SignatureException In case of problem with signature data */ public KeyId retrieveKeyId(PGPSignature signature) throws SignatureException { @@ -201,7 +194,6 @@ public KeyId retrieveKeyId(PGPSignature signature) throws SignatureException { .map(PGPSignatureSubpacketVector::getIssuerKeyID) .filter(id -> id != 0L); - if (!issuerKeyId.isPresent()) { issuerKeyId = hashedSubPackets .map(PGPSignatureSubpacketVector::getIssuerKeyID) @@ -250,11 +242,10 @@ public KeyId retrieveKeyId(PGPSignature signature) throws SignatureException { * @param artifactAsc The artifact contains signature * @param onlyResolve Only resolve signature and keys * @param cache PGP cache for access public key - * * @return check verification result */ private SignatureCheckResult checkSignature(Artifact artifact, Artifact artifactAsc, - boolean onlyResolve, PGPKeysCache cache) { + boolean onlyResolve, PGPKeysCache cache) { SignatureCheckResult.SignatureCheckResultBuilder signatureCheckResultBuilder = SignatureCheckResult.builder(); @@ -332,10 +323,10 @@ private SignatureCheckResult checkSignature(Artifact artifact, Artifact artifact } Boolean verifyStatus = Try.of(() -> { - signature.init(new BcPGPContentVerifierBuilderProvider(), publicKey); - readFileContentInto(signature, artifact.getFile()); - return signature.verify(); - }).onFailure(e -> signatureCheckResultBuilder.errorCause(e).status(SignatureStatus.ERROR)) + signature.init(new BcPGPContentVerifierBuilderProvider(), publicKey); + readFileContentInto(signature, artifact.getFile()); + return signature.verify(); + }).onFailure(e -> signatureCheckResultBuilder.errorCause(e).status(SignatureStatus.ERROR)) .getOrNull(); if (verifyStatus == null) { @@ -355,7 +346,6 @@ private SignatureCheckResult checkSignature(Artifact artifact, Artifact artifact * @param artifact The artifact to check signature * @param artifactAsc The artifact contains signature * @param cache PGP cache for access public key - * * @return check verification result */ public SignatureCheckResult checkSignature(Artifact artifact, Artifact artifactAsc, PGPKeysCache cache) { @@ -369,7 +359,6 @@ public SignatureCheckResult checkSignature(Artifact artifact, Artifact artifactA * @param artifact The artifact to check signature * @param artifactAsc The artifact contains signature * @param cache PGP cache for access public key - * * @return check verification result */ public SignatureCheckResult resolveSignature(Artifact artifact, Artifact artifactAsc, PGPKeysCache cache) { @@ -377,14 +366,12 @@ public SignatureCheckResult resolveSignature(Artifact artifact, Artifact artifac } /** - * Map Public-Key algorithms id to name - * - * @param keyAlgorithm key algorithm id - * - * @return key algorithm name - * - * @throws UnsupportedOperationException if algorithm is is not known - */ + * Map Public-Key algorithms id to name + * + * @param keyAlgorithm key algorithm id + * @return key algorithm name + * @throws UnsupportedOperationException if algorithm is is not known + */ public String keyAlgorithmName(int keyAlgorithm) { switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: @@ -431,4 +418,48 @@ public String keyAlgorithmName(int keyAlgorithm) { throw new UnsupportedOperationException("Unknown key algorithm value encountered: " + keyAlgorithm); } } + + public String digestName(int hashAlgorithm) { + switch (hashAlgorithm) { + case HashAlgorithmTags.SHA1: + return "SHA1"; + case HashAlgorithmTags.DOUBLE_SHA: + return "double-width SHA"; + case HashAlgorithmTags.MD2: + return "MD2"; + case HashAlgorithmTags.MD4: + return "MD4"; + case HashAlgorithmTags.MD5: + return "MD5"; + case HashAlgorithmTags.HAVAL_5_160: + return "HAVAL (5 pass, 160-bit)"; + case HashAlgorithmTags.RIPEMD160: + return "RIPEMD160"; + case HashAlgorithmTags.SHA256: + return "SHA256"; + case HashAlgorithmTags.SHA384: + return "SHA384"; + case HashAlgorithmTags.SHA512: + return "SHA512"; + case HashAlgorithmTags.SHA224: + return "SHA224"; + case HashAlgorithmTags.SHA3_256: + case HashAlgorithmTags.SHA3_256_OLD: + return "SHA256"; + case HashAlgorithmTags.SHA3_384: + return "SHA384"; + case HashAlgorithmTags.SHA3_512: + case HashAlgorithmTags.SHA3_512_OLD: + return "SHA512"; + case HashAlgorithmTags.SHA3_224: + return "SHA224"; + case HashAlgorithmTags.TIGER_192: + return "TIGER"; + case HashAlgorithmTags.SM3: + return "SM3"; + default: + throw new UnsupportedOperationException( + "Unknown hash algorithm tag in digestName: " + hashAlgorithm); + } + } } diff --git a/src/test/java/org/simplify4u/plugins/ShowMojoTest.java b/src/test/java/org/simplify4u/plugins/ShowMojoTest.java index e23c9af0..78bac6a5 100644 --- a/src/test/java/org/simplify4u/plugins/ShowMojoTest.java +++ b/src/test/java/org/simplify4u/plugins/ShowMojoTest.java @@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -69,14 +70,13 @@ public class ShowMojoTest { @InjectMocks private ShowMojo mojo; - @Test void shouldReturnMojoName() { assertThat(mojo.getMojoName()).isEqualTo(ShowMojo.MOJO_NAME); } public static String[] invalidArtifactNames() { - return new String[]{null, "test", "test:test", "test:test:1.0:type:class:class"}; + return new String[] {null, "test", "test:test", "test:test:1.0:type:class:class"}; } @ParameterizedTest @@ -103,9 +103,10 @@ void shouldProcessArtifact() throws MojoFailureException, MojoExecutionException //given mojo.setArtifact("groupId:artifactId:1.0.0:war"); - when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), isNull())).thenReturn(artifact); - when(artifactResolver.resolveSignatures(anyCollection())).thenReturn(Collections.singletonMap(artifact, artifactAsc)); - + when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), + isNull())).thenReturn(artifact); + when(artifactResolver.resolveSignatures(anyCollection())).thenReturn( + Collections.singletonMap(artifact, artifactAsc)); SignatureCheckResult signatureCheckResult = aSignatureCheckResultBuilder() .status(SignatureStatus.SIGNATURE_VALID) @@ -122,7 +123,8 @@ void shouldProcessArtifact() throws MojoFailureException, MojoExecutionException verify(artifactResolver).resolveSignatures(anyCollection()); verify(signatureUtils).checkSignature(artifact, artifactAsc, pgpKeysCache); - verify(signatureUtils).keyAlgorithmName(anyInt()); + verify(signatureUtils, times(2)).keyAlgorithmName(anyInt()); + verify(signatureUtils).digestName(anyInt()); verify(pgpKeysCache).init(any(), any()); @@ -138,7 +140,8 @@ void shouldProcessArtifactWithPom() throws MojoFailureException, MojoExecutionEx mojo.setArtifact("groupId:artifactId:1.0.0:war"); mojo.setShowPom(true); - when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), isNull())) + when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), + isNull())) .thenReturn(artifact); // when @@ -150,7 +153,6 @@ void shouldProcessArtifactWithPom() throws MojoFailureException, MojoExecutionEx verify(artifactResolver).resolvePom(artifact); verify(artifactResolver).resolveSignatures(anyCollection()); - verify(pgpKeysCache).init(any(), any()); verifyNoMoreInteractions(artifactResolver, pgpKeysCache, signatureUtils, repositorySystem); @@ -165,7 +167,8 @@ void shouldFailForNotResolvedArtifact() throws IOException { //given mojo.setArtifact("groupId:artifactId:1.0.0:war"); - when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), isNull())) + when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), + isNull())) .thenReturn(artifact); when(artifactResolver.resolveSignatures(anyCollection())) @@ -187,7 +190,8 @@ void shouldFailForNotResolvedArtifact() throws IOException { verify(artifactResolver).resolveArtifact(artifact); verify(artifactResolver).resolveSignatures(anyCollection()); - verify(signatureUtils).keyAlgorithmName(anyInt()); + verify(signatureUtils, times(2)).keyAlgorithmName(anyInt()); + verify(signatureUtils).digestName(anyInt()); verify(pgpKeysCache).init(any(), any()); @@ -203,7 +207,8 @@ void shouldFailForNotResolvedSignature() throws MojoExecutionException, IOExcept //given mojo.setArtifact("groupId:artifactId:1.0.0:war"); - when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), isNull())) + when(repositorySystem.createArtifactWithClassifier(anyString(), anyString(), anyString(), anyString(), + isNull())) .thenReturn(artifact); when(artifactResolver.resolveSignatures(anyCollection())) diff --git a/src/test/java/org/simplify4u/plugins/pgp/SignatureUtilsTest.java b/src/test/java/org/simplify4u/plugins/pgp/SignatureUtilsTest.java index e0b682d7..60d7d1ea 100644 --- a/src/test/java/org/simplify4u/plugins/pgp/SignatureUtilsTest.java +++ b/src/test/java/org/simplify4u/plugins/pgp/SignatureUtilsTest.java @@ -103,7 +103,7 @@ void testCheckWeakHashAlgorithmAllAlgorithms(int algorithm, boolean strong) { } public static Object[][] providerSignatureHashAlgorithms() { - return new Object[][]{ + return new Object[][] { {HashAlgorithmTags.MD5, false}, {HashAlgorithmTags.SHA1, true}, {HashAlgorithmTags.RIPEMD160, true}, @@ -303,7 +303,6 @@ void checkSignaturePositiveFlow() throws IOException, PGPException { .build()); } - public static Object[] keyAlgorithms() { return Arrays.stream(PublicKeyAlgorithmTags.class.getDeclaredFields()) .map(filed -> Try.of(() -> filed.getInt(null)).get()) @@ -317,9 +316,29 @@ void keyAlgorithmNameShouldBeResolved(int keyAlgorithm) { } @Test - void unKnownKeyAlgorithmThrowExceptio() { + void unKnownKeyAlgorithmThrowException() { assertThatCode(() -> signatureUtils.keyAlgorithmName(9999998)) .isExactlyInstanceOf(UnsupportedOperationException.class) .hasMessage("Unknown key algorithm value encountered: 9999998"); } + + public static Object[] digestAlgorithms() { + return Arrays.stream(HashAlgorithmTags.class.getDeclaredFields()) + .map(filed -> Try.of(() -> filed.getInt(null)).get()) + .toArray(); + } + + @ParameterizedTest + @MethodSource("digestAlgorithms") + void digestNameShouldBeResolved(int keyAlgorithm) { + assertThat(signatureUtils.digestName(keyAlgorithm)).isNotBlank(); + } + + @Test + void unKnownDigestNameThrowException() { + assertThatCode(() -> signatureUtils.digestName(9999998)) + .isExactlyInstanceOf(UnsupportedOperationException.class) + .hasMessage("Unknown hash algorithm tag in digestName: 9999998"); + } + }