Skip to content

Commit caa098e

Browse files
FuroYTMAJigsaw77
authored andcommitted
Fixed SSL CA chain on iOS and tvOS
1 parent 18204ea commit caa098e

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

src/hx/libs/ssl/Build.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@
2323
<lib name="crypt32.lib" if="windows" unless="static_link" />
2424
<lib name="ws2_32.lib" if="windows" unless="static_link" />
2525

26-
<flag value="-framework" if="macos"/>
27-
<flag value="Security" if="macos"/>
26+
<section if="apple" unless="static_link">
27+
<flag value="-framework" />
28+
<flag value="Security" />
29+
30+
<flag value="-framework" unless="macos" />
31+
<flag value="Security" unless="macos" />
32+
</section>
2833
</target>
2934

3035
</xml>

src/hx/libs/ssl/SSL.cpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ typedef int SOCKET;
1414
#include <hxcpp.h>
1515
#include <hx/OS.h>
1616

17-
#if defined(NEKO_MAC) && !defined(IPHONE) && !defined(APPLETV)
17+
#if defined(NEKO_MAC) || defined(IPHONE) || defined(APPLETV)
1818
#include <Security/Security.h>
1919
#endif
20+
#if defined(IPHONE) || defined(APPLETV)
21+
#include <CoreFoundation/CoreFoundation.h>
22+
#endif
2023

2124
typedef size_t socket_int;
2225

@@ -439,6 +442,37 @@ static int verify_callback(void* param, mbedtls_x509_crt *crt, int depth, uint32
439442
CertCloseStore(store, 0);
440443
return 0;
441444
}
445+
#elif defined(IPHONE) || defined(APPLETV)
446+
static int verify_callback(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
447+
// use mbedtls validate the chain structure and we validate with the iOS system trust store to replace the missing CA bundle
448+
if (depth != 0) {
449+
*flags = 0;
450+
return 0;
451+
}
452+
453+
CFDataRef derData = CFDataCreate(NULL, crt->raw.p, crt->raw.len);
454+
if (!derData) return 0;
455+
456+
SecCertificateRef secCert = SecCertificateCreateWithData(NULL, derData);
457+
CFRelease(derData);
458+
if (!secCert) return 0;
459+
460+
SecPolicyRef policy = SecPolicyCreateSSL(true, NULL);
461+
CFArrayRef certs = CFArrayCreate(NULL, (const void **)&secCert, 1, &kCFTypeArrayCallBacks);
462+
SecTrustRef trust = NULL;
463+
SecTrustCreateWithCertificates(certs, policy, &trust);
464+
CFRelease(certs);
465+
CFRelease(policy);
466+
CFRelease(secCert);
467+
468+
CFErrorRef err = NULL;
469+
bool trusted = SecTrustEvaluateWithError(trust, &err);
470+
CFRelease(trust);
471+
if (err) CFRelease(err);
472+
473+
if (trusted) *flags = 0;
474+
return 0;
475+
}
442476
#endif
443477

444478
Dynamic _hx_ssl_conf_new( bool server ) {
@@ -451,7 +485,7 @@ Dynamic _hx_ssl_conf_new( bool server ) {
451485
conf->destroy();
452486
ssl_error( ret );
453487
}
454-
#ifdef NEKO_WINDOWS
488+
#if defined(NEKO_WINDOWS) || defined(IPHONE) || defined(APPLETV)
455489
mbedtls_ssl_conf_verify(conf->c, verify_callback, NULL);
456490
#endif
457491
mbedtls_ssl_conf_rng( conf->c, mbedtls_ctr_drbg_random, &ctr_drbg );
@@ -583,6 +617,10 @@ Dynamic _hx_ssl_cert_load_defaults(){
583617
CFRelease(keychain);
584618
if( chain != NULL )
585619
return chain;
620+
#elif defined(IPHONE) || defined(APPLETV) // SystemRootCertificates.keychain doesn't exist on iOS and tvOS so i use a cool workaround
621+
sslcert *chain = new sslcert();
622+
chain->create(NULL); // creates a ssl cert with only the default ones that iOS or tvOS trust in the os
623+
return chain;
586624
#endif
587625
return null();
588626
}

0 commit comments

Comments
 (0)