Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] SSL support for eval #9009

Merged
merged 44 commits into from
Feb 4, 2020
Merged

[WIP] SSL support for eval #9009

merged 44 commits into from
Feb 4, 2020

Conversation

Simn
Copy link
Member

@Simn Simn commented Dec 5, 2019

This PR starts adding SSL support for eval. To that end, we currently include the entire mbedtls code in libs/mbedtls, have a FFI layer in mbedtls_stubs.c and mbedtls.ml and then Haxe extern definitions in eval/_std/mbedtls. As a result, the diff is a mess.

There are several TODOs here:

LIB_PARAMS

I have added this to Makefile.win in order to link crypt32 on Windows:

ifeq ($(STATICLINK),0)
	LIB_PARAMS = -cclib -lpcre -cclib -lz -cclib -lcrypt32
endif

This probably isn't ideal.

Update: This is fine.

Default certificate loading

For Linux, this is handled in Mbedtls.hx with the code being copied from neko/HL. For Windows, it is handled at C-level through Mbedtls.loadDefaults with that code also being copied from neko/HL. This requires some testing.

There's currently no implementation for Mac. I was hoping that @Aurel300 could look into setting that up. It should be a matter of copying the code from https://github.com/HaxeFoundation/hashlink/blob/master/libs/ssl/ssl.c#L364-L397 and then figuring out how to handle the linking.

Amount of .c and .h files

We probably don't need to include all these files, so we should look into removing some of them.

Update: The C files have been removed.

SNI stuff

The neko/HL implementations have some code in sys.ssl.Socket which, from my understanding, is about server-side sockets. I ignored that completely as I don't plan to run https servers in eval. We have to verify that this is fine to ignore.

Rest of the sys.ssl package

The sys.ssl package has some other files:

  • Certificate
  • Digest
  • DigestAlgorithm
  • Key

Update: Certificate is done. DigestAlgorithm is just an enum.

I think Digest and Key can be added easily, but I don't know what to do with Certificate. It goes beyond being a simple extern for an mbedtls certificate and provides some public API that deals with its wrapping nature, such as next. I don't want to replicate this wrapping because it's a bad pattern for eval, so we have to think about the public API for this.

I don't think this should stop us from merging the Socket part this PR focuses on though.

Update: I'll just shut up and follow the API.

Update: Key has been added.

Overall testing

The CI is green so building works, but we don't actually have any https tests.

Packaging and licensing

This is something I usually forget about, so this time around I'd like to check with @andyli if the approach taken here causes any issues for packaging.

On a maybe related note, I have no idea about licensing and if we can just drop the mbedtls source code into our project.

Update: The C files have been removed.

Makefile Outdated Show resolved Hide resolved
@RealyUniqueName
Copy link
Member

I have only a slight knowledge of SSL, so I can't properly review that.
But I don't like mbedtls being a top-level package. I think it should be somewhere in subpackages of eval.
Same for sys.net.NativeSocket which is eval-specific.

@andyli
Copy link
Member

andyli commented Dec 5, 2019

Don't commit mbedtls source code into our repo. I think you can let dune to download and extract a mbedtls archive, when it doesn't exist globally or in the project folder. It's mainly because the Linux packages have to use the distros' mbedtls.

@Simn
Copy link
Member Author

Simn commented Dec 5, 2019

But I don't like mbedtls being a top-level package. I think it should be somewhere in subpackages of eval.

The mbedtls API isn't eval-specific.

@skial skial mentioned this pull request Dec 5, 2019
1 task
@Simn
Copy link
Member Author

Simn commented Dec 5, 2019

Same for sys.net.NativeSocket which is eval-specific.

That used to be a private class so it didn't matter, but you're right. I've moved it to eval.vm now, which is not a good package name but follows the neko layout.

@RealyUniqueName
Copy link
Member

The mbedtls API isn't eval-specific.

Maybe move it into sys.ssl?

@Simn
Copy link
Member Author

Simn commented Dec 5, 2019

