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