Skip to content

Commit b19feb9

Browse files
Apprentice-AlchemistkLabz
authored andcommitted
[mbedtls] Support mbedtls 3.x and fix bugs and compiler warnings. (#11646)
* [mbedtls] Store bio functions in a GC root. * [mbedtls] Fix incorrect alt name check. * [mbedtls] Replace String_val with Bytes_val to prevent compiler warnings. * [mbedtls] use SecTrustCopyAnchorCertificates to get root certs on macOS. SecKeychainOpen is deprecated. * [mbedtls] Remove unused includes and use angled brackets. * [mbedtls] Fix more warnings. * [mbedtls] Support mbedtls 3.x.
1 parent bc028c8 commit b19feb9

File tree

5 files changed

+61
-62
lines changed

5 files changed

+61
-62
lines changed

libs/mbedtls/mbedtls.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ external mbedtls_ssl_setup : mbedtls_ssl_context -> mbedtls_ssl_config -> mbedtl
4343
external mbedtls_ssl_write : mbedtls_ssl_context -> bytes -> int -> int -> mbedtls_result = "ml_mbedtls_ssl_write"
4444

4545
external mbedtls_pk_init : unit -> mbedtls_pk_context = "ml_mbedtls_pk_init"
46-
external mbedtls_pk_parse_key : mbedtls_pk_context -> bytes -> string option -> mbedtls_result = "ml_mbedtls_pk_parse_key"
47-
external mbedtls_pk_parse_keyfile : mbedtls_pk_context -> string -> string option -> mbedtls_result = "ml_mbedtls_pk_parse_keyfile"
46+
external mbedtls_pk_parse_key : mbedtls_pk_context -> bytes -> string option -> mbedtls_ctr_drbg_context -> mbedtls_result = "ml_mbedtls_pk_parse_key"
47+
external mbedtls_pk_parse_keyfile : mbedtls_pk_context -> string -> string option -> mbedtls_ctr_drbg_context -> mbedtls_result = "ml_mbedtls_pk_parse_keyfile"
4848
external mbedtls_pk_parse_public_keyfile : mbedtls_pk_context -> string -> mbedtls_result = "ml_mbedtls_pk_parse_public_keyfile"
4949
external mbedtls_pk_parse_public_key : mbedtls_pk_context -> bytes -> mbedtls_result = "ml_mbedtls_pk_parse_public_key"
5050

libs/mbedtls/mbedtls_stubs.c

+51-52
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include <ctype.h>
21
#include <string.h>
32
#include <stdio.h>
43

@@ -18,13 +17,10 @@
1817
#include <caml/callback.h>
1918
#include <caml/custom.h>
2019

21-
#include "mbedtls/debug.h"
2220
#include "mbedtls/error.h"
23-
#include "mbedtls/config.h"
2421
#include "mbedtls/ssl.h"
2522
#include "mbedtls/entropy.h"
2623
#include "mbedtls/ctr_drbg.h"
27-
#include "mbedtls/certs.h"
2824
#include "mbedtls/oid.h"
2925

3026
#define PVoid_val(v) (*((void**) Data_custom_val(v)))
@@ -84,7 +80,7 @@ CAMLprim value ml_mbedtls_ctr_drbg_init(void) {
8480

8581
CAMLprim value ml_mbedtls_ctr_drbg_random(value p_rng, value output, value output_len) {
8682
CAMLparam3(p_rng, output, output_len);
87-
CAMLreturn(Val_int(mbedtls_ctr_drbg_random(CtrDrbg_val(p_rng), String_val(output), Int_val(output_len))));
83+
CAMLreturn(Val_int(mbedtls_ctr_drbg_random(CtrDrbg_val(p_rng), Bytes_val(output), Int_val(output_len))));
8884
}
8985

9086
CAMLprim value ml_mbedtls_ctr_drbg_seed(value ctx, value p_entropy, value custom) {
@@ -124,7 +120,7 @@ CAMLprim value ml_mbedtls_entropy_init(void) {
124120

125121
CAMLprim value ml_mbedtls_entropy_func(value data, value output, value len) {
126122
CAMLparam3(data, output, len);
127-
CAMLreturn(Val_int(mbedtls_entropy_func(PVoid_val(data), String_val(output), Int_val(len))));
123+
CAMLreturn(Val_int(mbedtls_entropy_func(PVoid_val(data), Bytes_val(output), Int_val(len))));
128124
}
129125

130126
// Certificate
@@ -171,7 +167,7 @@ CAMLprim value ml_mbedtls_x509_next(value chain) {
171167

172168
CAMLprim value ml_mbedtls_x509_crt_parse(value chain, value bytes) {
173169
CAMLparam2(chain, bytes);
174-
const char* buf = String_val(bytes);
170+
const unsigned char* buf = Bytes_val(bytes);
175171
int len = caml_string_length(bytes);
176172
CAMLreturn(Val_int(mbedtls_x509_crt_parse(X509Crt_val(chain), buf, len + 1)));
177173
}
@@ -191,16 +187,19 @@ CAMLprim value ml_mbedtls_x509_crt_parse_path(value chain, value path) {
191187
value caml_string_of_asn1_buf(mbedtls_asn1_buf* dat) {
192188
CAMLparam0();
193189
CAMLlocal1(s);
194-
s = caml_alloc_string(dat->len);
195-
memcpy(String_val(s), dat->p, dat->len);
190+
s = caml_alloc_initialized_string(dat->len, (const char *)dat->p);
196191
CAMLreturn(s);
197192
}
198193

199194
CAMLprim value hx_cert_get_alt_names(value chain) {
200195
CAMLparam1(chain);
201196
CAMLlocal1(obj);
202197
mbedtls_x509_crt* cert = X509Crt_val(chain);
203-
if (cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME == 0 || &cert->subject_alt_names == NULL) {
198+
#if MBEDTLS_VERSION_MAJOR >= 3
199+
if (!mbedtls_x509_crt_has_ext_type(cert, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) {
200+
#else
201+
if ((cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) == 0) {
202+
#endif
204203
obj = Atom(0);
205204
} else {
206205
mbedtls_asn1_sequence* cur = &cert->subject_alt_names;
@@ -366,29 +365,39 @@ CAMLprim value ml_mbedtls_pk_init(void) {
366365
CAMLreturn(obj);
367366
}
368367

369-
CAMLprim value ml_mbedtls_pk_parse_key(value ctx, value key, value password) {
370-
CAMLparam3(ctx, key, password);
371-
const char* pwd = NULL;
368+
CAMLprim value ml_mbedtls_pk_parse_key(value ctx, value key, value password, value rng) {
369+
CAMLparam4(ctx, key, password, rng);
370+
const unsigned char* pwd = NULL;
372371
size_t pwdlen = 0;
373372
if (password != Val_none) {
374-
pwd = String_val(Field(password, 0));
373+
pwd = Bytes_val(Field(password, 0));
375374
pwdlen = caml_string_length(Field(password, 0));
376375
}
377-
CAMLreturn(mbedtls_pk_parse_key(PkContext_val(ctx), String_val(key), caml_string_length(key) + 1, pwd, pwdlen));
376+
#if MBEDTLS_VERSION_MAJOR >= 3
377+
mbedtls_ctr_drbg_context *ctr_drbg = CtrDrbg_val(rng);
378+
CAMLreturn(mbedtls_pk_parse_key(PkContext_val(ctx), Bytes_val(key), caml_string_length(key) + 1, pwd, pwdlen, mbedtls_ctr_drbg_random, NULL));
379+
#else
380+
CAMLreturn(mbedtls_pk_parse_key(PkContext_val(ctx), Bytes_val(key), caml_string_length(key) + 1, pwd, pwdlen));
381+
#endif
378382
}
379383

380-
CAMLprim value ml_mbedtls_pk_parse_keyfile(value ctx, value path, value password) {
381-
CAMLparam3(ctx, path, password);
384+
CAMLprim value ml_mbedtls_pk_parse_keyfile(value ctx, value path, value password, value rng) {
385+
CAMLparam4(ctx, path, password, rng);
382386
const char* pwd = NULL;
383387
if (password != Val_none) {
384388
pwd = String_val(Field(password, 0));
385389
}
390+
#if MBEDTLS_VERSION_MAJOR >= 3
391+
mbedtls_ctr_drbg_context *ctr_drbg = CtrDrbg_val(rng);
392+
CAMLreturn(mbedtls_pk_parse_keyfile(PkContext_val(ctx), String_val(path), pwd, mbedtls_ctr_drbg_random, ctr_drbg));
393+
#else
386394
CAMLreturn(mbedtls_pk_parse_keyfile(PkContext_val(ctx), String_val(path), pwd));
395+
#endif
387396
}
388397

389398
CAMLprim value ml_mbedtls_pk_parse_public_key(value ctx, value key) {
390399
CAMLparam2(ctx, key);
391-
CAMLreturn(mbedtls_pk_parse_public_key(PkContext_val(ctx), String_val(key), caml_string_length(key) + 1));
400+
CAMLreturn(mbedtls_pk_parse_public_key(PkContext_val(ctx), Bytes_val(key), caml_string_length(key) + 1));
392401
}
393402

394403
CAMLprim value ml_mbedtls_pk_parse_public_keyfile(value ctx, value path) {
@@ -446,23 +455,22 @@ CAMLprim value ml_mbedtls_ssl_handshake(value ssl) {
446455

447456
CAMLprim value ml_mbedtls_ssl_read(value ssl, value buf, value pos, value len) {
448457
CAMLparam4(ssl, buf, pos, len);
449-
CAMLreturn(Val_int(mbedtls_ssl_read(SslContext_val(ssl), String_val(buf) + Int_val(pos), Int_val(len))));
458+
CAMLreturn(Val_int(mbedtls_ssl_read(SslContext_val(ssl), Bytes_val(buf) + Int_val(pos), Int_val(len))));
450459
}
451460

452461
static int bio_write_cb(void* ctx, const unsigned char* buf, size_t len) {
453462
CAMLparam0();
454463
CAMLlocal3(r, s, vctx);
455-
vctx = (value)ctx;
456-
s = caml_alloc_string(len);
457-
memcpy(String_val(s), buf, len);
464+
vctx = *(value*)ctx;
465+
s = caml_alloc_initialized_string(len, (const char*)buf);
458466
r = caml_callback2(Field(vctx, 1), Field(vctx, 0), s);
459467
CAMLreturn(Int_val(r));
460468
}
461469

462470
static int bio_read_cb(void* ctx, unsigned char* buf, size_t len) {
463471
CAMLparam0();
464472
CAMLlocal3(r, s, vctx);
465-
vctx = (value)ctx;
473+
vctx = *(value*)ctx;
466474
s = caml_alloc_string(len);
467475
r = caml_callback2(Field(vctx, 2), Field(vctx, 0), s);
468476
memcpy(buf, String_val(s), len);
@@ -476,7 +484,11 @@ CAMLprim value ml_mbedtls_ssl_set_bio(value ssl, value p_bio, value f_send, valu
476484
Store_field(ctx, 0, p_bio);
477485
Store_field(ctx, 1, f_send);
478486
Store_field(ctx, 2, f_recv);
479-
mbedtls_ssl_set_bio(SslContext_val(ssl), (void*)ctx, bio_write_cb, bio_read_cb, NULL);
487+
// TODO: this allocation is leaked
488+
value *location = malloc(sizeof(value));
489+
*location = ctx;
490+
caml_register_generational_global_root(location);
491+
mbedtls_ssl_set_bio(SslContext_val(ssl), (void*)location, bio_write_cb, bio_read_cb, NULL);
480492
CAMLreturn(Val_unit);
481493
}
482494

@@ -492,7 +504,7 @@ CAMLprim value ml_mbedtls_ssl_setup(value ssl, value conf) {
492504

493505
CAMLprim value ml_mbedtls_ssl_write(value ssl, value buf, value pos, value len) {
494506
CAMLparam4(ssl, buf, pos, len);
495-
CAMLreturn(Val_int(mbedtls_ssl_write(SslContext_val(ssl), String_val(buf) + Int_val(pos), Int_val(len))));
507+
CAMLreturn(Val_int(mbedtls_ssl_write(SslContext_val(ssl), Bytes_val(buf) + Int_val(pos), Int_val(len))));
496508
}
497509

498510
// glue
@@ -520,36 +532,23 @@ CAMLprim value hx_cert_load_defaults(value certificate) {
520532
#endif
521533

522534
#ifdef __APPLE__
523-
CFMutableDictionaryRef search;
524-
CFArrayRef result;
525-
SecKeychainRef keychain;
526-
SecCertificateRef item;
527-
CFDataRef dat;
528-
// Load keychain
529-
if (SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain", &keychain) == errSecSuccess) {
530-
// Search for certificates
531-
search = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
532-
CFDictionarySetValue(search, kSecClass, kSecClassCertificate);
533-
CFDictionarySetValue(search, kSecMatchLimit, kSecMatchLimitAll);
534-
CFDictionarySetValue(search, kSecReturnRef, kCFBooleanTrue);
535-
CFDictionarySetValue(search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL));
536-
if (SecItemCopyMatching(search, (CFTypeRef *)&result) == errSecSuccess) {
537-
CFIndex n = CFArrayGetCount(result);
538-
for (CFIndex i = 0; i < n; i++) {
539-
item = (SecCertificateRef)CFArrayGetValueAtIndex(result, i);
540-
541-
// Get certificate in DER format
542-
dat = SecCertificateCopyData(item);
543-
if (dat) {
544-
r = mbedtls_x509_crt_parse_der(chain, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat));
545-
CFRelease(dat);
546-
if (r != 0) {
547-
CAMLreturn(Val_int(r));
548-
}
535+
CFArrayRef certs;
536+
if (SecTrustCopyAnchorCertificates(&certs) == errSecSuccess) {
537+
CFIndex count = CFArrayGetCount(certs);
538+
for(CFIndex i = 0; i < count; i++) {
539+
SecCertificateRef item = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
540+
541+
// Get certificate in DER format
542+
CFDataRef data = SecCertificateCopyData(item);
543+
if(data) {
544+
r = mbedtls_x509_crt_parse_der(chain, (unsigned char *)CFDataGetBytePtr(data), CFDataGetLength(data));
545+
CFRelease(data);
546+
if (r != 0) {
547+
CAMLreturn(Val_int(r));
549548
}
550549
}
551550
}
552-
CFRelease(keychain);
551+
CFRelease(certs);
553552
}
554553
#endif
555554

src/macro/eval/evalSsl.ml

+4-4
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,11 @@ let init_fields init_fields builtins =
160160
"strerror",vfun1 (fun code -> encode_string (mbedtls_strerror (decode_int code)));
161161
] [];
162162
init_fields builtins (["mbedtls"],"PkContext") [] [
163-
"parse_key",vifun2 (fun this key password ->
164-
vint (mbedtls_pk_parse_key (as_pk_context this) (decode_bytes key) (match password with VNull -> None | _ -> Some (decode_string password)));
163+
"parse_key",vifun3 (fun this key password rng ->
164+
vint (mbedtls_pk_parse_key (as_pk_context this) (decode_bytes key) (match password with VNull -> None | _ -> Some (decode_string password)) (as_ctr_drbg rng));
165165
);
166-
"parse_keyfile",vifun2 (fun this path password ->
167-
vint (mbedtls_pk_parse_keyfile (as_pk_context this) (decode_string path) (match password with VNull -> None | _ -> Some (decode_string password)));
166+
"parse_keyfile",vifun3 (fun this path password rng ->
167+
vint (mbedtls_pk_parse_keyfile (as_pk_context this) (decode_string path) (match password with VNull -> None | _ -> Some (decode_string password)) (as_ctr_drbg rng));
168168
);
169169
"parse_public_key",vifun1 (fun this key ->
170170
vint (mbedtls_pk_parse_public_key (as_pk_context this) (decode_bytes key));

std/eval/_std/mbedtls/PkContext.hx

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import haxe.io.Bytes;
55
extern class PkContext {
66
function new():Void;
77

8-
function parse_key(key:Bytes, ?pwd:String):Int;
9-
function parse_keyfile(path:String, ?password:String):Int;
8+
function parse_key(key:Bytes, ?pwd:String, ctr_dbg: CtrDrbg):Int;
9+
function parse_keyfile(path:String, ?password:String, ctr_dbg: CtrDrbg):Int;
1010
function parse_public_key(key:Bytes):Int;
1111
function parse_public_keyfile(path:String):Int;
1212
}

std/eval/_std/sys/ssl/Key.hx

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Key {
3838
var code = if (isPublic) {
3939
key.native.parse_public_keyfile(file);
4040
} else {
41-
key.native.parse_keyfile(file, pass);
41+
key.native.parse_keyfile(file, pass, Mbedtls.getDefaultCtrDrbg());
4242
}
4343
if (code != 0) {
4444
throw(mbedtls.Error.strerror(code));
@@ -51,7 +51,7 @@ class Key {
5151
var code = if (isPublic) {
5252
key.native.parse_public_key(data);
5353
} else {
54-
key.native.parse_key(data);
54+
key.native.parse_key(data, null, Mbedtls.getDefaultCtrDrbg());
5555
}
5656
if (code != 0) {
5757
throw(mbedtls.Error.strerror(code));

0 commit comments

Comments
 (0)