Don't commit mbedtls source code into our repo. I think you can let dune to download and extract a mbedtls archive, when it doesn't exist globally or in the project folder.

I can't find anything about it downloading sources. The foreign build section explicitly states "put all the foreign code in a sub-directory".

The best alternative I can think of right now is using a submodule...

libs/mbedtls/dune Outdated Show resolved Hide resolved
libs/mbedtls/mbedtls_stubs.c Outdated Show resolved Hide resolved
libs/mbedtls/mbedtls_stubs.c Outdated Show resolved Hide resolved
libs/mbedtls/mbedtls_stubs.c Outdated Show resolved Hide resolved
libs/mbedtls/mbedtls_stubs.c Outdated Show resolved Hide resolved
src/macro/eval/evalSsl.ml Outdated Show resolved Hide resolved
std/eval/_std/mbedtls/Certificate.hx Outdated Show resolved Hide resolved
std/eval/_std/sys/ssl/Mbedtls.hx Outdated Show resolved Hide resolved
std/eval/_std/sys/ssl/Socket.hx Outdated Show resolved Hide resolved
std/sys/Http.hx Show resolved Hide resolved
mbedtls_x509_crt* cert = X509Crt_val(chain);
mbedtls_x509_time *t = &cert->valid_to;
time_t time = time_to_time_t(t);
CAMLreturn(caml_copy_double((double)time));
Copy link
Member

Choose a reason for hiding this comment

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

I thought time_t was usually an integer type? Also will this work on 32-bit systems?

Copy link
Member Author

Choose a reason for hiding this comment

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

I expect the C compiler to handle this accordingly, but if you have an alternative suggestion I'll be happy to change this.

private function get_altNames():Array<String> {
throw "Not implemented";
}
extern private function get_altNames():Array<String>;
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know if this actually works because no Certificate I come across has a value for this, so all we get are empty arrays.

@Simn
Copy link
Member Author

Simn commented Dec 12, 2019

I have completed the Certificate API. Not sure if this actually works as expected because we have no tests, so I guess time will tell.

I'll add the APIs for Digest and Key and then we just need to deal with the OS X default certificate loading. After that, I think we can merge.

CAMLlocal1(obj);
mbedtls_x509_crt* cert = X509Crt_val(chain);
if (cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME == 0 || &cert->subject_alt_names == NULL) {
obj = Atom(0);
Copy link
Member Author

Choose a reason for hiding this comment

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

@Aurel300 fyi, I found another potential trap here:

Atom(t) returns an “atom” (zero-sized block) with tag t. Zero-sized blocks are preallocated outside of the heap. It is incorrect to try and allocate a zero-sized block using the functions below. For instance, Atom(0) represents the empty array.

This means that whenever we want to return an array from C externs, we have to deal with the length == 0 special case.

@RealyUniqueName RealyUniqueName added this to the Release 4.1 milestone Dec 19, 2019
@RealyUniqueName RealyUniqueName added the platform-eval Everything related to the Haxe 4 eval macro interpreter label Dec 19, 2019
@Simn
Copy link
Member Author

Simn commented Jan 23, 2020

@Aurel300 Could you look into the OS X default certificate situation some time soon? I want to merge SSL support for the next release and this is blocking it at the moment.

@Aurel300
Copy link
Member

Aurel300 commented Feb 4, 2020

@Simn Sorry for the delay, this should be good now. Python failure is unrelated. For reference, the reason the LIB_PARAMS change in the Makefile didn't work on its own is because apparently if you specify a variable directly on the command line, it completely overrides it in the Makefile, so even things like += don't work.

@Simn
Copy link
Member Author

Simn commented Feb 4, 2020

Alright, thanks! I'm gonna merge this now.

For people building Haxe, please refer to the CI-related changes here. I think we've made this as straightforward as possible.

@Simn Simn merged commit 2351868 into development Feb 4, 2020
@Simn Simn deleted the eval-ssl branch February 4, 2020 12:12
@skial skial mentioned this pull request Feb 5, 2020
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform-eval Everything related to the Haxe 4 eval macro interpreter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants