@@ -48,6 +48,13 @@ internal override IMonoSslStream CreateSslStreamInternal (
4848 return new UnityTlsStream ( innerStream , leaveInnerStreamOpen , sslStream , settings , this ) ;
4949 }
5050
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+
5158 internal override bool ValidateCertificate (
5259 ICertificateValidator2 validator , string targetHost , bool serverMode ,
5360 X509CertificateCollection certificates , bool wantsChain , ref X509Chain chain ,
@@ -85,6 +92,8 @@ internal override bool ValidateCertificate (
8592 // convert cert to native or extract from unityTlsChainImpl.
8693 var result = UnityTls . unitytls_x509verify_result . UNITYTLS_X509VERIFY_NOT_DONE ;
8794 UnityTls . unitytls_x509list * certificatesNative = null ;
95+ UnityTls . unitytls_x509list * finalCertificateChainNative =
96+ chain == null ? null : UnityTls . NativeInterface . unitytls_x509list_create ( & errorState ) ;
8897 try
8998 {
9099 // Things the validator provides that we might want to make use of here:
@@ -114,22 +123,36 @@ internal override bool ValidateCertificate (
114123 var trustCAnativeRef = UnityTls . NativeInterface . unitytls_x509list_get_ref ( trustCAnative , & errorState ) ;
115124
116125 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 ) ;
118128 }
119129 }
120130 finally {
121131 UnityTls . NativeInterface . unitytls_x509list_free ( trustCAnative ) ;
122132 }
123133 } else {
124134 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 ) ;
126137 }
127138 }
128139 }
140+ catch {
141+ UnityTls . NativeInterface . unitytls_x509list_free ( finalCertificateChainNative ) ;
142+ throw ;
143+ }
129144 finally {
130145 UnityTls . NativeInterface . unitytls_x509list_free ( certificatesNative ) ;
131146 }
132147
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+
133156 errors = UnityTlsConversions . VerifyResultToPolicyErrror ( result ) ;
134157 // There should be a status per certificate, but once again we're following closely the BTLS implementation
135158 // https://github.com/mono/mono/blob/1553889bc54f87060158febca7e6b8b9910975f8/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs#L180
0 commit comments