Skip to content

Commit

Permalink
Merge pull request #524 from s4u/show-mojo-new-alg
Browse files Browse the repository at this point in the history
Support for new algorithm in ShowMojo
  • Loading branch information
slawekjaranowski committed Apr 1, 2024
2 parents 8312ad7 + 4da410a commit 981cd6b
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 46 deletions.
10 changes: 4 additions & 6 deletions src/main/java/org/simplify4u/plugins/ShowMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -130,9 +129,8 @@ private boolean processArtifact(Map.Entry<Artifact, Artifact> 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: ");
Expand Down
83 changes: 57 additions & 26 deletions src/main/java/org/simplify4u/plugins/pgp/SignatureUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.io.InputStream;
import java.math.BigInteger;
import java.util.Optional;

import javax.inject.Named;
import javax.inject.Singleton;

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)) {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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)
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -369,22 +359,19 @@ 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) {
return checkSignature(artifact, artifactAsc, true, cache);
}

/**
* 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:
Expand Down Expand Up @@ -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);
}
}
}
27 changes: 16 additions & 11 deletions src/test/java/org/simplify4u/plugins/ShowMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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());

Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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()))
Expand All @@ -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());

Expand All @@ -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()))
Expand Down
25 changes: 22 additions & 3 deletions src/test/java/org/simplify4u/plugins/pgp/SignatureUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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())
Expand All @@ -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");
}

}

0 comments on commit 981cd6b

Please sign in to comment.