Skip to content

Commit

Permalink
Add Commit.ExtractSignature to get signature data from a commit
Browse files Browse the repository at this point in the history
This method returns the signature data along with the rest of the commit
without this header field, ready to be fed to whatever authentication
method the caller prefers.
  • Loading branch information
carlosmn committed Apr 26, 2016
1 parent e9f5778 commit 73aa605
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 0 deletions.
71 changes: 71 additions & 0 deletions LibGit2Sharp.Tests/CommitFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using LibGit2Sharp.Core;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
Expand Down Expand Up @@ -1055,5 +1056,75 @@ public void CanPrettifyAMessage()
Assert.Equal(expected, Commit.PrettifyMessage(input, '#'));
Assert.Equal(expected, Commit.PrettifyMessage(input.Replace('#', ';'), ';'));
}

[Fact]
public void CanExtractSignatureFromCommit()
{
string commitData = @"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6
parent 34734e478d6cf50c27c9d69026d93974d052c454
author Ben Burkert <[email protected]> 1358451456 -0800
committer Ben Burkert <[email protected]> 1358451456 -0800
gpgsig -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (Darwin)
iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al
o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8
JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq
AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq
SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW
who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok
6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG
cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu
c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9
ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J
7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc
cpxtDQQMGYFpXK/71stq
=ozeK
-----END PGP SIGNATURE-----
a simple commit which works
";

string signatureData = @"-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (Darwin)
iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al
o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8
JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq
AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq
SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW
who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok
6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG
cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu
c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9
ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J
7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc
cpxtDQQMGYFpXK/71stq
=ozeK
-----END PGP SIGNATURE-----";

string signedData = @"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6
parent 34734e478d6cf50c27c9d69026d93974d052c454
author Ben Burkert <[email protected]> 1358451456 -0800
committer Ben Burkert <[email protected]> 1358451456 -0800
a simple commit which works
";

string repoPath = InitNewRepository();
using (var repo = new Repository(repoPath))
{
var odb = repo.ObjectDatabase;
var signedId = odb.Write<Commit>(Encoding.UTF8.GetBytes(commitData));

// Look up the commit to make sure we wrote something valid
var commit = repo.Lookup<Commit>(signedId);
Assert.Equal("a simple commit which works\n", commit.Message);

var signatureInfo = Commit.ExtractSignature(repo, signedId, "gpgsig");
Assert.Equal(signedData, signatureInfo.SignedData);
Assert.Equal(signatureData, signatureInfo.Signature);
}
}
}
}
26 changes: 26 additions & 0 deletions LibGit2Sharp/Commit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,32 @@ private string DebuggerDisplay
}
}

/// <summary>
/// Extract the signature data from this commit
/// </summary>
/// <returns>The signature and the signed data</returns>
/// <param name="repo">The repository in which the object lives</param>
/// <param name="id">The commit to extract the signature from</param>
/// <param name="field">The header field which contains the signature; use null for the default of "gpgsig"</param>
public static SignatureInfo ExtractSignature(Repository repo, ObjectId id, string field)
{
return Proxy.git_commit_extract_signature(repo.Handle, id, field);
}

/// <summary>
/// Extract the signature data from this commit
/// <para>
/// The overload uses the default header field "gpgsig"
/// </para>
/// </summary>
/// <returns>The signature and the signed data</returns>
/// <param name="repo">The repository in which the object lives</param>
/// <param name="id">The commit to extract the signature from</param>
public static SignatureInfo ExtractSignature(Repository repo, ObjectId id)
{
return Proxy.git_commit_extract_signature(repo.Handle, id, null);
}

private class ParentsCollection : ICollection<Commit>
{
private readonly Lazy<ICollection<Commit>> _parents;
Expand Down
8 changes: 8 additions & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ internal static extern unsafe int git_commit_create_from_ids(
[DllImport(libgit2)]
internal static extern unsafe git_oid* git_commit_tree_id(git_object* commit);

[DllImport(libgit2)]
internal static extern unsafe int git_commit_extract_signature(
GitBuf signature,
GitBuf signed_data,
git_repository *repo,
ref GitOid commit_id,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string field);

[DllImport(libgit2)]
internal static extern unsafe int git_config_delete_entry(
git_config* cfg,
Expand Down
16 changes: 16 additions & 0 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,22 @@ public static unsafe ObjectId git_commit_tree_id(ObjectHandle obj)
return ObjectId.BuildFromPtr(NativeMethods.git_commit_tree_id(obj));
}

public static unsafe SignatureInfo git_commit_extract_signature(RepositoryHandle repo, ObjectId id, string field)
{
using (var signature = new GitBuf())
using (var signedData = new GitBuf())
{
var oid = id.Oid;
Ensure.ZeroResult(NativeMethods.git_commit_extract_signature(signature, signedData, repo, ref oid, field));

return new SignatureInfo()
{
Signature = LaxUtf8Marshaler.FromNative(signature.ptr, signature.size.ConvertToInt()),
SignedData = LaxUtf8Marshaler.FromNative(signedData.ptr, signedData.size.ConvertToInt()),
};
}
}

#endregion

#region git_config_
Expand Down
1 change: 1 addition & 0 deletions LibGit2Sharp/LibGit2Sharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@
<Compile Include="Commands\Stage.cs" />
<Compile Include="Commands\Remove.cs" />
<Compile Include="Commands\Checkout.cs" />
<Compile Include="SignatureInfo.cs" />
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="CustomDictionary.xml" />
Expand Down
20 changes: 20 additions & 0 deletions LibGit2Sharp/SignatureInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace LibGit2Sharp
{
/// <summary>
/// Structure for holding a signature extracted from a commit or a tag
/// </summary>
public struct SignatureInfo
{
/// <summary>
/// The signature data, PGP/GPG or otherwise.
/// </summary>
public string Signature;
/// <summary>
/// The data which was signed. The object contents without the signature part.
/// </summary>
public string SignedData;
}
}

0 comments on commit 73aa605

Please sign in to comment.