Imported Upstream version 5.10.0.69

Former-commit-id: fc39669a0b707dd3c063977486506b6793da2890
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-01-29 19:03:06 +00:00
parent d8f8abd549
commit e2950ec768
6283 changed files with 453847 additions and 91879 deletions

View File

@@ -9,13 +9,11 @@ namespace Microsoft.Win32.SafeHandles
{
public sealed partial class SafeX509ChainHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
{
internal SafeX509ChainHandle() : base(default(bool)) { }
public override bool IsInvalid { get { throw null; } }
internal SafeX509ChainHandle() : base (default(bool)) { }
protected override void Dispose(bool disposing) { }
protected override bool ReleaseHandle() { throw null; }
}
}
namespace System.Security.Cryptography.X509Certificates
{
public sealed partial class CertificateRequest
@@ -131,7 +129,7 @@ namespace System.Security.Cryptography.X509Certificates
public int PathLengthConstraint { get { throw null; } }
public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { }
}
public partial class X509Certificate : System.IDisposable, System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback
public partial class X509Certificate : System.IDisposable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
{
public X509Certificate() { }
public X509Certificate(byte[] data) { }
@@ -166,7 +164,9 @@ namespace System.Security.Cryptography.X509Certificates
public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string password) { throw null; }
protected static string FormatDate(System.DateTime date) { throw null; }
public virtual byte[] GetCertHash() { throw null; }
public virtual byte[] GetCertHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual string GetCertHashString() { throw null; }
public virtual string GetCertHashString(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual string GetEffectiveDateString() { throw null; }
public virtual string GetExpirationDateString() { throw null; }
public virtual string GetFormat() { throw null; }
@@ -197,6 +197,7 @@ namespace System.Security.Cryptography.X509Certificates
void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
public override string ToString() { throw null; }
public virtual string ToString(bool fVerbose) { throw null; }
public virtual bool TryGetCertHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Span<byte> destination, out int bytesWritten) { throw null; }
}
public partial class X509Certificate2 : System.Security.Cryptography.X509Certificates.X509Certificate
{
@@ -253,12 +254,12 @@ namespace System.Security.Cryptography.X509Certificates
{
public X509Certificate2Collection() { }
public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { }
public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { }
public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { }
public new System.Security.Cryptography.X509Certificates.X509Certificate2 this[int index] { get { throw null; } set { } }
public int Add(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { }
public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { }
public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { }
public bool Contains(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
public byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType) { throw null; }
public byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string password) { throw null; }
@@ -270,8 +271,8 @@ namespace System.Security.Cryptography.X509Certificates
public void Import(string fileName, string password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { }
public void Insert(int index, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { }
public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { }
public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { }
}
public sealed partial class X509Certificate2Enumerator : System.Collections.IEnumerator
{
@@ -286,18 +287,19 @@ namespace System.Security.Cryptography.X509Certificates
public partial class X509CertificateCollection : System.Collections.CollectionBase
{
public X509CertificateCollection() { }
public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { }
public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509CertificateCollection value) { }
public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { }
public System.Security.Cryptography.X509Certificates.X509Certificate this[int index] { get { throw null; } set { } }
public int Add(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; }
public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { }
public void AddRange(System.Security.Cryptography.X509Certificates.X509CertificateCollection value) { }
public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { }
public bool Contains(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; }
public void CopyTo(System.Security.Cryptography.X509Certificates.X509Certificate[] array, int index) { }
public new System.Security.Cryptography.X509Certificates.X509CertificateCollection.X509CertificateEnumerator GetEnumerator() { throw null; }
public override int GetHashCode() { throw null; }
public int IndexOf(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; }
public void Insert(int index, System.Security.Cryptography.X509Certificates.X509Certificate value) { }
protected override void OnValidate(object value) { }
public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate value) { }
public partial class X509CertificateEnumerator : System.Collections.IEnumerator
{
@@ -315,13 +317,13 @@ namespace System.Security.Cryptography.X509Certificates
public X509Chain() { }
public X509Chain(bool useMachineContext) { }
public X509Chain(System.IntPtr chainContext) { }
public static X509Chain Create() { throw null; }
public System.IntPtr ChainContext { get { throw null; } }
public System.Security.Cryptography.X509Certificates.X509ChainElementCollection ChainElements { get { throw null; } }
public System.Security.Cryptography.X509Certificates.X509ChainPolicy ChainPolicy { get { throw null; } set { } }
public System.Security.Cryptography.X509Certificates.X509ChainStatus[] ChainStatus { get { throw null; } }
public Microsoft.Win32.SafeHandles.SafeX509ChainHandle SafeHandle { get { throw null; } }
public bool Build(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
public static System.Security.Cryptography.X509Certificates.X509Chain Create() { throw null; }
public void Dispose() { }
protected virtual void Dispose(bool disposing) { }
public void Reset() { }
@@ -366,9 +368,9 @@ namespace System.Security.Cryptography.X509Certificates
public System.DateTime VerificationTime { get { throw null; } set { } }
public void Reset() { }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct X509ChainStatus
{
private object _dummy;
public System.Security.Cryptography.X509Certificates.X509ChainStatusFlags Status { get { throw null; } set { } }
public string StatusInformation { get { throw null; } set { } }
}

View File

@@ -459,7 +459,7 @@ namespace Internal.Cryptography.Pal
return new X509ChainElement(cert, statuses.ToArray(), "");
}
private struct X509ChainErrorMapping
private readonly struct X509ChainErrorMapping
{
internal static readonly X509ChainErrorMapping[] s_chainErrorMappings =
{

View File

@@ -117,13 +117,15 @@ namespace Internal.Cryptography.Pal
}
privateCert = cert;
var certPal = (OpenSslX509CertificateReader)cert.Pal;
privateCertHandle = certPal.SafeHandle;
privateCertKeyHandle = certPal.PrivateKeyHandle;
}
else
{
PushHandle(cert.Handle, publicCerts);
}
GC.KeepAlive(cert); // ensure cert's safe handle isn't finalized while raw handle is in use
}
}
@@ -138,11 +140,17 @@ namespace Internal.Cryptography.Pal
throw Interop.Crypto.CreateOpenSslCryptographicException();
}
return Interop.Crypto.OpenSslEncode(
byte[] result = Interop.Crypto.OpenSslEncode(
Interop.Crypto.GetPkcs12DerSize,
Interop.Crypto.EncodePkcs12,
pkcs12);
// ensure cert handles aren't finalized while the raw handles are in use
GC.KeepAlive(_certs);
return result;
}
}
}

View File

@@ -77,7 +77,7 @@ namespace Internal.Cryptography.Pal
return SR.Unknown_Error;
}
private struct X509ChainErrorMapping
private readonly struct X509ChainErrorMapping
{
public readonly CertTrustErrorStatus Win32Flag;
public readonly int Win32ErrorCode;

View File

@@ -412,6 +412,7 @@
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tools" />
<Reference Include="System.IO.FileSystem" />
<Reference Include="System.Memory" />
<Reference Include="System.Net.Primitives" />
<Reference Include="System.Resources.ResourceManager" />
<Reference Include="System.Runtime" />

View File

@@ -317,12 +317,44 @@ namespace System.Security.Cryptography.X509Certificates
return GetRawCertHash().CloneByteArray();
}
public virtual byte[] GetCertHash(HashAlgorithmName hashAlgorithm)
{
ThrowIfInvalid();
using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm))
{
hasher.AppendData(Pal.RawData);
return hasher.GetHashAndReset();
}
}
public virtual bool TryGetCertHash(
HashAlgorithmName hashAlgorithm,
Span<byte> destination,
out int bytesWritten)
{
ThrowIfInvalid();
using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm))
{
hasher.AppendData(Pal.RawData);
return hasher.TryGetHashAndReset(destination, out bytesWritten);
}
}
public virtual string GetCertHashString()
{
ThrowIfInvalid();
return GetRawCertHash().ToHexStringUpper();
}
public virtual string GetCertHashString(HashAlgorithmName hashAlgorithm)
{
ThrowIfInvalid();
return GetCertHash(hashAlgorithm).ToHexStringUpper();
}
// Only use for internal purposes when the returned byte[] will not be mutated
private byte[] GetRawCertHash()
{

View File

@@ -289,6 +289,9 @@ namespace System.Security.Cryptography.X509Certificates.Tests
// State held on X509Certificate
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHash());
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHash(HashAlgorithmName.SHA256));
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHashString());
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHashString(HashAlgorithmName.SHA256));
Assert.ThrowsAny<CryptographicException>(() => c.GetKeyAlgorithm());
Assert.ThrowsAny<CryptographicException>(() => c.GetKeyAlgorithmParameters());
Assert.ThrowsAny<CryptographicException>(() => c.GetKeyAlgorithmParametersString());
@@ -299,6 +302,9 @@ namespace System.Security.Cryptography.X509Certificates.Tests
Assert.ThrowsAny<CryptographicException>(() => c.NotBefore);
Assert.ThrowsAny<CryptographicException>(() => c.NotAfter);
Assert.ThrowsAny<CryptographicException>(
() => c.TryGetCertHash(HashAlgorithmName.SHA256, Array.Empty<byte>(), out _));
// State held on X509Certificate2
Assert.ThrowsAny<CryptographicException>(() => c.RawData);
Assert.ThrowsAny<CryptographicException>(() => c.SignatureAlgorithm);

