8000 Add Commit.ExtractSignature to get signature data from a commit · VRDate/libgit2sharp@73aa605 · GitHub
[go: up one dir, main page]

Skip to content

Commit 73aa605

Browse files
committed
Add Commit.ExtractSignature to get signature data from a commit
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.
1 parent e9f5778 commit 73aa605

File tree

6 files changed

+142
-0
lines changed

6 files changed

+142
-0
lines changed

LibGit2Sharp.Tests/CommitFixture.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Text;
56
using LibGit2Sharp.Core;
67
using LibGit2Sharp.Tests.TestHelpers;
78
using Xunit;
@@ -1055,5 +1056,75 @@ public void CanPrettifyAMessage()
10551056
Assert.Equal(expected, Commit.PrettifyMessage(input, '#'));
10561057
Assert.Equal(expected, Commit.PrettifyMessage(input.Replace('#', ';'), ';'));
10571058
}
1059+
1060+
[Fact]
1061+
public void CanExtractSignatureFromCommit()
1062+
{
1063+
string commitData = @"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6
1064+
parent 34734e478d6cf50c27c9d69026d93974d052c454
1065+
author Ben Burkert <ben@benburkert.com> 1358451456 -0800
1066+
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800
1067+
gpgsig -----BEGIN PGP SIGNATURE-----
1068+
Version: GnuPG v1.4.12 (Darwin)
1069+
1070+
iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al
1071+
o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8
1072+
JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq
1073+
AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq
1074+
SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW
1075+
who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok
1076+
6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG
1077+
cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu
1078+
c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9
1079+
ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J
1080+
7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc
1081+
cpxtDQQMGYFpXK/71stq
1082+
=ozeK
1083+
-----END PGP SIGNATURE-----
1084+
1085+
a simple commit which works
1086+
";
1087+
1088+
string signatureData = @"-----BEGIN PGP SIGNATURE-----
1089+
Version: GnuPG v1.4.12 (Darwin)
1090+
1091+
iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al
1092+
o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8
1093+
JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq
1094+
AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq
1095+
SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW
1096+
who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok
1097+
6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG
1098+
cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu
1099+
c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9
1100+
ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J
1101+
7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc
1102+
cpxtDQQMGYFpXK/71stq
1103+
=ozeK
1104+
-----END PGP SIGNATURE-----";
1105+
1106+
string signedData = @"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6
1107+
parent 34734e478d6cf50c27c9d69026d93974d052c454
1108+
author Ben Burkert <ben@benburkert.com> 1358451456 -0800
1109+
committer Ben Burkert <ben@benburkert.com> 1358451456 -0800
1110+
1111+
a simple commit which works
1112+
";
1113+
1114+
string repoPath = InitNewRepository();
1115+
using (var repo = new Repository(repoPath))
1116+
{
1117+
var odb = repo.ObjectDatabase;
1118+
var signedId = odb.Write<Commit>(Encoding.UTF8.GetBytes(commitData));
1119+
1120+
// Look up the commit to make sure we wrote something valid
1121+
var commit = repo.Lookup<Commit>(signedId);
1122+
Assert.Equal("a simple commit which works\n", commit.Message);
1123+
1124+
var signatureInfo = Commit.ExtractSignature(repo, signedId, "gpgsig");
1125+
Assert.Equal(signedData, signatureInfo.SignedData);
1126+
Assert.Equal(signatureData, signatureInfo.Signature);
1127+
}
1128+
}
10581129
}
10591130
}

LibGit2Sharp/Commit.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,32 @@ private string DebuggerDisplay
138138
}
139139
}
140140

141+
/// <summary>
142+
/// Extract the signature data from this commit
143+
/// </summary>
144+
/// <returns>The signature and the signed data</returns>
145+
/// <param name="repo">The repository in which the object lives</param>
146+
/// <param name="id">The commit to extract the signature from</param>
147+
/// <param name="field">The header field which contains the signature; use null for the default of "gpgsig"</param>
148+
public static SignatureInfo ExtractSignature(Repository repo, ObjectId id, string field)
149+
{
150+
return Proxy.git_commit_extract_signature(repo.Handle, id, field);
151+
}
152+
153+
/// <summary>
154+
/// Extract the signature data from this commit
155+
/// <para>
156+
/// The overload uses the default header field "gpgsig"
157+
/// </para>
158+
/// </summary>
159+
/// <returns>The signature and the signed data</returns>
160+
/// <param name="repo">The repository in which the object lives</param>
161+
/// <param name="id">The commit to extract the signature from</param>
162+
public static SignatureInfo ExtractSignature(Repository repo, ObjectId id)
163+
{
164+
return Proxy.git_commit_extract_signature(repo.Handle, id, null);
165+
}
166+
141167
private class ParentsCollection : ICollection<Commit>
142168
{
143169
private readonly Lazy<ICollection<Commit>> _parents;

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,14 @@ internal static extern unsafe int git_commit_create_from_ids(
337337
[DllImport(libgit2)]
338338
internal static extern unsafe git_oid* git_commit_tree_id(git_object* commit);
339339

340+
[DllImport(libgit2)]
341+
internal static extern unsafe int git_commit_extract_signature(
342+
GitBuf signature,
343+
GitBuf signed_data,
344+
git_repository *repo,
345+
ref GitOid commit_id,
346+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string field);
347+
340348
[DllImport(libgit2)]
341349
internal static extern unsafe int git_config_delete_entry(
342350
git_config* cfg,

LibGit2Sharp/Core/Proxy.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,22 @@ public static unsafe ObjectId git_commit_tree_id(ObjectHandle obj)
426426
return ObjectId.BuildFromPtr(NativeMethods.git_commit_tree_id(obj));
427427
}
428428

429+
public static unsafe SignatureInfo git_commit_extract_signature(RepositoryHandle repo, ObjectId id, string field)
430+
{
431+
using (var signature = new GitBuf())
432+
using (var signedData = new GitBuf())
433+
{
434+
var oid = id.Oid;
435+
Ensure.ZeroResult(NativeMethods.git_commit_extract_signature(signature, signedData, repo, ref oid, field));
436+
437+
return new SignatureInfo()
438+
{
439+
Signature = LaxUtf8Marshaler.FromNative(signature.ptr, signature.size.ConvertToInt()),
440+
SignedData = LaxUtf8Marshaler.FromNative(signedData.ptr, signedData.size.ConvertToInt()),
441+
};
442+
}
443+
}
444+
429445
#endregion
430446

431447
#region git_config_

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@
355355
<Compile Include="Commands\Stage.cs" />
356356
<Compile Include="Commands\Remove.cs" />
357357
<Compile Include="Commands\Checkout.cs" />
358+
<Compile Include="SignatureInfo.cs" />
358359
</ItemGroup>
359360
<ItemGroup>
360361
<CodeAnalysisDictionary Include="CustomDictionary.xml" />

LibGit2Sharp/SignatureInfo.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
3+
namespace LibGit2Sharp
4+
{
5+
/// <summary>
6+
/// Structure for holding a signature extracted from a commit or a tag
7+
/// </summary>
8+
public struct SignatureInfo
9+
{
10+
/// <summary>
11+
/// The signature data, PGP/GPG or otherwise.
12+
/// </summary>
13+
public string Signature;
14+
/// <summary>
15+
/// The data which was signed. The object contents without the signature part.
16+
/// </summary>
17+
public string SignedData;
18+
}
19+
}
20+

0 commit comments

Comments
 (0)
0