Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/hx/libs/ssl/Build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@
<lib name="crypt32.lib" if="windows" unless="static_link" />
<lib name="ws2_32.lib" if="windows" unless="static_link" />

<flag value="-framework" if="macos"/>
<flag value="Security" if="macos"/>
<section if="apple" unless="static_link">
<flag value="-framework" />
<flag value="Security" />

<flag value="-framework" unless="macos" />
<flag value="CoreFoundation" unless="macos" />
</section>
</target>

</xml>
44 changes: 41 additions & 3 deletions src/hx/libs/ssl/SSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ typedef int SOCKET;
#include <hxcpp.h>
#include <hx/OS.h>

#if defined(NEKO_MAC) && !defined(IPHONE) && !defined(APPLETV)
#if defined(NEKO_MAC) || defined(IPHONE) || defined(APPLETV)
#include <Security/Security.h>
#endif
#if defined(IPHONE) || defined(APPLETV)
#include <CoreFoundation/CoreFoundation.h>
#endif

typedef size_t socket_int;

Expand Down Expand Up @@ -439,6 +442,37 @@ static int verify_callback(void* param, mbedtls_x509_crt *crt, int depth, uint32
CertCloseStore(store, 0);
return 0;
}
#elif defined(IPHONE) || defined(APPLETV)
static int verify_callback(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
// use mbedtls validate the chain structure and we validate with the iOS system trust store to replace the missing CA bundle
if (depth != 0) {
*flags = 0;
return 0;
}

CFDataRef derData = CFDataCreate(NULL, crt->raw.p, crt->raw.len);
if (!derData) return 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The windows verify_callback returns MBEDTLS_ERR_X509_FATAL_ERROR in cases like this. Shouldn't we do the same here?


SecCertificateRef secCert = SecCertificateCreateWithData(NULL, derData);
CFRelease(derData);
if (!secCert) return 0;

SecPolicyRef policy = SecPolicyCreateSSL(true, NULL);
CFArrayRef certs = CFArrayCreate(NULL, (const void **)&secCert, 1, &kCFTypeArrayCallBacks);
SecTrustRef trust = NULL;
SecTrustCreateWithCertificates(certs, policy, &trust);
CFRelease(certs);
CFRelease(policy);
CFRelease(secCert);

CFErrorRef err = NULL;
bool trusted = SecTrustEvaluateWithError(trust, &err);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning shows when compiling this code:

/Users/runner/haxelib/hxcpp/git/src/hx/libs/ssl/SSL.cpp:427:17: warning: 'SecTrustEvaluateWithError' is only available on iOS 12.0 or newer [-Wunguarded-availability-new]
  427 |         bool trusted = SecTrustEvaluateWithError(trust, &err);
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode_26.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.2.sdk/System/Library/Frameworks/Security.framework/Headers/SecTrust.h:426:1: note: 'SecTrustEvaluateWithError' has been marked as being introduced in iOS 12.0 here, but the deployment target is iOS 10.0.0
  426 | SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error)
      | ^
/Users/runner/haxelib/hxcpp/git/src/hx/libs/ssl/SSL.cpp:427:17: note: enclose 'SecTrustEvaluateWithError' in a __builtin_available check to silence this warning
  427 |         bool trusted = SecTrustEvaluateWithError(trust, &err);
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~
  428 |         CFRelease(trust);
  429 |         if (err) CFRelease(err);
  430 | 
  431 |         if (trusted) *flags = 0;
      |                                 

We should add the suggested check

CFRelease(trust);
if (err) CFRelease(err);

if (trusted) *flags = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly on windows we set *flags |= MBEDTLS_X509_BADCERT_OTHER; if we could not verify the certificate, I think we should do the same here if trusted is false. Otherwise, I think the current code can accept invalid certificates.

return 0;
}
#endif

Dynamic _hx_ssl_conf_new( bool server ) {
Expand All @@ -451,7 +485,7 @@ Dynamic _hx_ssl_conf_new( bool server ) {
conf->destroy();
ssl_error( ret );
}
#ifdef NEKO_WINDOWS
#if defined(NEKO_WINDOWS) || defined(IPHONE) || defined(APPLETV)
mbedtls_ssl_conf_verify(conf->c, verify_callback, NULL);
#endif
mbedtls_ssl_conf_rng( conf->c, mbedtls_ctr_drbg_random, &ctr_drbg );
Expand All @@ -465,7 +499,7 @@ void _hx_ssl_conf_close( Dynamic hconf ) {

void _hx_ssl_conf_set_ca( Dynamic hconf, Dynamic hcert ) {
sslconf *conf = val_conf(hconf);
if( hconf.mPtr ){
if( hcert.mPtr ){
sslcert *cert = val_cert(hcert);
mbedtls_ssl_conf_ca_chain( conf->c, cert->c, NULL );
}else{
Expand Down Expand Up @@ -583,6 +617,10 @@ Dynamic _hx_ssl_cert_load_defaults(){
CFRelease(keychain);
if( chain != NULL )
return chain;
#elif defined(IPHONE) || defined(APPLETV) // SystemRootCertificates.keychain doesn't exist on iOS and tvOS so i use a cool workaround
sslcert *chain = new sslcert();
chain->create(NULL); // creates a ssl cert with only the default ones that iOS or tvOS trust in the os
return chain;
#endif
return null();
}
Expand Down
Loading