View File

@@ -863,6 +863,33 @@ namespace System.Security.Cryptography.X509Certificates.Tests
}
}
[Fact]
[ActiveIssue(26397, TestPlatforms.OSX)]
public static void CanAddMultipleCertsWithSinglePrivateKey()
{
using (var oneWithKey = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword, X509KeyStorageFlags.Exportable | Cert.EphemeralIfPossible))
using (var twoWithoutKey = new X509Certificate2(TestData.ComplexNameInfoCert))
{
Assert.True(oneWithKey.HasPrivateKey);
var col = new X509Certificate2Collection
{
oneWithKey,
twoWithoutKey,
};
Assert.Equal(1, col.Cast<X509Certificate2>().Count(x => x.HasPrivateKey));
Assert.Equal(2, col.Count);
byte[] buffer = col.Export(X509ContentType.Pfx);
using (ImportedCollection newCollection = Cert.Import(buffer))
{
Assert.Equal(2, newCollection.Collection.Count);
}
}
}
[Fact]
public static void X509CertificateCollectionCopyTo()
{

View File

@@ -25,6 +25,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
object ignored;
Assert.Equal(IntPtr.Zero, h);
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHash());
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHash(HashAlgorithmName.SHA256));
Assert.ThrowsAny<CryptographicException>(() => c.GetKeyAlgorithm());
Assert.ThrowsAny<CryptographicException>(() => c.GetKeyAlgorithmParameters());
Assert.ThrowsAny<CryptographicException>(() => c.GetKeyAlgorithmParametersString());
@@ -43,6 +44,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
Assert.ThrowsAny<CryptographicException>(() => ignored = c.SubjectName);
Assert.ThrowsAny<CryptographicException>(() => ignored = c.IssuerName);
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHashString());
Assert.ThrowsAny<CryptographicException>(() => c.GetCertHashString(HashAlgorithmName.SHA256));
Assert.ThrowsAny<CryptographicException>(() => c.GetEffectiveDateString());
Assert.ThrowsAny<CryptographicException>(() => c.GetExpirationDateString());
Assert.ThrowsAny<CryptographicException>(() => c.GetPublicKeyString());
@@ -53,12 +55,15 @@ namespace System.Security.Cryptography.X509Certificates.Tests
Assert.ThrowsAny<CryptographicException>(() => c.GetIssuerName());
Assert.ThrowsAny<CryptographicException>(() => c.GetName());
#pragma warning restore 0618
Assert.ThrowsAny<CryptographicException>(
() => c.TryGetCertHash(HashAlgorithmName.SHA256, Array.Empty<byte>(), out _));
}
[Fact]
public static void TestConstructor_DER()
{
byte[] expectedThumbPrint = new byte[]
byte[] expectedThumbPrintSha1 =
{
0x10, 0x8e, 0x2b, 0xa2, 0x36, 0x32, 0x62, 0x0c,
0x42, 0x7c, 0x57, 0x0b, 0x6d, 0x9d, 0xb5, 0x1a,
@@ -70,7 +75,10 @@ namespace System.Security.Cryptography.X509Certificates.Tests
IntPtr h = c.Handle;
Assert.NotEqual(IntPtr.Zero, h);
byte[] actualThumbprint = c.GetCertHash();
Assert.Equal(expectedThumbPrint, actualThumbprint);
Assert.Equal(expectedThumbPrintSha1, actualThumbprint);
byte[] specifiedAlgThumbprint = c.GetCertHash(HashAlgorithmName.SHA1);
Assert.Equal(expectedThumbPrintSha1, specifiedAlgThumbprint);
};
using (X509Certificate2 c = new X509Certificate2(TestData.MsCertificate))
@@ -86,7 +94,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
[Fact]
public static void TestConstructor_PEM()
{
byte[] expectedThumbPrint =
byte[] expectedThumbPrintSha1 =
{
0x10, 0x8e, 0x2b, 0xa2, 0x36, 0x32, 0x62, 0x0c,
0x42, 0x7c, 0x57, 0x0b, 0x6d, 0x9d, 0xb5, 0x1a,
@@ -98,7 +106,10 @@ namespace System.Security.Cryptography.X509Certificates.Tests
IntPtr h = cert.Handle;
Assert.NotEqual(IntPtr.Zero, h);
byte[] actualThumbprint = cert.GetCertHash();
Assert.Equal(expectedThumbPrint, actualThumbprint);
Assert.Equal(expectedThumbPrintSha1, actualThumbprint);
byte[] specifiedAlgThumbprint = cert.GetCertHash(HashAlgorithmName.SHA1);
Assert.Equal(expectedThumbPrintSha1, specifiedAlgThumbprint);
};
using (X509Certificate2 c = new X509Certificate2(TestData.MsCertificatePemBytes))
@@ -168,6 +179,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
using (var c2 = new X509Certificate2(c1))
{
Assert.Equal(c1.GetCertHash(), c2.GetCertHash());
Assert.Equal(c1.GetCertHash(HashAlgorithmName.SHA256), c2.GetCertHash(HashAlgorithmName.SHA256));
Assert.Equal(c1.GetKeyAlgorithm(), c2.GetKeyAlgorithm());
Assert.Equal(c1.GetKeyAlgorithmParameters(), c2.GetKeyAlgorithmParameters());
Assert.Equal(c1.GetKeyAlgorithmParametersString(), c2.GetKeyAlgorithmParametersString());
@@ -184,6 +196,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests
Assert.Equal(c1.SubjectName.Name, c2.SubjectName.Name);
Assert.Equal(c1.IssuerName.Name, c2.IssuerName.Name);
Assert.Equal(c1.GetCertHashString(), c2.GetCertHashString());
Assert.Equal(c1.GetCertHashString(HashAlgorithmName.SHA256), c2.GetCertHashString(HashAlgorithmName.SHA256));
Assert.Equal(c1.GetEffectiveDateString(), c2.GetEffectiveDateString());
Assert.Equal(c1.GetExpirationDateString(), c2.GetExpirationDateString());
Assert.Equal(c1.GetPublicKeyString(), c2.GetPublicKeyString());

View File

@@ -66,6 +66,89 @@ namespace System.Security.Cryptography.X509Certificates.Tests
}
}
[Theory]
[InlineData("SHA1", false)]
[InlineData("SHA1", true)]
[InlineData("SHA256", false)]
[InlineData("SHA256", true)]
[InlineData("SHA384", false)]
[InlineData("SHA384", true)]
[InlineData("SHA512", false)]
[InlineData("SHA512", true)]
public static void TestThumbprint(string hashAlgName, bool viaSpan)
{
string expectedThumbprintHex;
switch (hashAlgName)
{
case "SHA1":
expectedThumbprintHex =
"108E2BA23632620C427C570B6D9DB51AC31387FE";
break;
case "SHA256":
expectedThumbprintHex =
"73FCF982974387FB164C91D0168FE8C3B957DE6526AE239AAD32825C5A63D2A4";
break;
case "SHA384":
expectedThumbprintHex =
"E6DCEF0840DAB43E1DBE9BE23142182BD05106AB25F7043BDE6A551928DFB4C7082791B86A5FB5E77B0F43DD92B7A3E5";
break;
case "SHA512":
expectedThumbprintHex =
"8435635A12915A1A9C28BC2BCE7C3CAD08EB723FE276F13CD37D1C3B21416994" +
"0661A27B419882DBA643B23A557CA9EBC03ACC3D7EE3D4D591AB4BA0E553B945";
break;
default:
throw new ArgumentOutOfRangeException(nameof(hashAlgName));
}
HashAlgorithmName alg = new HashAlgorithmName(hashAlgName);
using (X509Certificate2 c = LoadCertificateFromFile())
{
if (viaSpan)
{
const int WriteOffset = 3;
const byte FillByte = 0x55;
int expectedSize = expectedThumbprintHex.Length / 2;
byte[] thumbPrint = new byte[expectedSize + 10];
thumbPrint.AsSpan().Fill(FillByte);
Span<byte> writeDest = thumbPrint.AsSpan().Slice(WriteOffset);
int bytesWritten;
// Too small.
Assert.False(c.TryGetCertHash(alg, writeDest.Slice(0, expectedSize - 1), out bytesWritten));
Assert.Equal(0, bytesWritten);
// Still all 0x55s.
Assert.Equal(new string('5', thumbPrint.Length * 2), thumbPrint.ByteArrayToHex());
// Large enough (+7)
Assert.True(c.TryGetCertHash(alg, writeDest, out bytesWritten));
Assert.Equal(expectedSize, bytesWritten);
Assert.Equal(expectedThumbprintHex, writeDest.Slice(0, bytesWritten).ByteArrayToHex());
Assert.Equal(FillByte, thumbPrint[expectedSize + WriteOffset]);
// Try again with a perfectly sized value
thumbPrint.AsSpan().Fill(FillByte);
Assert.True(c.TryGetCertHash(alg, writeDest.Slice(0, expectedSize), out bytesWritten));
Assert.Equal(expectedSize, bytesWritten);
Assert.Equal(expectedThumbprintHex, writeDest.Slice(0, bytesWritten).ByteArrayToHex());
Assert.Equal(FillByte, thumbPrint[expectedSize + WriteOffset]);
}
else
{
byte[] thumbPrint = c.GetCertHash(alg);
Assert.Equal(expectedThumbprintHex, thumbPrint.ByteArrayToHex());
string thumbPrintHex = c.GetCertHashString(alg);
Assert.Equal(expectedThumbprintHex, thumbPrintHex);
}
}
}
[Fact]
public static void TestGetFormat()
{

View File

@@ -94,4 +94,4 @@
<SupplementalTestData Include="$(PackagesDir)system.security.cryptography.x509certificates.testdata\1.0.2-prerelease\content\**\*.*" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
</Project>