mirror of
				https://github.com/scm-manager/scm-manager.git
				synced 2025-11-03 20:15:52 +01:00 
			
		
		
		
	work on getting signatures running
This commit is contained in:
		@@ -422,16 +422,8 @@ public final class GitUtil
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Method description
 | 
			
		||||
   *
 | 
			
		||||
   *
 | 
			
		||||
   * @param repository
 | 
			
		||||
   * @param revWalk
 | 
			
		||||
   * @param ref
 | 
			
		||||
   *
 | 
			
		||||
   * @return
 | 
			
		||||
   *
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   * Returns the commit for the given ref.
 | 
			
		||||
   * If the given ref is for a tag, the commit that this tag belongs to is returned instead.
 | 
			
		||||
   */
 | 
			
		||||
  public static RevCommit getCommit(org.eclipse.jgit.lib.Repository repository,
 | 
			
		||||
    RevWalk revWalk, Ref ref)
 | 
			
		||||
@@ -710,22 +702,20 @@ public final class GitUtil
 | 
			
		||||
    return name;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static final byte[] GPG_HEADER = {'P', 'G', 'P'};
 | 
			
		||||
  private static final String GPG_HEADER = "-----BEGIN PGP SIGNATURE-----";
 | 
			
		||||
 | 
			
		||||
  public static Optional<Signature> getTagSignature(RevObject revObject, GPG gpg)  {
 | 
			
		||||
  public static Optional<Signature> getTagSignature(RevObject revObject, GPG gpg, RevWalk revWalk) throws IOException {
 | 
			
		||||
    if (revObject instanceof RevTag) {
 | 
			
		||||
      RevTag tag = (RevTag) revObject;
 | 
			
		||||
      byte[] raw = tag.getFullMessage().getBytes();
 | 
			
		||||
 | 
			
		||||
      int start = RawParseUtils.headerStart(GPG_HEADER, raw, 0);
 | 
			
		||||
      if (start < 0) {
 | 
			
		||||
      final byte[] bytes = revWalk.getObjectReader().open(revObject.getId()).getBytes();
 | 
			
		||||
      final String message = new String(bytes);
 | 
			
		||||
      final int signatureStartIndex = message.indexOf(GPG_HEADER);
 | 
			
		||||
      if (signatureStartIndex < 0) {
 | 
			
		||||
        return Optional.empty();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int end = RawParseUtils.headerEnd(raw, start);
 | 
			
		||||
      byte[] signature = Arrays.copyOfRange(raw, start, end);
 | 
			
		||||
      final String signature = message.substring(signatureStartIndex);
 | 
			
		||||
 | 
			
		||||
      String publicKeyId = gpg.findPublicKeyId(signature);
 | 
			
		||||
      String publicKeyId = gpg.findPublicKeyId(signature.getBytes());
 | 
			
		||||
      if (Strings.isNullOrEmpty(publicKeyId)) {
 | 
			
		||||
        // key not found
 | 
			
		||||
        return Optional.of(new Signature(publicKeyId, "gpg", SignatureStatus.NOT_FOUND, null, Collections.emptySet()));
 | 
			
		||||
@@ -739,19 +729,7 @@ public final class GitUtil
 | 
			
		||||
 | 
			
		||||
      PublicKey publicKey = publicKeyById.get();
 | 
			
		||||
 | 
			
		||||
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
			
		||||
      try {
 | 
			
		||||
        byte[] headerPrefix = Arrays.copyOfRange(raw, 0, start - GPG_HEADER.length - 1);
 | 
			
		||||
        baos.write(headerPrefix);
 | 
			
		||||
 | 
			
		||||
        byte[] headerSuffix = Arrays.copyOfRange(raw, end + 1, raw.length);
 | 
			
		||||
        baos.write(headerSuffix);
 | 
			
		||||
      } catch (IOException ex) {
 | 
			
		||||
        // this will never happen, because we are writing into memory
 | 
			
		||||
        throw new IllegalStateException("failed to write into memory", ex);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      boolean verified = publicKey.verify(baos.toByteArray(), signature);
 | 
			
		||||
      boolean verified = publicKey.verify(message.substring(0, signatureStartIndex - 1).getBytes(), signature.getBytes());
 | 
			
		||||
      return Optional.of(new Signature(
 | 
			
		||||
        publicKeyId,
 | 
			
		||||
        "gpg",
 | 
			
		||||
 
 | 
			
		||||
@@ -111,7 +111,7 @@ public class GitTagCommand extends AbstractGitCommand implements TagCommand {
 | 
			
		||||
 | 
			
		||||
      try (RevWalk walk = new RevWalk(git.getRepository())) {
 | 
			
		||||
        revObject = walk.parseTag(ref.getObjectId());
 | 
			
		||||
        final Optional<Signature> tagSignature = GitUtil.getTagSignature(revObject, gpg);
 | 
			
		||||
        final Optional<Signature> tagSignature = GitUtil.getTagSignature(revObject, gpg, walk);
 | 
			
		||||
        tagSignature.ifPresent(tag::addSignature);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand {
 | 
			
		||||
      List<Ref> tagList = git.tagList().call();
 | 
			
		||||
 | 
			
		||||
      tags = Lists.transform(tagList,
 | 
			
		||||
        new TransformFuntion(git.getRepository(), revWalk, gpg, git));
 | 
			
		||||
        new TransformFunction(git.getRepository(), revWalk, gpg, git));
 | 
			
		||||
    } catch (GitAPIException ex) {
 | 
			
		||||
      throw new InternalRepositoryException(repository, "could not read tags from repository", ex);
 | 
			
		||||
    } finally {
 | 
			
		||||
@@ -100,13 +100,13 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand {
 | 
			
		||||
   * @author Enter your name here...
 | 
			
		||||
   * @version Enter version here..., 12/07/06
 | 
			
		||||
   */
 | 
			
		||||
  private static class TransformFuntion implements Function<Ref, Tag> {
 | 
			
		||||
  private static class TransformFunction implements Function<Ref, Tag> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * the logger for TransformFuntion
 | 
			
		||||
     */
 | 
			
		||||
    private static final Logger logger =
 | 
			
		||||
      LoggerFactory.getLogger(TransformFuntion.class);
 | 
			
		||||
      LoggerFactory.getLogger(TransformFunction.class);
 | 
			
		||||
 | 
			
		||||
    //~--- constructors -------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@@ -116,10 +116,10 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand {
 | 
			
		||||
     * @param repository
 | 
			
		||||
     * @param revWalk
 | 
			
		||||
     */
 | 
			
		||||
    public TransformFuntion(org.eclipse.jgit.lib.Repository repository,
 | 
			
		||||
                            RevWalk revWalk,
 | 
			
		||||
                            GPG gpg,
 | 
			
		||||
                            Git git) {
 | 
			
		||||
    public TransformFunction(org.eclipse.jgit.lib.Repository repository,
 | 
			
		||||
                             RevWalk revWalk,
 | 
			
		||||
                             GPG gpg,
 | 
			
		||||
                             Git git) {
 | 
			
		||||
      this.repository = repository;
 | 
			
		||||
      this.revWalk = revWalk;
 | 
			
		||||
      this.gpg = gpg;
 | 
			
		||||
@@ -149,12 +149,12 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand {
 | 
			
		||||
          try {
 | 
			
		||||
            RevTag revTag = GitUtil.getTag(repository, revWalk, ref);
 | 
			
		||||
 | 
			
		||||
            final Optional<Signature> tagSignature = GitUtil.getTagSignature(revTag, gpg);
 | 
			
		||||
            final Optional<Signature> tagSignature = GitUtil.getTagSignature(revTag, gpg, revWalk);
 | 
			
		||||
            if (tagSignature.isPresent()) {
 | 
			
		||||
              tag.addSignature(tagSignature.get());
 | 
			
		||||
            }
 | 
			
		||||
          } catch (IncorrectObjectTypeException e) {
 | 
			
		||||
            // Ignore, this must be a lightweight tag
 | 
			
		||||
            // Ignore because it is a lightweight tag which cannot have signatures
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -24,41 +24,33 @@
 | 
			
		||||
 | 
			
		||||
package sonia.scm.repository.spi;
 | 
			
		||||
 | 
			
		||||
import com.github.sdorra.shiro.ShiroRule;
 | 
			
		||||
import com.github.sdorra.shiro.SubjectAware;
 | 
			
		||||
import org.junit.Rule;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.rules.TemporaryFolder;
 | 
			
		||||
import org.junit.runner.RunWith;
 | 
			
		||||
import org.mockito.ArgumentMatchers;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
import org.mockito.Mockito;
 | 
			
		||||
import org.mockito.junit.MockitoJUnitRunner;
 | 
			
		||||
import sonia.scm.repository.Tag;
 | 
			
		||||
import sonia.scm.security.GPG;
 | 
			
		||||
import sonia.scm.security.PublicKey;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.anyOf;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.mockito.Mockito.when;
 | 
			
		||||
 | 
			
		||||
@SubjectAware(configuration = "classpath:sonia/scm/configuration/shiro.ini", username = "admin", password = "secret")
 | 
			
		||||
@RunWith(MockitoJUnitRunner.class)
 | 
			
		||||
public class GitTagsCommandTest extends AbstractGitCommandTestBase {
 | 
			
		||||
 | 
			
		||||
  @Rule
 | 
			
		||||
  public TemporaryFolder temporaryFolder = new TemporaryFolder();
 | 
			
		||||
 | 
			
		||||
  @Rule
 | 
			
		||||
  public BindTransportProtocolRule transportProtocolRule = new BindTransportProtocolRule();
 | 
			
		||||
 | 
			
		||||
  @Rule
 | 
			
		||||
  public ShiroRule shiro = new ShiroRule();
 | 
			
		||||
 | 
			
		||||
  @Mock
 | 
			
		||||
  GPG gpg;
 | 
			
		||||
 | 
			
		||||
  @Mock
 | 
			
		||||
  PublicKey publicKey;
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  public void shouldGetDatesCorrectly() throws IOException {
 | 
			
		||||
    final GitContext gitContext = createContext();
 | 
			
		||||
@@ -79,7 +71,24 @@ public class GitTagsCommandTest extends AbstractGitCommandTestBase {
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  public void shouldGetSignatures() throws IOException {
 | 
			
		||||
    Mockito.when(gpg.findPublicKeyId(ArgumentMatchers.any())).thenReturn("2BA27721F113C005CC16F06BAE63EFBC49F140CF");
 | 
			
		||||
    when(gpg.findPublicKeyId(ArgumentMatchers.any())).thenReturn("2BA27721F113C005CC16F06BAE63EFBC49F140CF");
 | 
			
		||||
    when(gpg.findPublicKey("2BA27721F113C005CC16F06BAE63EFBC49F140CF")).thenReturn(Optional.of(publicKey));
 | 
			
		||||
    String signature = "-----BEGIN PGP SIGNATURE-----\n" +
 | 
			
		||||
      "\n" +
 | 
			
		||||
      "iQEzBAABCgAdFiEEK6J3IfETwAXMFvBrrmPvvEnxQM8FAl+9acoACgkQrmPvvEnx\n" +
 | 
			
		||||
      "QM9abwgAnGP+Y/Ijli+PAsimfOmZQWYepjptoOv9m7i3bnHv8V+Qg6cm51I3E0YV\n" +
 | 
			
		||||
      "R2QaxxzW9PgS4hcES+L1qs8Lwo18RurF469eZEmNb8DcUFJ3sEWeHlIl5wZNNo/v\n" +
 | 
			
		||||
      "jJm0d9LNcSmtAIiQ8eDMoGdFXJzHewGickLOSsQGmfZgZus4Qlsh7r3BZTI1Zwd/\n" +
 | 
			
		||||
      "6jaBFctX13FuepCTxq2SjEfRaQHIYkyFQq2o6mjL5S2qfYJ/S//gcCCzxllQrisF\n" +
 | 
			
		||||
      "5fRW3LzLI4eXFH0vua7+UzNS2Rwpifg2OENJA/Kn+3R36LWEGxFK9pNqjVPRAcQj\n" +
 | 
			
		||||
      "1vSkcjK26RqhAqCjNLSagM8ATZrh+g==\n" +
 | 
			
		||||
      "=kUKm\n" +
 | 
			
		||||
      "-----END PGP SIGNATURE-----\n";
 | 
			
		||||
    String signedContent = "Tagger: Arthur Dent <arthur.dent@hitchhiker.com>\n" +
 | 
			
		||||
      "Date:   Tue Nov 24 21:37:46 2020 +0100\n" +
 | 
			
		||||
      "\n" +
 | 
			
		||||
      "this tag is signed";
 | 
			
		||||
    when(publicKey.verify(signedContent.getBytes(), signature.getBytes())).thenReturn(true);
 | 
			
		||||
 | 
			
		||||
    final GitContext gitContext = createContext();
 | 
			
		||||
    final GitTagsCommand tagsCommand = new GitTagsCommand(gitContext, gpg);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user