@@ -48,6 +48,13 @@ internal override IMonoSslStream CreateSslStreamInternal (
48
48
return new UnityTlsStream ( innerStream , leaveInnerStreamOpen , sslStream , settings , this ) ;
49
49
}
50
50
51
+ static UnityTls . unitytls_x509verify_result x509verify_callback ( void * userData , UnityTls . unitytls_x509_ref cert , UnityTls . unitytls_x509verify_result result , UnityTls . unitytls_errorstate * errorState )
52
+ {
53
+ if ( userData != null )
54
+ UnityTls . NativeInterface . unitytls_x509list_append ( ( UnityTls . unitytls_x509list * ) userData , cert , errorState ) ;
55
+ return result ;
56
+ }
57
+
51
58
internal override bool ValidateCertificate (
52
59
ICertificateValidator2 validator , string targetHost , bool serverMode ,
53
60
X509CertificateCollection certificates , bool wantsChain , ref X509Chain chain ,
@@ -85,6 +92,8 @@ internal override bool ValidateCertificate (
85
92
// convert cert to native or extract from unityTlsChainImpl.
86
93
var result = UnityTls . unitytls_x509verify_result . UNITYTLS_X509VERIFY_NOT_DONE ;
87
94
UnityTls . unitytls_x509list * certificatesNative = null ;
95
+ UnityTls . unitytls_x509list * finalCertificateChainNative =
96
+ chain == null ? null : UnityTls . NativeInterface . unitytls_x509list_create ( & errorState ) ;
88
97
try
89
98
{
90
99
// Things the validator provides that we might want to make use of here:
@@ -114,22 +123,36 @@ internal override bool ValidateCertificate (
114
123
var trustCAnativeRef = UnityTls . NativeInterface . unitytls_x509list_get_ref ( trustCAnative , & errorState ) ;
115
124
116
125
fixed ( byte * targetHostUtf8Ptr = targetHostUtf8 ) {
117
- result = UnityTls . NativeInterface . unitytls_x509verify_explicit_ca ( certificatesNativeRef , trustCAnativeRef , targetHostUtf8Ptr , ( size_t ) targetHostUtf8 . Length , null , null , & errorState ) ;
126
+ result = UnityTls . NativeInterface . unitytls_x509verify_explicit_ca (
127
+ certificatesNativeRef , trustCAnativeRef , targetHostUtf8Ptr , ( size_t ) targetHostUtf8 . Length , x509verify_callback , finalCertificateChainNative , & errorState ) ;
118
128
}
119
129
}
120
130
finally {
121
131
UnityTls . NativeInterface . unitytls_x509list_free ( trustCAnative ) ;
122
132
}
123
133
} else {
124
134
fixed ( byte * targetHostUtf8Ptr = targetHostUtf8 ) {
125
- result = UnityTls . NativeInterface . unitytls_x509verify_default_ca ( certificatesNativeRef , targetHostUtf8Ptr , ( size_t ) targetHostUtf8 . Length , null , null , & errorState ) ;
135
+ result = UnityTls . NativeInterface . unitytls_x509verify_default_ca (
136
+ certificatesNativeRef , targetHostUtf8Ptr , ( size_t ) targetHostUtf8 . Length , x509verify_callback , finalCertificateChainNative , & errorState ) ;
126
137
}
127
138
}
128
139
}
140
+ catch {
141
+ UnityTls . NativeInterface . unitytls_x509list_free ( finalCertificateChainNative ) ;
142
+ throw ;
143
+ }
129
144
finally {
130
145
UnityTls . NativeInterface . unitytls_x509list_free ( certificatesNative ) ;
131
146
}
132
147
148
+ if ( finalCertificateChainNative != null ) {
149
+ chain ? . Dispose ( ) ;
150
+ chain = new X509Chain ( new X509ChainImplUnityTls (
151
+ UnityTls . NativeInterface . unitytls_x509list_get_ref ( finalCertificateChainNative , & errorState ) ,
152
+ reverseOrder : true // the verify callback starts with the root and ends with the leaf. That's the opposite of chain ordering.
153
+ ) ) ;
154
+ }
155
+
133
156
errors = UnityTlsConversions . VerifyResultToPolicyErrror ( result ) ;
134
157
// There should be a status per certificate, but once again we're following closely the BTLS implementation
135
158
// https://github.com/mono/mono/blob/1553889bc54f87060158febca7e6b8b9910975f8/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs#L180
0 commit comments