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="Security" unless="macos" />
</section>
</target>

</xml>
56 changes: 53 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 @@ -361,12 +364,12 @@ int _hx_ssl_recv( Dynamic hssl, Array<unsigned char> buf, int p, int l ) {
HANDLE_EINTR(recv_again);
hx::Throw(HX_CSTRING("ssl network error"));
}
if( dlen < 0 ) {
if( dlen < 0 ) {
if( dlen == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ) {
mbedtls_ssl_close_notify( ssl->s );
return 0;
}
hx::Throw( HX_CSTRING("ssl_recv") );
hx::Throw( HX_CSTRING("ssl_recv") );
}
return dlen;
}
Expand Down Expand Up @@ -463,14 +466,57 @@ void _hx_ssl_conf_close( Dynamic hconf ) {
conf->destroy();
}

#if defined(IPHONE) || defined(APPLETV)
static int apple_verify_cb(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;

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);
CFRelease(trust);
if (err) CFRelease(err);

if (trusted) *flags = 0;
return 0;
}
#endif

void _hx_ssl_conf_set_ca( Dynamic hconf, Dynamic hcert ) {
sslconf *conf = val_conf(hconf);
#if defined(IPHONE) || defined(APPLETV)
// always attach Apple system verification callback
mbedtls_ssl_conf_verify(conf->c, apple_verify_cb, NULL);

sslcert *cert = val_cert(hcert);
// make sure the ca chain is set even if null
mbedtls_ssl_conf_ca_chain(conf->c, cert ? cert->c : NULL, NULL);

#else
if( hconf.mPtr ){
sslcert *cert = val_cert(hcert);
mbedtls_ssl_conf_ca_chain( conf->c, cert->c, NULL );
}else{
mbedtls_ssl_conf_ca_chain( conf->c, NULL, NULL );
}
#endif
}

void _hx_ssl_conf_set_verify( Dynamic hconf, int mode ) {
Expand Down Expand Up @@ -583,6 +629,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