forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCertificateValidationPal.OSX.cs
More file actions
133 lines (110 loc) · 4.78 KB
/
CertificateValidationPal.OSX.cs
File metadata and controls
133 lines (110 loc) · 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Win32.SafeHandles;
namespace System.Net
{
internal static partial class CertificateValidationPal
{
internal static SslPolicyErrors VerifyCertificateProperties(
SafeDeleteContext? _ /*securityContext*/,
X509Chain chain,
X509Certificate2 remoteCertificate,
bool checkCertName,
bool isServer,
string? hostName)
{
return CertificateValidation.BuildChainAndVerifyProperties(chain, remoteCertificate, checkCertName, isServer, hostName, Span<byte>.Empty);
}
private static X509Certificate2? GetRemoteCertificate(
SafeDeleteContext? securityContext,
bool retrieveChainCertificates,
ref X509Chain? chain,
X509ChainPolicy? chainPolicy)
{
if (securityContext == null)
{
return null;
}
SafeSslHandle sslContext = ((SafeDeleteSslContext)securityContext).SslContext;
if (sslContext == null)
{
return null;
}
X509Certificate2? result = null;
using (SafeX509ChainHandle chainHandle = Interop.AppleCrypto.SslCopyCertChain(sslContext))
{
long chainSize = Interop.AppleCrypto.X509ChainGetChainSize(chainHandle);
if (retrieveChainCertificates && chainSize > 1)
{
chain ??= new X509Chain();
if (chainPolicy != null)
{
chain.ChainPolicy = chainPolicy;
}
// First certificate is peer's certificate.
// Any any additional intermediate CAs to ExtraStore.
for (int i = 1; i < chainSize; i++)
{
IntPtr certHandle = Interop.AppleCrypto.X509ChainGetCertificateAtIndex(chainHandle, i);
chain.ChainPolicy.ExtraStore.Add(new X509Certificate2(certHandle));
}
}
// This will be a distinct object than remoteCertificateStore[0] (if applicable),
// to match what the Windows and Unix PALs do.
if (chainSize > 0)
{
IntPtr certHandle = Interop.AppleCrypto.X509ChainGetCertificateAtIndex(chainHandle, 0);
result = new X509Certificate2(certHandle);
}
}
if (NetEventSource.Log.IsEnabled()) NetEventSource.Log.RemoteCertificate(result);
return result;
}
// This is only called when we selected local client certificate.
// Currently this is only when Apple crypto asked for it.
internal static bool IsLocalCertificateUsed(SafeFreeCredentials? _1, SafeDeleteContext? _2) => true;
//
// Used only by client SSL code, never returns null.
//
internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
{
SafeSslHandle sslContext = ((SafeDeleteSslContext)securityContext).SslContext;
if (sslContext == null)
{
return Array.Empty<string>();
}
using (SafeCFArrayHandle dnArray = Interop.AppleCrypto.SslCopyCADistinguishedNames(sslContext))
{
if (dnArray.IsInvalid)
{
return Array.Empty<string>();
}
long size = Interop.CoreFoundation.CFArrayGetCount(dnArray);
if (size == 0)
{
return Array.Empty<string>();
}
string[] distinguishedNames = new string[size];
for (int i = 0; i < size; i++)
{
IntPtr element = Interop.CoreFoundation.CFArrayGetValueAtIndex(dnArray, i);
using (SafeCFDataHandle cfData = new SafeCFDataHandle(element, ownsHandle: false))
{
byte[] dnData = Interop.CoreFoundation.CFGetData(cfData);
X500DistinguishedName dn = new X500DistinguishedName(dnData);
distinguishedNames[i] = dn.Name;
}
}
return distinguishedNames;
}
}
private static X509Store OpenStore(StoreLocation storeLocation)
{
X509Store store = new X509Store(StoreName.My, storeLocation);
store.Open(OpenFlags.ReadOnly);
return store;
}
}
}