-
Notifications
You must be signed in to change notification settings - Fork 886
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1134 from libgit2/cmn/certs
Certificate validation callback
- Loading branch information
Showing
16 changed files
with
323 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -237,6 237,66 @@ public void CanCloneFromBBWithCredentials(string url, string user, string pass, | |
} | ||
} | ||
|
||
[SkippableTheory] | ||
[InlineData("https://github.com/libgit2/TestGitRepository.git", "github.com", typeof(CertificateX509))] | ||
[InlineData("[email protected]:libgit2/TestGitRepository.git", "github.com", typeof(CertificateSsh))] | ||
public void CanInspectCertificateOnClone(string url, string hostname, Type certType) | ||
{ | ||
var scd = BuildSelfCleaningDirectory(); | ||
|
||
InconclusiveIf( | ||
() => | ||
certType == typeof (CertificateSsh) && !GlobalSettings.Version.Features.HasFlag(BuiltInFeatures.Ssh), | ||
"SSH not supported"); | ||
|
||
bool wasCalled = false; | ||
bool checksHappy = false; | ||
|
||
var options = new CloneOptions { | ||
CertificateCheck = (cert, valid, host) => { | ||
wasCalled = true; | ||
Assert.Equal(hostname, host); | ||
Assert.Equal(certType, cert.GetType()); | ||
if (certType == typeof(CertificateX509)) { | ||
Assert.True(valid); | ||
var x509 = ((CertificateX509)cert).Certificate; | ||
// we get a string with the different fields instead of a structure, so... | ||
Assert.True(x509.Subject.Contains("CN=github.com,")); | ||
checksHappy = true; | ||
return false; | ||
} | ||
if (certType == typeof(CertificateSsh)) { | ||
var hostkey = (CertificateSsh)cert; | ||
Assert.True(hostkey.HasMD5); | ||
/* | ||
* Once you've connected and thus your ssh has stored the hostkey, | ||
* you can get the hostkey for a host with | ||
* | ||
* ssh-keygen -F github.com -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':' | ||
* | ||
* though GitHub's hostkey won't change anytime soon. | ||
*/ | ||
Assert.Equal("1627aca576282d36631b564debdfa648", | ||
BitConverter.ToString(hostkey.HashMD5).ToLower().Replace("-", "")); | ||
checksHappy = true; | ||
return false; | ||
} | ||
return false; | ||
}, | ||
}; | ||
|
||
Assert.Throws<UserCancelledException>(() => | ||
Repository.Clone(url, scd.DirectoryPath, options) | ||
); | ||
|
||
Assert.True(wasCalled); | ||
Assert.True(checksHappy); | ||
} | ||
|
||
[Fact] | ||
public void CloningAnUrlWithoutPathThrows() | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,9 @@ | ||
namespace LibGit2Sharp | ||
{ | ||
/// <summary> | ||
/// Top-level certificate type. The usable certificates inherit from this class. | ||
/// </summary> | ||
public abstract class Certificate | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,53 @@ | ||
using LibGit2Sharp.Core; | ||
|
||
namespace LibGit2Sharp | ||
{ | ||
/// <summary> | ||
/// This class represents the hostkey which is avaiable when connecting to a SSH host. | ||
/// </summary> | ||
public class CertificateSsh : Certificate | ||
{ | ||
/// <summary> | ||
/// For mocking purposes | ||
/// </summary> | ||
protected CertificateSsh() | ||
{ } | ||
|
||
/// <summary> | ||
/// The MD5 hash of the host. Meaningful if <see cref="HasMD5"/> is true | ||
/// </summary> | ||
public readonly byte[] HashMD5; | ||
|
||
/// <summary> | ||
/// The SHA1 hash of the host. Meaningful if <see cref="HasSHA1"/> is true | ||
/// </summary> | ||
public readonly byte[] HashSHA1; | ||
|
||
/// <summary> | ||
/// True if we have the MD5 hostkey hash from the server | ||
/// </summary> | ||
public readonly bool HasMD5; | ||
|
||
/// <summary> | ||
/// True if we have the SHA1 hostkey hash from the server | ||
/// </summary> | ||
public readonly bool HasSHA1; | ||
|
||
/// <summary> | ||
/// True if we have the SHA1 hostkey hash from the server | ||
/// </summary>public readonly bool HasSHA1; | ||
|
||
internal CertificateSsh(GitCertificateSsh cert) | ||
{ | ||
|
||
HasMD5 = cert.type.HasFlag(GitCertificateSshType.MD5); | ||
HasSHA1 = cert.type.HasFlag(GitCertificateSshType.SHA1); | ||
|
||
HashMD5 = new byte[16]; | ||
cert.HashMD5.CopyTo(HashMD5, 0); | ||
|
||
HashSHA1 = new byte[20]; | ||
cert.HashSHA1.CopyTo(HashSHA1, 0); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,32 @@ | ||
using System.Runtime.InteropServices; | ||
using System.Security.Cryptography.X509Certificates; | ||
using LibGit2Sharp.Core; | ||
|
||
namespace LibGit2Sharp | ||
{ | ||
/// <summary> | ||
/// Conains a X509 certificate | ||
/// </summary> | ||
public class CertificateX509 : Certificate | ||
{ | ||
|
||
/// <summary> | ||
/// For mocking purposes | ||
/// </summary> | ||
protected CertificateX509() | ||
{ } | ||
|
||
/// <summary> | ||
/// The certificate. | ||
/// </summary> | ||
public virtual X509Certificate Certificate { get; private set; } | ||
|
||
internal CertificateX509(GitCertificateX509 cert) | ||
{ | ||
int len = checked((int) cert.len.ToUInt32()); | ||
byte[] data = new byte[len]; | ||
Marshal.Copy(cert.data, data, 0, len); | ||
Certificate = new X509Certificate(data); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,10 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
namespace LibGit2Sharp.Core | ||
{ | ||
[StructLayout(LayoutKind.Sequential)] | ||
internal struct GitCertificate | ||
{ | ||
public GitCertificateType type; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,23 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
namespace LibGit2Sharp.Core | ||
{ | ||
[StructLayout(LayoutKind.Sequential)] | ||
internal struct GitCertificateSsh | ||
{ | ||
public GitCertificateType cert_type; | ||
public GitCertificateSshType type; | ||
|
||
/// <summary> | ||
/// The MD5 hash (if appropriate) | ||
/// </summary> | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] | ||
public byte[] HashMD5; | ||
|
||
/// <summary> | ||
/// The MD5 hash (if appropriate) | ||
/// </summary> | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] | ||
public byte[] HashSHA1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,11 @@ | ||
using System; | ||
|
||
namespace LibGit2Sharp.Core | ||
{ | ||
[Flags] | ||
internal enum GitCertificateSshType | ||
{ | ||
MD5 = (1 << 0), | ||
SHA1 = (1 << 1), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,29 @@ | ||
namespace LibGit2Sharp.Core | ||
{ | ||
/// <summary> | ||
/// Git certificate types to present to the user | ||
/// </summary> | ||
internal enum GitCertificateType | ||
{ | ||
/// <summary> | ||
/// No information about the certificate is available. | ||
/// </summary> | ||
None = 0, | ||
|
||
/// <summary> | ||
/// The certificate is a x509 certificate | ||
/// </summary> | ||
X509 = 1, | ||
|
||
/// <summary> | ||
/// The "certificate" is in fact a hostkey identification for ssh. | ||
/// </summary> | ||
Hostkey = 2, | ||
|
||
/// <summary> | ||
/// The "certificate" is in fact a collection of `name:content` strings | ||
/// containing information about the certificate. | ||
/// </summary> | ||
StrArray = 3, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,22 @@ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace LibGit2Sharp.Core | ||
{ | ||
[StructLayout(LayoutKind.Sequential)] | ||
internal struct GitCertificateX509 | ||
{ | ||
/// <summary> | ||
/// Type of the certificate, in this case, GitCertificateType.X509 | ||
/// </summary> | ||
public GitCertificateType cert_type; | ||
/// <summary> | ||
/// Pointer to the X509 certificate data | ||
/// </summary> | ||
public IntPtr data; | ||
/// <summary> | ||
/// The size of the certificate data | ||
/// </summary> | ||
public UIntPtr len; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.