From c950be01aca0ecce9b5f68b9f4430e99ecc51037 Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Fri, 30 Sep 2016 11:46:46 +0200 Subject: [PATCH] [BTLS]: Add the native BTLS sources. --- .gitmodules | 4 + configure.ac | 1 + external/boringssl | 1 + mono/Makefile.am | 12 +- mono/btls/.gitignore | 6 + mono/btls/CMakeLists.txt | 89 ++++++ mono/btls/Makefile.am | 30 ++ mono/btls/btls-android-utils.c | 33 +++ mono/btls/btls-bio.c | 206 ++++++++++++++ mono/btls/btls-bio.h | 58 ++++ mono/btls/btls-error.c | 35 +++ mono/btls/btls-error.h | 29 ++ mono/btls/btls-key.c | 83 ++++++ mono/btls/btls-key.h | 35 +++ mono/btls/btls-pkcs12.c | 101 +++++++ mono/btls/btls-pkcs12.h | 46 +++ mono/btls/btls-ssl-ctx.c | 255 +++++++++++++++++ mono/btls/btls-ssl-ctx.h | 84 ++++++ mono/btls/btls-ssl.c | 229 +++++++++++++++ mono/btls/btls-ssl.h | 83 ++++++ mono/btls/btls-util.c | 76 +++++ mono/btls/btls-util.h | 29 ++ mono/btls/btls-x509-chain.c | 96 +++++++ mono/btls/btls-x509-chain.h | 41 +++ mono/btls/btls-x509-crl.c | 150 ++++++++++ mono/btls/btls-x509-crl.h | 49 ++++ mono/btls/btls-x509-lookup-mono.c | 228 +++++++++++++++ mono/btls/btls-x509-lookup-mono.h | 36 +++ mono/btls/btls-x509-lookup.c | 160 +++++++++++ mono/btls/btls-x509-lookup.h | 58 ++++ mono/btls/btls-x509-name.c | 294 +++++++++++++++++++ mono/btls/btls-x509-name.h | 80 ++++++ mono/btls/btls-x509-revoked.c | 72 +++++ mono/btls/btls-x509-revoked.h | 34 +++ mono/btls/btls-x509-store-ctx.c | 229 +++++++++++++++ mono/btls/btls-x509-store-ctx.h | 69 +++++ mono/btls/btls-x509-store.c | 110 ++++++++ mono/btls/btls-x509-store.h | 46 +++ mono/btls/btls-x509-verify-param.c | 221 +++++++++++++++ mono/btls/btls-x509-verify-param.h | 81 ++++++ mono/btls/btls-x509.c | 436 +++++++++++++++++++++++++++++ mono/btls/btls-x509.h | 127 +++++++++ mono/btls/create-object-library.sh | 32 +++ mono/metadata/Makefile.am | 18 +- mono/metadata/icall-def.h | 239 ++++++++++++++++ mono/metadata/icall.c | 26 ++ 46 files changed, 4448 insertions(+), 9 deletions(-) create mode 160000 external/boringssl create mode 100644 mono/btls/.gitignore create mode 100644 mono/btls/CMakeLists.txt create mode 100644 mono/btls/Makefile.am create mode 100644 mono/btls/btls-android-utils.c create mode 100644 mono/btls/btls-bio.c create mode 100644 mono/btls/btls-bio.h create mode 100644 mono/btls/btls-error.c create mode 100644 mono/btls/btls-error.h create mode 100644 mono/btls/btls-key.c create mode 100644 mono/btls/btls-key.h create mode 100644 mono/btls/btls-pkcs12.c create mode 100644 mono/btls/btls-pkcs12.h create mode 100644 mono/btls/btls-ssl-ctx.c create mode 100644 mono/btls/btls-ssl-ctx.h create mode 100644 mono/btls/btls-ssl.c create mode 100644 mono/btls/btls-ssl.h create mode 100644 mono/btls/btls-util.c create mode 100644 mono/btls/btls-util.h create mode 100644 mono/btls/btls-x509-chain.c create mode 100644 mono/btls/btls-x509-chain.h create mode 100644 mono/btls/btls-x509-crl.c create mode 100644 mono/btls/btls-x509-crl.h create mode 100644 mono/btls/btls-x509-lookup-mono.c create mode 100644 mono/btls/btls-x509-lookup-mono.h create mode 100644 mono/btls/btls-x509-lookup.c create mode 100644 mono/btls/btls-x509-lookup.h create mode 100644 mono/btls/btls-x509-name.c create mode 100644 mono/btls/btls-x509-name.h create mode 100644 mono/btls/btls-x509-revoked.c create mode 100644 mono/btls/btls-x509-revoked.h create mode 100644 mono/btls/btls-x509-store-ctx.c create mode 100644 mono/btls/btls-x509-store-ctx.h create mode 100644 mono/btls/btls-x509-store.c create mode 100644 mono/btls/btls-x509-store.h create mode 100644 mono/btls/btls-x509-verify-param.c create mode 100644 mono/btls/btls-x509-verify-param.h create mode 100644 mono/btls/btls-x509.c create mode 100644 mono/btls/btls-x509.h create mode 100755 mono/btls/create-object-library.sh diff --git a/.gitmodules b/.gitmodules index d084d3948e4..6d87209417e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,3 +39,7 @@ path = external/cecil-legacy url = git://github.com/mono/cecil.git branch = mono-legacy-0.9.5 +[submodule "external/boringssl"] + path = external/boringssl + url = git://github.com/mono/boringssl.git + branch = mono diff --git a/configure.ac b/configure.ac index 0946284c263..7700a3fa1e5 100644 --- a/configure.ac +++ b/configure.ac @@ -4245,6 +4245,7 @@ llvm/Makefile scripts/mono-find-provides scripts/mono-find-requires mono/Makefile +mono/btls/Makefile mono/utils/Makefile mono/metadata/Makefile mono/dis/Makefile diff --git a/external/boringssl b/external/boringssl new file mode 160000 index 00000000000..bb4fcdfaaa6 --- /dev/null +++ b/external/boringssl @@ -0,0 +1 @@ +Subproject commit bb4fcdfaaa6190109f3e2413195cdc62fec30d82 diff --git a/mono/Makefile.am b/mono/Makefile.am index 7bf7b5c3ded..651271c25f8 100644 --- a/mono/Makefile.am +++ b/mono/Makefile.am @@ -2,11 +2,15 @@ if SUPPORT_SGEN sgen_dirs = sgen endif +if BTLS +btls_dirs = btls +endif + if CROSS_COMPILING -SUBDIRS = arch utils io-layer cil metadata $(sgen_dirs) mini dis profiler +SUBDIRS = $(btls_dirs) arch utils io-layer cil metadata $(sgen_dirs) mini dis profiler else if INSTALL_MONOTOUCH -SUBDIRS = arch utils io-layer metadata $(sgen_dirs) mini profiler +SUBDIRS = $(btls_dirs) arch utils io-layer metadata $(sgen_dirs) mini profiler monotouch-do-build: @list='$(SUBDIRS)'; for subdir in $$list; do \ @@ -30,7 +34,7 @@ monotouch-do-clean: (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ done; else -SUBDIRS = arch utils io-layer cil metadata $(sgen_dirs) mini dis tests unit-tests benchmark profiler +SUBDIRS = $(btls_dirs) arch utils io-layer cil metadata $(sgen_dirs) mini dis tests unit-tests benchmark profiler endif endif -DIST_SUBDIRS = arch utils io-layer cil metadata $(sgen_dirs) mini dis tests unit-tests benchmark profiler +DIST_SUBDIRS = btls arch utils io-layer cil metadata $(sgen_dirs) mini dis tests unit-tests benchmark profiler diff --git a/mono/btls/.gitignore b/mono/btls/.gitignore new file mode 100644 index 00000000000..545f630f79b --- /dev/null +++ b/mono/btls/.gitignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +build/ +martin-test +build-shared/ +build-static/ diff --git a/mono/btls/CMakeLists.txt b/mono/btls/CMakeLists.txt new file mode 100644 index 00000000000..7679aaadc44 --- /dev/null +++ b/mono/btls/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required (VERSION 2.8.10) + +project (mono-btls) + +cmake_policy(SET CMP0026 NEW) +cmake_policy(SET CMP0042 NEW) + +enable_language(C) +enable_language(CXX) + +# FIXME: cmake's asm detection is broken when using xcrun. +set (CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}") +set (CMAKE_ASM_COMPILER_ARG1 "${CMAKE_C_COMPILER_ARG1}") +set (CMAKE_ASM_COMPILER_ID "${CMAKE_C_COMPILER_ID}") +enable_language(ASM) + +if (NOT "${BTLS_ARCH}" STREQUAL "") + message (WARNING "SET ARCH: ${BTLS_ARCH}") + set (CMAKE_SYSTEM_PROCESSOR "${BTLS_ARCH}") +endif () +set (C_CXX_FLAGS "-Wall -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} ${BTLS_CFLAGS}") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_FLAGS} ${BTLS_CFLAGS}") +set (CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${BTLS_CFLAGS}") +set (CMAKE_MACOSX_RPATH 1) +set (MONO_BTLS 1) + +add_subdirectory (${BTLS_ROOT} boringssl) + +include_directories ( + ${SRC_DIR} + ${BTLS_ROOT}/include +) + +set ( + MONO_BTLS_SOURCES + + btls-bio.c + btls-bio.h + btls-error.c + btls-error.h + btls-key.c + btls-key.h + btls-pkcs12.c + btls-pkcs12.h + btls-ssl-ctx.c + btls-ssl-ctx.h + btls-ssl.c + btls-ssl.h + btls-util.c + btls-util.h + btls-x509-chain.c + btls-x509-chain.h + btls-x509-crl.c + btls-x509-crl.h + btls-x509-lookup.c + btls-x509-lookup.h + btls-x509-lookup-mono.c + btls-x509-lookup-mono.h + btls-x509-name.c + btls-x509-name.h + btls-x509-revoked.c + btls-x509-revoked.h + btls-x509-store-ctx.c + btls-x509-store-ctx.h + btls-x509-store.c + btls-x509-store.h + btls-x509-verify-param.c + btls-x509-verify-param.h + btls-x509.c + btls-x509.h + + btls-android-utils.c + + ${BORINGSSL_OBJECTS} +) + +if (BUILD_SHARED_LIBS) + add_library (mono-btls-shared SHARED ${MONO_BTLS_SOURCES}) + set_target_properties (mono-btls-shared PROPERTIES RULE_LAUNCH_LINK + "${PROJECT_SOURCE_DIR}/create-object-library.sh ${CMAKE_BINARY_DIR} mono-btls-shared.txt mono-btls-shared-lo.txt libmono-btls-shared.a shared ${CMAKE_AR} ${CMAKE_RANLIB} --" + ) +else () + add_library (mono-btls-static STATIC ${MONO_BTLS_SOURCES}) + set_target_properties (mono-btls-static PROPERTIES RULE_LAUNCH_LINK + "${PROJECT_SOURCE_DIR}/create-object-library.sh ${CMAKE_BINARY_DIR} mono-btls-static.txt mono-btls-static-lo.txt libmono-btls-static.a static ${CMAKE_AR} ${CMAKE_RANLIB} --" + ) +endif () + diff --git a/mono/btls/Makefile.am b/mono/btls/Makefile.am new file mode 100644 index 00000000000..064a05d74e0 --- /dev/null +++ b/mono/btls/Makefile.am @@ -0,0 +1,30 @@ +BTLS_STATIC_LIST = build-static/mono-btls-static-lo.txt +BTLS_SHARED_LIST = build-shared/mono-btls-shared-lo.txt + +BTLS_DEPS = $(BTLS_LIBS) build-shared/Makefile build-static/Makefile + +CMAKE_VERBOSE=$(if $(V),VERBOSE=1,) + +CMAKE_ARGS = -D CMAKE_INSTALL_PREFIX:PATH=$(prefix) -D BTLS_ROOT:PATH=$(BTLS_ROOT) \ + -D SRC_DIR:PATH=$(abs_top_srcdir)/mono/btls -D BTLS_CFLAGS:STRING="$(BTLS_CFLAGS)" + +all-local: $(BTLS_STATIC_LIST) $(BTLS_SHARED_LIST) + +build-shared/Makefile: + -mkdir -p build-shared + (cd build-shared && $(CMAKE) $(CMAKE_ARGS) $(BTLS_CMAKE_ARGS) -DBUILD_SHARED_LIBS=1 $(abs_top_srcdir)/mono/btls) + +build-static/Makefile: + -mkdir -p build-static + (cd build-static && $(CMAKE) $(CMAKE_ARGS) $(BTLS_CMAKE_ARGS) $(abs_top_srcdir)/mono/btls) + +$(BTLS_STATIC_LIST): build-static/Makefile + $(MAKE) -C build-static $(CMAKE_VERBOSE) + +$(BTLS_SHARED_LIST): build-shared/Makefile + $(MAKE) -C build-shared $(CMAKE_VERBOSE) + +clean-local: + -rm -rf build-static + -rm -rf build-shared + diff --git a/mono/btls/btls-android-utils.c b/mono/btls/btls-android-utils.c new file mode 100644 index 00000000000..df30f855d7e --- /dev/null +++ b/mono/btls/btls-android-utils.c @@ -0,0 +1,33 @@ +// Copied from Chromium: https://src.chromium.org/svn/trunk/src/base/os_compat_android.cc + +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(__ANDROID__) + +#include +#include +#include +#include +#include + +#if !defined(__LP64__) +#include +#endif + +#if !defined(__LP64__) +// 32-bit Android has only timegm64() and not timegm(). +// We replicate the behaviour of timegm() when the result overflows time_t. +time_t timegm(struct tm* const t) { + // time_t is signed on Android. + static const time_t kTimeMax = ~(1L << (sizeof(time_t) * CHAR_BIT - 1)); + static const time_t kTimeMin = (1L << (sizeof(time_t) * CHAR_BIT - 1)); + time64_t result = timegm64(t); + if (result < kTimeMin || result > kTimeMax) + return -1; + return result; +} +#endif + +#endif diff --git a/mono/btls/btls-bio.c b/mono/btls/btls-bio.c new file mode 100644 index 00000000000..5af2d86ecd6 --- /dev/null +++ b/mono/btls/btls-bio.c @@ -0,0 +1,206 @@ +// +// btls-bio.c +// MonoBtls +// +// Created by Martin Baulig on 14/11/15. +// Copyright (c) 2015 Xamarin. All rights reserved. +// + +#include +#include +#include + +struct MonoBtlsBio { + const void *instance; + MonoBtlsReadFunc read_func; + MonoBtlsWriteFunc write_func; + MonoBtlsControlFunc control_func; +}; + +#if 0 +static void +mono_debug (const char *message) +{ + BIO *bio_err; + bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); + fprintf (stderr, "DEBUG: %s\n", message); + ERR_print_errors (bio_err); +} +#endif + +static int +mono_read (BIO *bio, char *out, int outl) +{ + MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr; + int ret, wantMore; + + if (!mono) + return -1; + + ret = mono->read_func (mono->instance, out, outl, &wantMore); + + if (ret < 0) + return -1; + if (ret > 0) + return ret; + + if (wantMore) { + errno = EAGAIN; + BIO_set_retry_read (bio); + return -1; + } + + return 0; +} + +static int +mono_write (BIO *bio, const char *in, int inl) +{ + MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr; + + if (!mono) + return -1; + + return mono->write_func (mono->instance, in, inl); +} + +static long +mono_ctrl (BIO *bio, int cmd, long num, void *ptr) +{ + MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr; + + if (!mono) + return -1; + + // fprintf (stderr, "mono_ctrl: %x - %lx - %p\n", cmd, num, ptr); + switch (cmd) { + case BIO_CTRL_FLUSH: + return mono->control_func (mono->instance, MONO_BTLS_CONTROL_COMMAND_FLUSH, 0); + default: + return -1; + } + return -1; +} + +static int +mono_new (BIO *bio) +{ + // mono_debug("mono_new!\n"); + bio->init = 0; + bio->num = -1; + bio->flags = 0; + return 1; +} + +static int +mono_free (BIO *bio) +{ + // mono_debug ("mono_free!\n"); + if (bio->ptr) { + MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr; + + bio->ptr = NULL; + mono->instance = NULL; + mono->read_func = NULL; + mono->write_func = NULL; + mono->control_func = NULL; + free (mono); + } + return 1; +} + +static const BIO_METHOD mono_method = { + BIO_TYPE_NONE, "mono", mono_write, mono_read, + NULL, NULL, mono_ctrl, mono_new, mono_free, NULL +}; + +BIO * +mono_btls_bio_mono_new (void) +{ + BIO *bio; + MonoBtlsBio *monoBio; + + bio = BIO_new (&mono_method); + if (!bio) + return NULL; + + monoBio = calloc (1, sizeof (MonoBtlsBio)); + if (!monoBio) { + BIO_free (bio); + return NULL; + } + + bio->ptr = monoBio; + bio->init = 0; + + return bio; +} + +void +mono_btls_bio_mono_initialize (BIO *bio, const void *instance, + MonoBtlsReadFunc read_func, MonoBtlsWriteFunc write_func, + MonoBtlsControlFunc control_func) +{ + MonoBtlsBio *monoBio = bio->ptr; + + monoBio->instance = instance; + monoBio->read_func = read_func; + monoBio->write_func = write_func; + monoBio->control_func = control_func; + + bio->init = 1; +} + +int +mono_btls_bio_read (BIO *bio, void *data, int len) +{ + return BIO_read (bio, data, len); +} + +int +mono_btls_bio_write (BIO *bio, const void *data, int len) +{ + return BIO_write (bio, data, len); +} + +int +mono_btls_bio_flush (BIO *bio) +{ + return BIO_flush (bio); +} + +int +mono_btls_bio_indent (BIO *bio, unsigned indent, unsigned max_indent) +{ + return BIO_indent (bio, indent, max_indent); +} + +int +mono_btls_bio_hexdump (BIO *bio, const uint8_t *data, int len, unsigned indent) +{ + return BIO_hexdump (bio, data, len, indent); +} + +void +mono_btls_bio_print_errors (BIO *bio) +{ + BIO_print_errors (bio); +} + +void +mono_btls_bio_free (BIO *bio) +{ + BIO_free (bio); +} + +BIO * +mono_btls_bio_mem_new (void) +{ + return BIO_new (BIO_s_mem ()); +} + +int +mono_btls_bio_mem_get_data (BIO *bio, void **data) +{ + return (int)BIO_get_mem_data (bio, (char**)data); +} diff --git a/mono/btls/btls-bio.h b/mono/btls/btls-bio.h new file mode 100644 index 00000000000..d4429f6d628 --- /dev/null +++ b/mono/btls/btls-bio.h @@ -0,0 +1,58 @@ +// +// btls-bio.h +// MonoBtls +// +// Created by Martin Baulig on 14/11/15. +// Copyright (c) 2015 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_bio__ +#define __btls__btls_bio__ + +#include +#include + +typedef enum { + MONO_BTLS_CONTROL_COMMAND_FLUSH = 1 +} MonoBtlsControlCommand; + +typedef int (* MonoBtlsReadFunc) (const void *instance, const void *buf, int size, int *wantMore); +typedef int (* MonoBtlsWriteFunc) (const void *instance, const void *buf, int size); +typedef long (* MonoBtlsControlFunc) (const void *instance, MonoBtlsControlCommand command, long arg); + +BIO * +mono_btls_bio_mono_new (void); + +void +mono_btls_bio_mono_initialize (BIO *bio, const void *instance, + MonoBtlsReadFunc read_func, MonoBtlsWriteFunc write_func, + MonoBtlsControlFunc control_func); + +int +mono_btls_bio_read (BIO *bio, void *data, int len); + +int +mono_btls_bio_write (BIO *bio, const void *data, int len); + +int +mono_btls_bio_flush (BIO *bio); + +int +mono_btls_bio_indent (BIO *bio, unsigned indent, unsigned max_indent); + +int +mono_btls_bio_hexdump (BIO *bio, const uint8_t *data, int len, unsigned indent); + +void +mono_btls_bio_print_errors (BIO *bio); + +void +mono_btls_bio_free (BIO *bio); + +BIO * +mono_btls_bio_mem_new (void); + +int +mono_btls_bio_mem_get_data (BIO *bio, void **data); + +#endif /* defined(__btls__btls_bio__) */ diff --git a/mono/btls/btls-error.c b/mono/btls/btls-error.c new file mode 100644 index 00000000000..8ed950c7e66 --- /dev/null +++ b/mono/btls/btls-error.c @@ -0,0 +1,35 @@ +// +// btls-error.c +// MonoBtls +// +// Created by Martin Baulig on 6/19/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include + +int +mono_btls_error_peek_error (void) +{ + return ERR_peek_error (); +} + +int +mono_btls_error_get_error (void) +{ + return ERR_get_error (); +} + +void +mono_btls_error_clear_error (void) +{ + ERR_clear_error (); +} + +void +mono_btls_error_get_error_string_n (int error, char *buf, int len) +{ + ERR_error_string_n (error, buf, len); +} + diff --git a/mono/btls/btls-error.h b/mono/btls/btls-error.h new file mode 100644 index 00000000000..6f791c372a4 --- /dev/null +++ b/mono/btls/btls-error.h @@ -0,0 +1,29 @@ +// +// btls-util.h +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_error__ +#define __btls__btls_error__ + +#include +#include +#include +#include + +int +mono_btls_error_peek_error (void); + +int +mono_btls_error_get_error (void); + +void +mono_btls_error_clear_error (void); + +void +mono_btls_error_get_error_string_n (int error, char *buf, int len); + +#endif /* __btls__btls_error__ */ diff --git a/mono/btls/btls-key.c b/mono/btls/btls-key.c new file mode 100644 index 00000000000..708abe4cfbb --- /dev/null +++ b/mono/btls/btls-key.c @@ -0,0 +1,83 @@ +// +// btls-key.c +// MonoBtls +// +// Created by Martin Baulig on 3/7/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include + +void +mono_btls_key_free (EVP_PKEY *pkey) +{ + EVP_PKEY_free (pkey); +} + +EVP_PKEY * +mono_btls_key_up_ref (EVP_PKEY *pkey) +{ + return EVP_PKEY_up_ref (pkey); +} + +int +mono_btls_key_get_bits (EVP_PKEY *pkey) +{ + return EVP_PKEY_bits (pkey); +} + +int +mono_btls_key_is_rsa (EVP_PKEY *pkey) +{ + return pkey->type == EVP_PKEY_RSA; +} + +int +mono_btls_key_get_bytes (EVP_PKEY *pkey, uint8_t **buffer, int *size, int include_private_bits) +{ + size_t len; + RSA *rsa; + int ret; + + *size = 0; + *buffer = NULL; + + if (pkey->type != EVP_PKEY_RSA) + return 0; + + rsa = EVP_PKEY_get1_RSA (pkey); + if (!rsa) + return 0; + + if (include_private_bits) + ret = RSA_private_key_to_bytes (buffer, &len, rsa); + else + ret = RSA_public_key_to_bytes (buffer, &len, rsa); + + if (ret != 1) + return 0; + + *size = (int)len; + return 1; +} + +int +mono_btls_key_test (EVP_PKEY *pkey) +{ + RSA *rsa; + unsigned char *p = NULL; + int ret; + + if (pkey->type != EVP_PKEY_RSA) + return 0; + + rsa = EVP_PKEY_get1_RSA (pkey); + if (!rsa) + return 0; + + ret = i2d_RSA_PUBKEY (rsa, &p); + + RSA_free (rsa); + return ret; + +} diff --git a/mono/btls/btls-key.h b/mono/btls/btls-key.h new file mode 100644 index 00000000000..a262d6a0906 --- /dev/null +++ b/mono/btls/btls-key.h @@ -0,0 +1,35 @@ +// +// btls-key.h +// MonoBtls +// +// Created by Martin Baulig on 3/7/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_key__ +#define __btls__btls_key__ + +#include +#include +#include + +void +mono_btls_key_free (EVP_PKEY *pkey); + +EVP_PKEY * +mono_btls_key_up_ref (EVP_PKEY *pkey); + +int +mono_btls_key_get_bits (EVP_PKEY *pkey); + +int +mono_btls_key_is_rsa (EVP_PKEY *pkey); + +int +mono_btls_key_test (EVP_PKEY *pkey); + +int +mono_btls_key_get_bytes (EVP_PKEY *pkey, uint8_t **buffer, int *size, int include_private_bits); + +#endif /* __btls__btls_key__ */ + diff --git a/mono/btls/btls-pkcs12.c b/mono/btls/btls-pkcs12.c new file mode 100644 index 00000000000..d037ddb8910 --- /dev/null +++ b/mono/btls/btls-pkcs12.c @@ -0,0 +1,101 @@ +// +// btls-pkcs12.c +// MonoBtls +// +// Created by Martin Baulig on 3/8/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include + +struct MonoBtlsPkcs12 { + STACK_OF(X509) *certs; + EVP_PKEY *private_key; + CRYPTO_refcount_t references; +}; + +MonoBtlsPkcs12 * +mono_btls_pkcs12_new (void) +{ + MonoBtlsPkcs12 *pkcs12 = (MonoBtlsPkcs12 *)OPENSSL_malloc (sizeof (MonoBtlsPkcs12)); + if (pkcs12 == NULL) + return NULL; + + memset (pkcs12, 0, sizeof(MonoBtlsPkcs12)); + pkcs12->certs = sk_X509_new_null (); + pkcs12->references = 1; + return pkcs12; +} + +int +mono_btls_pkcs12_get_count (MonoBtlsPkcs12 *pkcs12) +{ + return (int)sk_X509_num (pkcs12->certs); +} + +X509 * +mono_btls_pkcs12_get_cert (MonoBtlsPkcs12 *pkcs12, int index) +{ + X509 *cert; + + if ((size_t)index >= sk_X509_num (pkcs12->certs)) + return NULL; + cert = sk_X509_value (pkcs12->certs, index); + if (cert) + X509_up_ref (cert); + return cert; +} + +STACK_OF(X509) * +mono_btls_pkcs12_get_certs (MonoBtlsPkcs12 *pkcs12) +{ + return pkcs12->certs; +} + +int +mono_btls_pkcs12_free (MonoBtlsPkcs12 *pkcs12) +{ + if (!CRYPTO_refcount_dec_and_test_zero (&pkcs12->references)) + return 0; + + sk_X509_pop_free (pkcs12->certs, X509_free); + OPENSSL_free (pkcs12); + return 1; +} + +MonoBtlsPkcs12 * +mono_btls_pkcs12_up_ref (MonoBtlsPkcs12 *pkcs12) +{ + CRYPTO_refcount_inc (&pkcs12->references); + return pkcs12; +} + +void +mono_btls_pkcs12_add_cert (MonoBtlsPkcs12 *pkcs12, X509 *x509) +{ + X509_up_ref (x509); + sk_X509_push (pkcs12->certs, x509); +} + +int +mono_btls_pkcs12_import (MonoBtlsPkcs12 *pkcs12, const void *data, int len, const void *password) +{ + CBS cbs; + CBS_init (&cbs, data, len); + return PKCS12_get_key_and_certs (&pkcs12->private_key, pkcs12->certs, &cbs, password); +} + +int +mono_btls_pkcs12_has_private_key (MonoBtlsPkcs12 *pkcs12) +{ + return pkcs12->private_key != NULL; +} + +EVP_PKEY * +mono_btls_pkcs12_get_private_key (MonoBtlsPkcs12 *pkcs12) +{ + if (!pkcs12->private_key) + return NULL; + return EVP_PKEY_up_ref (pkcs12->private_key); +} diff --git a/mono/btls/btls-pkcs12.h b/mono/btls/btls-pkcs12.h new file mode 100644 index 00000000000..20c4fd9c4e3 --- /dev/null +++ b/mono/btls/btls-pkcs12.h @@ -0,0 +1,46 @@ +// +// btls-pkcs12.h +// MonoBtls +// +// Created by Martin Baulig on 3/8/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_pkcs12__ +#define __btls__btls_pkcs12__ + +#include +#include +#include + +MonoBtlsPkcs12 * +mono_btls_pkcs12_new (void); + +int +mono_btls_pkcs12_get_count (MonoBtlsPkcs12 *pkcs12); + +X509 * +mono_btls_pkcs12_get_cert (MonoBtlsPkcs12 *pkcs12, int index); + +STACK_OF(X509) * +mono_btls_pkcs12_get_certs (MonoBtlsPkcs12 *pkcs12); + +int +mono_btls_pkcs12_free (MonoBtlsPkcs12 *pkcs12); + +MonoBtlsPkcs12 * +mono_btls_pkcs12_up_ref (MonoBtlsPkcs12 *pkcs12); + +void +mono_btls_pkcs12_add_cert (MonoBtlsPkcs12 *pkcs12, X509 *x509); + +int +mono_btls_pkcs12_import (MonoBtlsPkcs12 *pkcs12, const void *data, int len, const void *password); + +int +mono_btls_pkcs12_has_private_key (MonoBtlsPkcs12 *pkcs12); + +EVP_PKEY * +mono_btls_pkcs12_get_private_key (MonoBtlsPkcs12 *pkcs12); + +#endif /* __btls__btls_pkcs12__ */ diff --git a/mono/btls/btls-ssl-ctx.c b/mono/btls/btls-ssl-ctx.c new file mode 100644 index 00000000000..ddbb02f5517 --- /dev/null +++ b/mono/btls/btls-ssl-ctx.c @@ -0,0 +1,255 @@ +// +// btls-ssl-ctx.c +// MonoBtls +// +// Created by Martin Baulig on 4/11/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include + +struct MonoBtlsSslCtx { + CRYPTO_refcount_t references; + SSL_CTX *ctx; + BIO *bio; + BIO *debug_bio; + void *instance; + MonoBtlsVerifyFunc verify_func; + MonoBtlsSelectFunc select_func; +}; + +#define debug_print(ptr,message) \ +do { if (mono_btls_ssl_ctx_is_debug_enabled(ptr)) \ +mono_btls_ssl_ctx_debug_printf (ptr, "%s:%d:%s(): " message, __FILE__, __LINE__, \ + __func__); } while (0) + +#define debug_printf(ptr,fmt, ...) \ +do { if (mono_btls_ssl_ctx_is_debug_enabled(ptr)) \ +mono_btls_ssl_ctx_debug_printf (ptr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, \ + __func__, __VA_ARGS__); } while (0) + +void ssl_cipher_preference_list_free (struct ssl_cipher_preference_list_st *cipher_list); + +int +mono_btls_ssl_ctx_is_debug_enabled (MonoBtlsSslCtx *ctx) +{ + return ctx->debug_bio != NULL; +} + +int +mono_btls_ssl_ctx_debug_printf (MonoBtlsSslCtx *ctx, const char *format, ...) +{ + va_list args; + int ret; + + if (!ctx->debug_bio) + return 0; + + va_start (args, format); + ret = mono_btls_debug_printf (ctx->debug_bio, format, args); + va_end (args); + return ret; +} + +MonoBtlsSslCtx * +mono_btls_ssl_ctx_new (void) +{ + MonoBtlsSslCtx *ctx; + + ctx = OPENSSL_malloc (sizeof (MonoBtlsSslCtx)); + if (!ctx) + return NULL; + + memset (ctx, 0, sizeof (MonoBtlsSslCtx)); + ctx->references = 1; + ctx->ctx = SSL_CTX_new (TLS_method ()); + return ctx; +} + +MonoBtlsSslCtx * +mono_btls_ssl_ctx_up_ref (MonoBtlsSslCtx *ctx) +{ + CRYPTO_refcount_inc (&ctx->references); + return ctx; +} + +int +mono_btls_ssl_ctx_free (MonoBtlsSslCtx *ctx) +{ + if (!CRYPTO_refcount_dec_and_test_zero (&ctx->references)) + return 0; + SSL_CTX_free (ctx->ctx); + ctx->instance = NULL; + OPENSSL_free (ctx); + return 1; +} + +SSL_CTX * +mono_btls_ssl_ctx_get_ctx (MonoBtlsSslCtx *ctx) +{ + return ctx->ctx; +} + +void +mono_btls_ssl_ctx_set_debug_bio (MonoBtlsSslCtx *ctx, BIO *debug_bio) +{ + if (debug_bio) + ctx->debug_bio = BIO_up_ref(debug_bio); + else + ctx->debug_bio = NULL; +} + +void +mono_btls_ssl_ctx_initialize (MonoBtlsSslCtx *ctx, void *instance) +{ + ctx->instance = instance; +} + +static int +cert_verify_callback (X509_STORE_CTX *storeCtx, void *arg) +{ + MonoBtlsSslCtx *ptr = (MonoBtlsSslCtx*)arg; + int ret; + + debug_printf (ptr, "cert_verify_callback(): %p\n", ptr->verify_func); + ret = X509_verify_cert (storeCtx); + debug_printf (ptr, "cert_verify_callback() #1: %d\n", ret); + + if (ptr->verify_func) + ret = ptr->verify_func (ptr->instance, ret, storeCtx); + + return ret; +} + +void +mono_btls_ssl_ctx_set_cert_verify_callback (MonoBtlsSslCtx *ptr, MonoBtlsVerifyFunc func, int cert_required) +{ + int mode; + + ptr->verify_func = func; + SSL_CTX_set_cert_verify_callback (ptr->ctx, cert_verify_callback, ptr); + + mode = SSL_VERIFY_PEER; + if (cert_required) + mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + + SSL_CTX_set_verify (ptr->ctx, mode, NULL); +} + +static int +cert_select_callback (SSL *ssl, void *arg) +{ + MonoBtlsSslCtx *ptr = (MonoBtlsSslCtx*)arg; + int ret = 1; + + debug_printf (ptr, "cert_select_callback(): %p\n", ptr->select_func); + if (ptr->select_func) + ret = ptr->select_func (ptr->instance); + debug_printf (ptr, "cert_select_callback() #1: %d\n", ret); + + return ret; +} + +void +mono_btls_ssl_ctx_set_cert_select_callback (MonoBtlsSslCtx *ptr, MonoBtlsSelectFunc func) +{ + ptr->select_func = func; + SSL_CTX_set_cert_cb (ptr->ctx, cert_select_callback, ptr); +} + +X509_STORE * +mono_btls_ssl_ctx_peek_store (MonoBtlsSslCtx *ctx) +{ + return SSL_CTX_get_cert_store (ctx->ctx); +} + +void +mono_btls_ssl_ctx_set_min_version (MonoBtlsSslCtx *ctx, int version) +{ + SSL_CTX_set_min_version (ctx->ctx, version); +} + +void +mono_btls_ssl_ctx_set_max_version (MonoBtlsSslCtx *ctx, int version) +{ + SSL_CTX_set_max_version (ctx->ctx, version); +} + +int +mono_btls_ssl_ctx_is_cipher_supported (MonoBtlsSslCtx *ctx, uint16_t value) +{ + const SSL_CIPHER *cipher; + + cipher = SSL_get_cipher_by_value (value); + return cipher != NULL; +} + +int +mono_btls_ssl_ctx_set_ciphers (MonoBtlsSslCtx *ctx, int count, const uint16_t *data, + int allow_unsupported) +{ + STACK_OF(SSL_CIPHER) *ciphers = NULL; + struct ssl_cipher_preference_list_st *pref_list = NULL; + uint8_t *in_group_flags = NULL; + int i; + + ciphers = sk_SSL_CIPHER_new_null (); + if (!ciphers) + goto err; + + for (i = 0; i < count; i++) { + const SSL_CIPHER *cipher = SSL_get_cipher_by_value (data [i]); + if (!cipher) { + debug_printf (ctx, "mono_btls_ssl_ctx_set_ciphers(): unknown cipher %02x", data [i]); + if (!allow_unsupported) + goto err; + continue; + } + if (!sk_SSL_CIPHER_push (ciphers, cipher)) + goto err; + } + + pref_list = OPENSSL_malloc (sizeof (struct ssl_cipher_preference_list_st)); + if (!pref_list) + goto err; + + memset (pref_list, 0, sizeof (struct ssl_cipher_preference_list_st)); + pref_list->ciphers = sk_SSL_CIPHER_dup (ciphers); + if (!pref_list->ciphers) + goto err; + pref_list->in_group_flags = OPENSSL_malloc (sk_SSL_CIPHER_num (ciphers)); + if (!pref_list->in_group_flags) + goto err; + + if (ctx->ctx->cipher_list) + ssl_cipher_preference_list_free (ctx->ctx->cipher_list); + if (ctx->ctx->cipher_list_by_id) + sk_SSL_CIPHER_free (ctx->ctx->cipher_list_by_id); + if (ctx->ctx->cipher_list_tls10) { + ssl_cipher_preference_list_free (ctx->ctx->cipher_list_tls10); + ctx->ctx->cipher_list_tls10 = NULL; + } + if (ctx->ctx->cipher_list_tls11) { + ssl_cipher_preference_list_free (ctx->ctx->cipher_list_tls11); + ctx->ctx->cipher_list_tls11 = NULL; + } + + ctx->ctx->cipher_list = pref_list; + ctx->ctx->cipher_list_by_id = ciphers; + + return (int)sk_SSL_CIPHER_num (ciphers); + +err: + sk_SSL_CIPHER_free (ciphers); + OPENSSL_free (pref_list); + OPENSSL_free (in_group_flags); + return 0; +} + +int +mono_btls_ssl_ctx_set_verify_param (MonoBtlsSslCtx *ctx, const MonoBtlsX509VerifyParam *param) +{ + return SSL_CTX_set1_param (ctx->ctx, mono_btls_x509_verify_param_peek_param (param)); +} + diff --git a/mono/btls/btls-ssl-ctx.h b/mono/btls/btls-ssl-ctx.h new file mode 100644 index 00000000000..09541927093 --- /dev/null +++ b/mono/btls/btls-ssl-ctx.h @@ -0,0 +1,84 @@ +// +// btls-ssl-ctx.h +// MonoBtls +// +// Created by Martin Baulig on 4/11/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls_ssl_ctx__btls_ssl_ctx__ +#define __btls_ssl_ctx__btls_ssl_ctx__ + +#include +#include +#include +#include +#include + +typedef struct MonoBtlsBio MonoBtlsBio; +typedef struct MonoBtlsX509Chain MonoBtlsX509Chain; +typedef struct MonoBtlsX509Crl MonoBtlsX509Crl; +typedef struct MonoBtlsX509Lookup MonoBtlsX509Lookup; +typedef struct MonoBtlsX509LookupMono MonoBtlsX509LookupMono; +typedef struct MonoBtlsX509Name MonoBtlsX509Name; +typedef struct MonoBtlsX509Store MonoBtlsX509Store; +typedef struct MonoBtlsX509StoreCtx MonoBtlsX509StoreCtx; +typedef struct MonoBtlsX509Revoked MonoBtlsX509Revoked; +typedef struct MonoBtlsX509VerifyParam MonoBtlsX509VerifyParam; +typedef struct MonoBtlsPkcs12 MonoBtlsPkcs12; +typedef struct MonoBtlsSsl MonoBtlsSsl; +typedef struct MonoBtlsSslCtx MonoBtlsSslCtx; + +typedef int (* MonoBtlsVerifyFunc) (void *instance, int preverify_ok, X509_STORE_CTX *ctx); +typedef int (* MonoBtlsSelectFunc) (void *instance); + +MonoBtlsSslCtx * +mono_btls_ssl_ctx_new (void); + +MonoBtlsSslCtx * +mono_btls_ssl_ctx_up_ref (MonoBtlsSslCtx *ctx); + +int +mono_btls_ssl_ctx_free (MonoBtlsSslCtx *ctx); + +void +mono_btls_ssl_ctx_initialize (MonoBtlsSslCtx *ctx, void *instance); + +SSL_CTX * +mono_btls_ssl_ctx_get_ctx (MonoBtlsSslCtx *ctx); + +int +mono_btls_ssl_ctx_debug_printf (MonoBtlsSslCtx *ctx, const char *format, ...); + +int +mono_btls_ssl_ctx_is_debug_enabled (MonoBtlsSslCtx *ctx); + +void +mono_btls_ssl_ctx_set_cert_verify_callback (MonoBtlsSslCtx *ptr, MonoBtlsVerifyFunc func, int cert_required); + +void +mono_btls_ssl_ctx_set_cert_select_callback (MonoBtlsSslCtx *ptr, MonoBtlsSelectFunc func); + +void +mono_btls_ssl_ctx_set_debug_bio (MonoBtlsSslCtx *ctx, BIO *debug_bio); + +X509_STORE * +mono_btls_ssl_ctx_peek_store (MonoBtlsSslCtx *ctx); + +void +mono_btls_ssl_ctx_set_min_version (MonoBtlsSslCtx *ctx, int version); + +void +mono_btls_ssl_ctx_set_max_version (MonoBtlsSslCtx *ctx, int version); + +int +mono_btls_ssl_ctx_is_cipher_supported (MonoBtlsSslCtx *ctx, uint16_t value); + +int +mono_btls_ssl_ctx_set_ciphers (MonoBtlsSslCtx *ctx, int count, const uint16_t *data, + int allow_unsupported); + +int +mono_btls_ssl_ctx_set_verify_param (MonoBtlsSslCtx *ctx, const MonoBtlsX509VerifyParam *param); + +#endif /* __btls_ssl_ctx__btls_ssl_ctx__ */ diff --git a/mono/btls/btls-ssl.c b/mono/btls/btls-ssl.c new file mode 100644 index 00000000000..ddb88d6710a --- /dev/null +++ b/mono/btls/btls-ssl.c @@ -0,0 +1,229 @@ +// +// btls-ssl.c +// MonoBtls +// +// Created by Martin Baulig on 14/11/15. +// Copyright (c) 2015 Xamarin. All rights reserved. +// + +#include +#include + +struct MonoBtlsSsl { + MonoBtlsSslCtx *ctx; + SSL *ssl; +}; + +#define debug_print(ptr,message) \ +do { if (mono_btls_ssl_ctx_is_debug_enabled(ptr->ctx)) \ +mono_btls_ssl_ctx_debug_printf (ptr->ctx, "%s:%d:%s(): " message, __FILE__, __LINE__, \ +__func__); } while (0) + +#define debug_printf(ptr,fmt, ...) \ +do { if (mono_btls_ssl_ctx_is_debug_enabled(ptr->ctx)) \ +mono_btls_ssl_ctx_debug_printf (ptr->ctx, "%s:%d:%s(): " fmt, __FILE__, __LINE__, \ +__func__, __VA_ARGS__); } while (0) + +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list (SSL *s, const CBS *cbs); + +MonoBtlsSsl * +mono_btls_ssl_new (MonoBtlsSslCtx *ctx) +{ + MonoBtlsSsl *ptr; + + ptr = calloc (1, sizeof (MonoBtlsSsl)); + + ptr->ctx = mono_btls_ssl_ctx_up_ref (ctx); + ptr->ssl = SSL_new (mono_btls_ssl_ctx_get_ctx (ptr->ctx)); + + SSL_set_options (ptr->ssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + + return ptr; +} + +void +mono_btls_ssl_destroy (MonoBtlsSsl *ptr) +{ + mono_btls_ssl_close (ptr); + if (ptr->ssl) { + SSL_free (ptr->ssl); + ptr->ssl = NULL; + } + if (ptr->ctx) { + mono_btls_ssl_ctx_free (ptr->ctx); + ptr->ctx = NULL; + } + free (ptr); +} + +void +mono_btls_ssl_close (MonoBtlsSsl *ptr) +{ + ; +} + +void +mono_btls_ssl_set_bio (MonoBtlsSsl *ptr, BIO *bio) +{ + BIO_up_ref (bio); + SSL_set_bio (ptr->ssl, bio, bio); +} + +void +mono_btls_ssl_print_errors_cb (ERR_print_errors_callback_t callback, void *ctx) +{ + ERR_print_errors_cb (callback, ctx); +} + +int +mono_btls_ssl_use_certificate (MonoBtlsSsl *ptr, X509 *x509) +{ + return SSL_use_certificate (ptr->ssl, x509); +} + +int +mono_btls_ssl_use_private_key (MonoBtlsSsl *ptr, EVP_PKEY *key) +{ + return SSL_use_PrivateKey (ptr->ssl, key); +} + +int +mono_btls_ssl_add_chain_certificate (MonoBtlsSsl *ptr, X509 *x509) +{ + return SSL_add1_chain_cert (ptr->ssl, x509); +} + +int +mono_btls_ssl_accept (MonoBtlsSsl *ptr) +{ + return SSL_accept (ptr->ssl); +} + +int +mono_btls_ssl_connect (MonoBtlsSsl *ptr) +{ + return SSL_connect (ptr->ssl); +} + +int +mono_btls_ssl_handshake (MonoBtlsSsl *ptr) +{ + return SSL_do_handshake (ptr->ssl); +} + +int +mono_btls_ssl_read (MonoBtlsSsl *ptr, void *buf, int count) +{ + return SSL_read (ptr->ssl, buf, count); +} + +int +mono_btls_ssl_write (MonoBtlsSsl *ptr, void *buf, int count) +{ + return SSL_write (ptr->ssl, buf, count); +} + +int +mono_btls_ssl_get_version (MonoBtlsSsl *ptr) +{ + return SSL_version (ptr->ssl); +} + +void +mono_btls_ssl_set_min_version (MonoBtlsSsl *ptr, int version) +{ + SSL_set_min_version (ptr->ssl, version); +} + +void +mono_btls_ssl_set_max_version (MonoBtlsSsl *ptr, int version) +{ + SSL_set_max_version (ptr->ssl, version); +} + +int +mono_btls_ssl_get_cipher (MonoBtlsSsl *ptr) +{ + const SSL_CIPHER *cipher; + + cipher = SSL_get_current_cipher (ptr->ssl); + if (!cipher) + return 0; + return (uint16_t)SSL_CIPHER_get_id (cipher); +} + +int +mono_btls_ssl_set_cipher_list (MonoBtlsSsl *ptr, const char *str) +{ + return SSL_set_cipher_list(ptr->ssl, str); +} + +int +mono_btls_ssl_get_ciphers (MonoBtlsSsl *ptr, uint16_t **data) +{ + STACK_OF(SSL_CIPHER) *ciphers; + int count, i; + + *data = NULL; + + ciphers = SSL_get_ciphers (ptr->ssl); + if (!ciphers) + return 0; + + count = (int)sk_SSL_CIPHER_num (ciphers); + + *data = OPENSSL_malloc (2 * count); + if (!*data) + return 0; + + for (i = 0; i < count; i++) { + const SSL_CIPHER *cipher = sk_SSL_CIPHER_value (ciphers, i); + (*data) [i] = (uint16_t) SSL_CIPHER_get_id (cipher); + } + + return count; +} + +X509 * +mono_btls_ssl_get_peer_certificate (MonoBtlsSsl *ptr) +{ + return SSL_get_peer_certificate (ptr->ssl); +} + +int +mono_btls_ssl_get_error (MonoBtlsSsl *ptr, int ret_code) +{ + return SSL_get_error (ptr->ssl, ret_code); +} + +int +mono_btls_ssl_set_verify_param (MonoBtlsSsl *ptr, const MonoBtlsX509VerifyParam *param) +{ + return SSL_set1_param (ptr->ssl, mono_btls_x509_verify_param_peek_param (param)); +} + +void +mono_btls_ssl_test (MonoBtlsSsl *ptr) +{ + SSL_SESSION *session; + const char *version; + const SSL_CIPHER *cipher; + int test; + +// SSL_get_ciphers(<#const SSL *ssl#>) + + test = SSL_version (ptr->ssl); + debug_printf(ptr, "TEST: %d\n", test); + session = SSL_get_session(ptr->ssl); + if (session) { + version = SSL_SESSION_get_version(session); + debug_printf (ptr, "SESSION: %p - %s\n", session, version); + } + + cipher = SSL_get_current_cipher (ptr->ssl); + if (cipher) { + test = SSL_CIPHER_get_id (cipher); + version = SSL_CIPHER_get_name (cipher); + debug_printf (ptr, "CIPHER: %p - %x:%s\n", cipher, test, version); + } +} diff --git a/mono/btls/btls-ssl.h b/mono/btls/btls-ssl.h new file mode 100644 index 00000000000..1557995b22d --- /dev/null +++ b/mono/btls/btls-ssl.h @@ -0,0 +1,83 @@ +// +// btls-ssl.h +// MonoBtls +// +// Created by Martin Baulig on 14/11/15. +// Copyright (c) 2015 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_ssl__ +#define __btls__btls_ssl__ + +#include + +MonoBtlsSsl * +mono_btls_ssl_new (MonoBtlsSslCtx *ctx); + +int +mono_btls_ssl_use_certificate (MonoBtlsSsl *ptr, X509 *x509); + +int +mono_btls_ssl_use_private_key (MonoBtlsSsl *ptr, EVP_PKEY *key); + +int +mono_btls_ssl_add_chain_certificate (MonoBtlsSsl *ptr, X509 *x509); + +int +mono_btls_ssl_accept (MonoBtlsSsl *ptr); + +int +mono_btls_ssl_connect (MonoBtlsSsl *ptr); + +int +mono_btls_ssl_handshake (MonoBtlsSsl *ptr); + +void +mono_btls_ssl_print_errors_cb (ERR_print_errors_callback_t callback, void *ctx); + +void +mono_btls_ssl_set_bio (MonoBtlsSsl *ptr, BIO *bio); + +int +mono_btls_ssl_read (MonoBtlsSsl *ptr, void *buf, int count); + +int +mono_btls_ssl_write (MonoBtlsSsl *ptr, void *buf, int count); + +int +mono_btls_ssl_get_version (MonoBtlsSsl *ptr); + +void +mono_btls_ssl_set_min_version (MonoBtlsSsl *ptr, int version); + +void +mono_btls_ssl_set_max_version (MonoBtlsSsl *ptr, int version); + +int +mono_btls_ssl_get_cipher (MonoBtlsSsl *ptr); + +int +mono_btls_ssl_set_cipher_list (MonoBtlsSsl *ptr, const char *str); + +int +mono_btls_ssl_get_ciphers (MonoBtlsSsl *ptr, uint16_t **data); + +X509 * +mono_btls_ssl_get_peer_certificate (MonoBtlsSsl *ptr); + +void +mono_btls_ssl_close (MonoBtlsSsl *ptr); + +int +mono_btls_ssl_get_error (MonoBtlsSsl *ptr, int ret_code); + +int +mono_btls_ssl_set_verify_param (MonoBtlsSsl *ptr, const MonoBtlsX509VerifyParam *param); + +void +mono_btls_ssl_destroy (MonoBtlsSsl *ptr); + +void +mono_btls_ssl_test (MonoBtlsSsl *ptr); + +#endif /* defined(__btls__btls_ssl__) */ diff --git a/mono/btls/btls-util.c b/mono/btls/btls-util.c new file mode 100644 index 00000000000..d28763a0fd1 --- /dev/null +++ b/mono/btls/btls-util.c @@ -0,0 +1,76 @@ +// +// btls-util.c +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include +#include + +#if defined(__ANDROID__) && !defined(__LP64__) +#include +extern time_t timegm (struct tm* const t); +#endif + +extern int asn1_generalizedtime_to_tm (struct tm *tm, const ASN1_GENERALIZEDTIME *d); + +void +mono_btls_free (void *data) +{ + OPENSSL_free (data); +} + +long +mono_btls_util_asn1_time_to_ticks (ASN1_TIME *time) +{ + ASN1_GENERALIZEDTIME *gtime; + struct tm tm; + time_t epoch; + + gtime = ASN1_TIME_to_generalizedtime (time, NULL); + asn1_generalizedtime_to_tm (&tm, gtime); + ASN1_GENERALIZEDTIME_free (gtime); + epoch = timegm(&tm); + + return epoch; +} + +// Copied from crypto/bio/printf.c, takes va_list +int +mono_btls_debug_printf (BIO *bio, const char *format, va_list args) +{ + char buf[256], *out, out_malloced = 0; + int out_len, ret; + + out_len = vsnprintf (buf, sizeof(buf), format, args); + if (out_len < 0) { + return -1; + } + + if ((size_t) out_len >= sizeof(buf)) { + const int requested_len = out_len; + /* The output was truncated. Note that vsnprintf's return value + * does not include a trailing NUL, but the buffer must be sized + * for it. */ + out = OPENSSL_malloc (requested_len + 1); + out_malloced = 1; + if (out == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return -1; + } + out_len = vsnprintf (out, requested_len + 1, format, args); + assert(out_len == requested_len); + } else { + out = buf; + } + + ret = BIO_write(bio, out, out_len); + if (out_malloced) { + OPENSSL_free(out); + } + + return ret; +} diff --git a/mono/btls/btls-util.h b/mono/btls/btls-util.h new file mode 100644 index 00000000000..a77bfcd61d0 --- /dev/null +++ b/mono/btls/btls-util.h @@ -0,0 +1,29 @@ +// +// btls-util.h +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_util__ +#define __btls__btls_util__ + +#include +#include +#include +#include + +void +mono_btls_free (void *data); + +long +mono_btls_util_asn1_time_to_ticks (ASN1_TIME *time); + +int +mono_btls_debug_printf (BIO *bio, const char *format, va_list args); + +OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count); +OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count); + +#endif /* __btls__btls_util__ */ diff --git a/mono/btls/btls-x509-chain.c b/mono/btls/btls-x509-chain.c new file mode 100644 index 00000000000..0584791dedf --- /dev/null +++ b/mono/btls/btls-x509-chain.c @@ -0,0 +1,96 @@ +// +// btls-x509-chain.c +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include + +struct MonoBtlsX509Chain { + STACK_OF(X509) *certs; + CRYPTO_refcount_t references; +}; + +MonoBtlsX509Chain * +mono_btls_x509_chain_new (void) +{ + MonoBtlsX509Chain *chain = (MonoBtlsX509Chain *)OPENSSL_malloc (sizeof (MonoBtlsX509Chain)); + if (chain == NULL) + return NULL; + + memset(chain, 0, sizeof(MonoBtlsX509Chain)); + chain->certs = sk_X509_new_null (); + chain->references = 1; + return chain; +} + +MonoBtlsX509Chain * +mono_btls_x509_chain_from_certs (STACK_OF(X509) *certs) +{ + MonoBtlsX509Chain *chain = (MonoBtlsX509Chain *)OPENSSL_malloc (sizeof (MonoBtlsX509Chain)); + if (chain == NULL) + return NULL; + + memset(chain, 0, sizeof(MonoBtlsX509Chain)); + chain->certs = X509_chain_up_ref(certs); + chain->references = 1; + return chain; +} + +STACK_OF(X509) * +mono_btls_x509_chain_peek_certs (MonoBtlsX509Chain *chain) +{ + return chain->certs; +} + +int +mono_btls_x509_chain_get_count (MonoBtlsX509Chain *chain) +{ + return (int)sk_X509_num(chain->certs); +} + +X509 * +mono_btls_x509_chain_get_cert (MonoBtlsX509Chain *chain, int index) +{ + X509 *cert; + + if ((size_t)index >= sk_X509_num(chain->certs)) + return NULL; + cert = sk_X509_value(chain->certs, index); + if (cert) + X509_up_ref(cert); + return cert; +} + +STACK_OF(X509) * +mono_btls_x509_chain_get_certs (MonoBtlsX509Chain *chain) +{ + return chain->certs; +} + +int +mono_btls_x509_chain_free (MonoBtlsX509Chain *chain) +{ + if (!CRYPTO_refcount_dec_and_test_zero(&chain->references)) + return 0; + + sk_X509_pop_free(chain->certs, X509_free); + OPENSSL_free (chain); + return 1; +} + +MonoBtlsX509Chain * +mono_btls_x509_chain_up_ref (MonoBtlsX509Chain *chain) +{ + CRYPTO_refcount_inc(&chain->references); + return chain; +} + +void +mono_btls_x509_chain_add_cert (MonoBtlsX509Chain *chain, X509 *x509) +{ + X509_up_ref(x509); + sk_X509_push(chain->certs, x509); +} diff --git a/mono/btls/btls-x509-chain.h b/mono/btls/btls-x509-chain.h new file mode 100644 index 00000000000..68ef5773ba8 --- /dev/null +++ b/mono/btls/btls-x509-chain.h @@ -0,0 +1,41 @@ +// +// btls-x509-chain.h +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_chain__ +#define __btls__btls_x509_chain__ + +#include +#include +#include + +MonoBtlsX509Chain * +mono_btls_x509_chain_new (void); + +MonoBtlsX509Chain * +mono_btls_x509_chain_from_certs (STACK_OF(X509) *certs); + +STACK_OF(X509) * +mono_btls_x509_chain_peek_certs (MonoBtlsX509Chain *chain); + +int +mono_btls_x509_chain_get_count (MonoBtlsX509Chain *chain); + +X509 * +mono_btls_x509_chain_get_cert (MonoBtlsX509Chain *chain, int index); + +MonoBtlsX509Chain * +mono_btls_x509_chain_up_ref (MonoBtlsX509Chain *chain); + +int +mono_btls_x509_chain_free (MonoBtlsX509Chain *chain); + +void +mono_btls_x509_chain_add_cert (MonoBtlsX509Chain *chain, X509 *x509); + +#endif /* defined(__btls__btls_x509_chain__) */ + diff --git a/mono/btls/btls-x509-crl.c b/mono/btls/btls-x509-crl.c new file mode 100644 index 00000000000..ccd3e287314 --- /dev/null +++ b/mono/btls/btls-x509-crl.c @@ -0,0 +1,150 @@ +// +// btls-x509-crl.c +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include + +struct MonoBtlsX509Crl { + X509_CRL *crl; + CRYPTO_refcount_t references; +}; + +MonoBtlsX509Crl * +mono_btls_x509_crl_from_data (const void *buf, int len, MonoBtlsX509Format format) +{ + MonoBtlsX509Crl *crl; + BIO *bio; + + crl = OPENSSL_malloc (sizeof (MonoBtlsX509Crl)); + memset (crl, 0, sizeof(MonoBtlsX509Crl)); + crl->references = 1; + + bio = BIO_new_mem_buf ((void *)buf, len); + switch (format) { + case MONO_BTLS_X509_FORMAT_DER: + crl->crl = d2i_X509_CRL_bio (bio, NULL); + break; + case MONO_BTLS_X509_FORMAT_PEM: + crl->crl = PEM_read_bio_X509_CRL (bio, NULL, NULL, NULL); + break; + } + BIO_free (bio); + + if (!crl->crl) { + OPENSSL_free (crl); + return NULL; + } + + return crl; +} + +MonoBtlsX509Crl * +mono_btls_x509_crl_ref (MonoBtlsX509Crl *crl) +{ + CRYPTO_refcount_inc (&crl->references); + return crl; +} + +int +mono_btls_x509_crl_free (MonoBtlsX509Crl *crl) +{ + if (!CRYPTO_refcount_dec_and_test_zero (&crl->references)) + return 0; + + X509_CRL_free (crl->crl); + OPENSSL_free (crl); + return 1; +} + +MonoBtlsX509Revoked * +mono_btls_x509_crl_get_by_cert (MonoBtlsX509Crl *crl, X509 *x509) +{ + X509_REVOKED *revoked; + int ret; + + revoked = NULL; + ret = X509_CRL_get0_by_cert (crl->crl, &revoked, x509); + fprintf (stderr, "mono_btls_x509_crl_get_by_cert: %d - %p\n", ret, revoked); + + if (!ret || !revoked) + return NULL; + + return mono_btls_x509_revoked_new (crl, revoked); +} + +MonoBtlsX509Revoked * +mono_btls_x509_crl_get_by_serial (MonoBtlsX509Crl *crl, void *serial, int len) +{ + ASN1_INTEGER si; + X509_REVOKED *revoked; + int ret; + + si.type = V_ASN1_INTEGER; + si.length = len; + si.data = serial; + + revoked = NULL; + ret = X509_CRL_get0_by_serial (crl->crl, &revoked, &si); + fprintf (stderr, "mono_btls_x509_crl_get_by_serial: %d - %p\n", ret, revoked); + + if (!ret || !revoked) + return NULL; + + return mono_btls_x509_revoked_new (crl, revoked); +} + +int +mono_btls_x509_crl_get_revoked_count (MonoBtlsX509Crl *crl) +{ + STACK_OF(X509_REVOKED) *stack; + + stack = X509_CRL_get_REVOKED (crl->crl); + return (int)sk_X509_REVOKED_num (stack); +} + +MonoBtlsX509Revoked * +mono_btls_x509_crl_get_revoked (MonoBtlsX509Crl *crl, int index) +{ + STACK_OF(X509_REVOKED) *stack; + X509_REVOKED *revoked; + + stack = X509_CRL_get_REVOKED (crl->crl); + if ((size_t)index >= sk_X509_REVOKED_num (stack)) + return NULL; + + revoked = sk_X509_REVOKED_value (stack, index); + if (!revoked) + return NULL; + + return mono_btls_x509_revoked_new (crl, revoked); +} + +long +mono_btls_x509_crl_get_last_update (MonoBtlsX509Crl *crl) +{ + return mono_btls_util_asn1_time_to_ticks (X509_CRL_get_lastUpdate (crl->crl)); +} + +long +mono_btls_x509_crl_get_next_update (MonoBtlsX509Crl *crl) +{ + return mono_btls_util_asn1_time_to_ticks (X509_CRL_get_nextUpdate (crl->crl)); +} + +long +mono_btls_x509_crl_get_version (MonoBtlsX509Crl *crl) +{ + return X509_CRL_get_version (crl->crl); +} + +MonoBtlsX509Name * +mono_btls_x509_crl_get_issuer (MonoBtlsX509Crl *crl) +{ + return mono_btls_x509_name_copy (X509_CRL_get_issuer (crl->crl)); +} + diff --git a/mono/btls/btls-x509-crl.h b/mono/btls/btls-x509-crl.h new file mode 100644 index 00000000000..0813fe5436a --- /dev/null +++ b/mono/btls/btls-x509-crl.h @@ -0,0 +1,49 @@ +// +// btls-x509-crl.h +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_crl__ +#define __btls__btls_x509_crl__ + +#include +#include +#include + +MonoBtlsX509Crl * +mono_btls_x509_crl_from_data (const void *buf, int len, MonoBtlsX509Format format); + +MonoBtlsX509Crl * +mono_btls_x509_crl_ref (MonoBtlsX509Crl *crl); + +int +mono_btls_x509_crl_free (MonoBtlsX509Crl *crl); + +MonoBtlsX509Revoked * +mono_btls_x509_crl_get_by_cert (MonoBtlsX509Crl *crl, X509 *x509); + +MonoBtlsX509Revoked * +mono_btls_x509_crl_get_by_serial (MonoBtlsX509Crl *crl, void *serial, int len); + +int +mono_btls_x509_crl_get_revoked_count (MonoBtlsX509Crl *crl); + +MonoBtlsX509Revoked * +mono_btls_x509_crl_get_revoked (MonoBtlsX509Crl *crl, int index); + +long +mono_btls_x509_crl_get_last_update (MonoBtlsX509Crl *crl); + +long +mono_btls_x509_crl_get_next_update (MonoBtlsX509Crl *crl); + +long +mono_btls_x509_crl_get_version (MonoBtlsX509Crl *crl); + +MonoBtlsX509Name * +mono_btls_x509_crl_get_issuer (MonoBtlsX509Crl *crl); + +#endif /* __btls__btls_x509_crl__ */ diff --git a/mono/btls/btls-x509-lookup-mono.c b/mono/btls/btls-x509-lookup-mono.c new file mode 100644 index 00000000000..cce73689469 --- /dev/null +++ b/mono/btls/btls-x509-lookup-mono.c @@ -0,0 +1,228 @@ +// +// btls-x509-lookup-mono.c +// MonoBtls +// +// Created by Martin Baulig on 3/6/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include +#include + +// random high number +#define MONO_BTLS_X509_L_MONO_ADD 36292 + +typedef struct MonoLookupNode MonoLookupNode; +struct MonoLookupNode { + MonoBtlsX509LookupMono *mono; + MonoLookupNode *next; +}; + +typedef struct { + MonoLookupNode *nodes; +} MonoLookup; + +struct MonoBtlsX509LookupMono { + const void *instance; + MonoBtlsX509LookupMono_BySubject by_subject_func; + MonoLookup *lookup; +}; + +MonoBtlsX509LookupMono * +mono_btls_x509_lookup_mono_new (void) +{ + MonoBtlsX509LookupMono *mono; + + mono = OPENSSL_malloc (sizeof (MonoBtlsX509LookupMono)); + if (!mono) + return NULL; + + memset (mono, 0, sizeof (MonoBtlsX509LookupMono)); + return mono; +} + +void +mono_btls_x509_lookup_mono_init (MonoBtlsX509LookupMono *mono, const void *instance, + MonoBtlsX509LookupMono_BySubject by_subject_func) +{ + mono->instance = instance; + mono->by_subject_func = by_subject_func; +} + +static int +mono_lookup_install (MonoLookup *lookup, MonoBtlsX509LookupMono *mono) +{ + MonoLookupNode *node; + + node = OPENSSL_malloc (sizeof (MonoLookupNode)); + if (!node) + return 0; + + memset (node, 0, sizeof (MonoLookupNode)); + mono->lookup = lookup; + node->mono = mono; + node->next = lookup->nodes; + lookup->nodes = node; + return 1; +} + +static int +mono_lookup_uninstall (MonoBtlsX509LookupMono *mono) +{ + MonoLookupNode **ptr; + + if (!mono->lookup) + return 0; + + for (ptr = &mono->lookup->nodes; *ptr; ptr = &(*ptr)->next) { + if ((*ptr)->mono == mono) { + *ptr = (*ptr)->next; + return 1; + } + } + + return 0; +} + +int +mono_btls_x509_lookup_mono_free (MonoBtlsX509LookupMono *mono) +{ + mono->instance = NULL; + mono->by_subject_func = NULL; + + if (mono->lookup) { + if (!mono_lookup_uninstall (mono)) + return 0; + } + + mono->lookup = NULL; + + OPENSSL_free (mono); + return 1; +} + +static int +mono_lookup_ctrl (X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret) +{ + MonoLookup *lookup = (MonoLookup*)ctx->method_data; + MonoBtlsX509LookupMono *mono = (MonoBtlsX509LookupMono*)argp; + + if (!lookup || cmd != MONO_BTLS_X509_L_MONO_ADD) + return 0; + if (!mono || mono->lookup) + return 0; + + return mono_lookup_install (lookup, mono); +} + +static int +mono_lookup_new (X509_LOOKUP *ctx) +{ + MonoLookup *data; + + data = OPENSSL_malloc (sizeof (MonoLookup)); + if (!data) + return 0; + + memset (data, 0, sizeof (MonoLookup)); + ctx->method_data = (void *)data; + return 1; +} + +static void +mono_lookup_free (X509_LOOKUP *ctx) +{ + MonoLookup *lookup; + MonoLookupNode *ptr; + + lookup = (MonoLookup *)ctx->method_data; + ctx->method_data = NULL; + if (!lookup) + return; + + ptr = lookup->nodes; + lookup->nodes = NULL; + + while (ptr) { + MonoLookupNode *node = ptr; + ptr = ptr->next; + + if (node->mono) + node->mono->lookup = NULL; + node->mono = NULL; + node->next = NULL; + OPENSSL_free (node); + } + + OPENSSL_free (lookup); +} + +static int +mono_lookup_get_by_subject (X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *obj_ret) +{ + MonoLookup *lookup; + MonoBtlsX509Name *name_obj; + MonoLookupNode *node; + X509 *x509 = NULL; + int ret = 0; + + lookup = (MonoLookup *)ctx->method_data; + + if (!lookup || !lookup->nodes) + return 0; + if (type != X509_LU_X509) + return 0; + + name_obj = mono_btls_x509_name_from_name (name); + x509 = NULL; + + for (node = lookup->nodes; node; node = node->next) { + if (!node->mono || !node->mono->by_subject_func) + continue; + ret = (* node->mono->by_subject_func) (node->mono->instance, name_obj, &x509); + if (ret) + break; + } + + mono_btls_x509_name_free (name_obj); + + if (!ret) { + if (x509) + X509_free(x509); + return 0; + } + + obj_ret->type = X509_LU_X509; + obj_ret->data.x509 = x509; + return 1; +} + +static X509_LOOKUP_METHOD mono_lookup_method = { + "Mono lookup method", + mono_lookup_new, /* new */ + mono_lookup_free, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + mono_lookup_ctrl, /* ctrl */ + mono_lookup_get_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD * +mono_btls_x509_lookup_mono_method (void) +{ + return &mono_lookup_method; +} + +int +mono_btls_x509_lookup_add_mono (MonoBtlsX509Lookup *lookup, MonoBtlsX509LookupMono *mono) +{ + if (mono_btls_x509_lookup_get_type (lookup) != MONO_BTLS_X509_LOOKUP_TYPE_MONO) + return 0; + return X509_LOOKUP_ctrl (mono_btls_x509_lookup_peek_lookup (lookup), + MONO_BTLS_X509_L_MONO_ADD, + (void*)mono, 0, NULL); +} diff --git a/mono/btls/btls-x509-lookup-mono.h b/mono/btls/btls-x509-lookup-mono.h new file mode 100644 index 00000000000..06df552c0f3 --- /dev/null +++ b/mono/btls/btls-x509-lookup-mono.h @@ -0,0 +1,36 @@ +// +// btls-x509-lookup-mono.h +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_lookup_mono__ +#define __btls__btls_x509_lookup_mono__ + +#include +#include +#include +#include + +typedef int (* MonoBtlsX509LookupMono_BySubject) (const void *instance, MonoBtlsX509Name *name, X509 **ret); + +MonoBtlsX509LookupMono * +mono_btls_x509_lookup_mono_new (void); + +int +mono_btls_x509_lookup_mono_free (MonoBtlsX509LookupMono *mono); + +void +mono_btls_x509_lookup_mono_init (MonoBtlsX509LookupMono *mono, const void *instance, + MonoBtlsX509LookupMono_BySubject by_subject_func); + +int +mono_btls_x509_lookup_add_mono (MonoBtlsX509Lookup *lookup, MonoBtlsX509LookupMono *mono); + +X509_LOOKUP_METHOD * +mono_btls_x509_lookup_mono_method (void); + +#endif /* defined(__btls__btls_x509_lookup_mono__) */ + diff --git a/mono/btls/btls-x509-lookup.c b/mono/btls/btls-x509-lookup.c new file mode 100644 index 00000000000..1cfc1741a36 --- /dev/null +++ b/mono/btls/btls-x509-lookup.c @@ -0,0 +1,160 @@ +// +// btls-x509-lookup.c +// MonoBtls +// +// Created by Martin Baulig on 3/6/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include + +struct MonoBtlsX509Lookup { + MonoBtlsX509LookupType type; + X509_LOOKUP *lookup; + int owns_lookup; + MonoBtlsX509Store *store; + CRYPTO_refcount_t references; +}; + +static X509_LOOKUP_METHOD * +get_lookup_method (MonoBtlsX509LookupType type) +{ + switch (type) { + case MONO_BTLS_X509_LOOKUP_TYPE_FILE: + return X509_LOOKUP_file (); + case MONO_BTLS_X509_LOOKUP_TYPE_HASH_DIR: + return X509_LOOKUP_hash_dir (); + case MONO_BTLS_X509_LOOKUP_TYPE_MONO: + return mono_btls_x509_lookup_mono_method (); + default: + return NULL; + } +} + +MonoBtlsX509Lookup * +mono_btls_x509_lookup_new (MonoBtlsX509Store *store, MonoBtlsX509LookupType type) +{ + MonoBtlsX509Lookup *lookup; + X509_LOOKUP *store_lookup; + X509_LOOKUP_METHOD *method; + + method = get_lookup_method (type); + if (!method) + return NULL; + + lookup = OPENSSL_malloc (sizeof(MonoBtlsX509Lookup)); + if (!lookup) + return NULL; + + store_lookup = X509_STORE_add_lookup (mono_btls_x509_store_peek_store (store), method); + if (!store_lookup) + return NULL; + + memset (lookup, 0, sizeof(MonoBtlsX509Lookup)); + // The X509_STORE owns the X509_LOOKUP. + lookup->store = mono_btls_x509_store_up_ref (store); + lookup->lookup = store_lookup; + lookup->owns_lookup = 0; + lookup->references = 1; + lookup->type = type; + return lookup; +} + +int +mono_btls_x509_lookup_load_file (MonoBtlsX509Lookup *lookup, const char *file, MonoBtlsX509FileType type) +{ + return X509_LOOKUP_load_file (lookup->lookup, file, type); +} + +int +mono_btls_x509_lookup_add_dir (MonoBtlsX509Lookup *lookup, const char *dir, MonoBtlsX509FileType type) +{ + return X509_LOOKUP_add_dir (lookup->lookup, dir, type); +} + +MonoBtlsX509Lookup * +mono_btls_x509_lookup_up_ref (MonoBtlsX509Lookup *lookup) +{ + CRYPTO_refcount_inc (&lookup->references); + return lookup; +} + +int +mono_btls_x509_lookup_free (MonoBtlsX509Lookup *lookup) +{ + if (!CRYPTO_refcount_dec_and_test_zero (&lookup->references)) + return 0; + + if (lookup->store) { + mono_btls_x509_store_free (lookup->store); + lookup->store = NULL; + } + + if (lookup->lookup) { + if (lookup->owns_lookup) + X509_LOOKUP_free (lookup->lookup); + lookup->lookup = NULL; + } + + OPENSSL_free (lookup); + return 1; +} + +int +mono_btls_x509_lookup_init (MonoBtlsX509Lookup *lookup) +{ + return X509_LOOKUP_init (lookup->lookup); +} + +int +mono_btls_x509_lookup_shutdown (MonoBtlsX509Lookup *lookup) +{ + return X509_LOOKUP_shutdown (lookup->lookup); +} + +MonoBtlsX509LookupType +mono_btls_x509_lookup_get_type (MonoBtlsX509Lookup *lookup) +{ + return lookup->type; +} + +X509_LOOKUP * +mono_btls_x509_lookup_peek_lookup (MonoBtlsX509Lookup *lookup) +{ + return lookup->lookup; +} + +X509 * +mono_btls_x509_lookup_by_subject (MonoBtlsX509Lookup *lookup, MonoBtlsX509Name *name) +{ + X509_OBJECT obj; + X509 *x509; + int ret; + + ret = X509_LOOKUP_by_subject (lookup->lookup, X509_LU_X509, mono_btls_x509_name_peek_name (name), &obj); + if (ret != X509_LU_X509) { + X509_OBJECT_free_contents (&obj); + return NULL; + } + + x509 = X509_up_ref (obj.data.x509); + return x509; +} + +X509 * +mono_btls_x509_lookup_by_fingerprint (MonoBtlsX509Lookup *lookup, unsigned char *bytes, int len) +{ + X509_OBJECT obj; + X509 *x509; + int ret; + + ret = X509_LOOKUP_by_fingerprint (lookup->lookup, X509_LU_X509, bytes, len, &obj); + if (ret != X509_LU_X509) { + X509_OBJECT_free_contents (&obj); + return NULL; + } + + x509 = X509_up_ref (obj.data.x509); + return x509; +} diff --git a/mono/btls/btls-x509-lookup.h b/mono/btls/btls-x509-lookup.h new file mode 100644 index 00000000000..df3d37f1ce3 --- /dev/null +++ b/mono/btls/btls-x509-lookup.h @@ -0,0 +1,58 @@ +// +// btls-x509-lookup.h +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_lookup__ +#define __btls__btls_x509_lookup__ + +#include +#include +#include +#include + +typedef enum { + MONO_BTLS_X509_LOOKUP_TYPE_UNKNOWN = 0, + MONO_BTLS_X509_LOOKUP_TYPE_FILE, + MONO_BTLS_X509_LOOKUP_TYPE_HASH_DIR, + MONO_BTLS_X509_LOOKUP_TYPE_MONO +} MonoBtlsX509LookupType; + +MonoBtlsX509Lookup * +mono_btls_x509_lookup_new (MonoBtlsX509Store *store, MonoBtlsX509LookupType type); + +int +mono_btls_x509_lookup_load_file (MonoBtlsX509Lookup *lookup, const char *file, MonoBtlsX509FileType type); + +int +mono_btls_x509_lookup_add_dir (MonoBtlsX509Lookup *lookup, const char *dir, MonoBtlsX509FileType type); + +MonoBtlsX509Lookup * +mono_btls_x509_lookup_up_ref (MonoBtlsX509Lookup *lookup); + +int +mono_btls_x509_lookup_free (MonoBtlsX509Lookup *lookup); + +int +mono_btls_x509_lookup_init (MonoBtlsX509Lookup *lookup); + +MonoBtlsX509LookupType +mono_btls_x509_lookup_get_type (MonoBtlsX509Lookup *lookup); + +X509_LOOKUP * +mono_btls_x509_lookup_peek_lookup (MonoBtlsX509Lookup *lookup); + +int +mono_btls_x509_lookup_shutdown (MonoBtlsX509Lookup *lookup); + +X509 * +mono_btls_x509_lookup_by_subject (MonoBtlsX509Lookup *lookup, MonoBtlsX509Name *name); + +X509 * +mono_btls_x509_lookup_by_fingerprint (MonoBtlsX509Lookup *lookup, unsigned char *bytes, int len); + +#endif /* defined(__btls__btls_x509_lookup__) */ + diff --git a/mono/btls/btls-x509-name.c b/mono/btls/btls-x509-name.c new file mode 100644 index 00000000000..d76d885e6a5 --- /dev/null +++ b/mono/btls/btls-x509-name.c @@ -0,0 +1,294 @@ +// +// btls-x509-name.c +// MonoBtls +// +// Created by Martin Baulig on 3/5/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include + +struct MonoBtlsX509Name { + int owns; + X509_NAME *name; +}; + +MonoBtlsX509Name * +mono_btls_x509_name_from_name (X509_NAME *xn) +{ + MonoBtlsX509Name *name; + + name = OPENSSL_malloc (sizeof (MonoBtlsX509Name)); + if (!name) + return NULL; + + memset(name, 0, sizeof(MonoBtlsX509Name)); + name->name = xn; + return name; +} + +MonoBtlsX509Name * +mono_btls_x509_name_copy (X509_NAME *xn) +{ + MonoBtlsX509Name *name; + + name = OPENSSL_malloc (sizeof (MonoBtlsX509Name)); + if (!name) + return NULL; + + memset(name, 0, sizeof(MonoBtlsX509Name)); + name->name = X509_NAME_dup(xn); + name->owns = 1; + return name; +} + +void +mono_btls_x509_name_free (MonoBtlsX509Name *name) +{ + if (name->owns) { + if (name->name) { + X509_NAME_free(name->name); + name->name = NULL; + } + } + OPENSSL_free(name); +} + +X509_NAME * +mono_btls_x509_name_peek_name (MonoBtlsX509Name *name) +{ + return name->name; +} + +int +mono_btls_x509_name_print_bio (MonoBtlsX509Name *name, BIO *bio) +{ + return X509_NAME_print_ex (bio, name->name, 0, ASN1_STRFLGS_RFC2253 | XN_FLAG_FN_SN | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_DN_REV); +} + +int +mono_btls_x509_name_get_raw_data (MonoBtlsX509Name *name, void **buffer, int use_canon_enc) +{ + int len; + void *ptr; + + if (use_canon_enc) { + // make sure canon_enc is initialized. + i2d_X509_NAME (name->name, NULL); + + len = name->name->canon_enclen; + ptr = name->name->canon_enc; + } else { + len = (int)name->name->bytes->length; + ptr = name->name->bytes->data; + } + + *buffer = OPENSSL_malloc (len); + if (!*buffer) + return 0; + + memcpy (*buffer, ptr, len); + return len; +} + +MonoBtlsX509Name * +mono_btls_x509_name_from_data (const void *data, int len, int use_canon_enc) +{ + MonoBtlsX509Name *name; + uint8_t *buf; + const unsigned char *ptr; + X509_NAME *ret; + + name = OPENSSL_malloc (sizeof (MonoBtlsX509Name)); + if (!name) + return NULL; + + memset (name, 0, sizeof(MonoBtlsX509Name)); + name->owns = 1; + + name->name = X509_NAME_new (); + if (!name->name) { + OPENSSL_free (name); + return NULL; + } + + if (use_canon_enc) { + CBB cbb, contents; + size_t buf_len; + + // re-add ASN1 SEQUENCE header. + CBB_init(&cbb, 0); + if (!CBB_add_asn1(&cbb, &contents, 0x30) || + !CBB_add_bytes(&contents, data, len) || + !CBB_finish(&cbb, &buf, &buf_len)) { + CBB_cleanup (&cbb); + mono_btls_x509_name_free (name); + return NULL; + } + + ptr = buf; + len = (int)buf_len; + } else { + ptr = data; + buf = NULL; + } + + ret = d2i_X509_NAME (&name->name, &ptr, len); + + if (buf) + OPENSSL_free (buf); + + if (ret != name->name) { + mono_btls_x509_name_free (name); + return NULL; + } + + return name; +} + +int +mono_btls_x509_name_print_string (MonoBtlsX509Name *name, char *buffer, int size) +{ + *buffer = 0; + return X509_NAME_oneline (name->name, buffer, size) != NULL; +} + +long +mono_btls_x509_name_hash (MonoBtlsX509Name *name) +{ + return X509_NAME_hash (name->name); +} + +long +mono_btls_x509_name_hash_old (MonoBtlsX509Name *name) +{ + return X509_NAME_hash_old (name->name); +} + +int +mono_btls_x509_name_get_entry_count (MonoBtlsX509Name *name) +{ + return X509_NAME_entry_count (name->name); +} + +static MonoBtlsX509NameEntryType +nid2mono (int nid) +{ + switch (nid) { + case NID_countryName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_COUNTRY_NAME; + case NID_organizationName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_ORGANIZATION_NAME; + case NID_organizationalUnitName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_ORGANIZATIONAL_UNIT_NAME; + case NID_commonName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_COMMON_NAME; + case NID_localityName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_LOCALITY_NAME; + case NID_stateOrProvinceName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_STATE_OR_PROVINCE_NAME; + case NID_streetAddress: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_STREET_ADDRESS; + case NID_serialNumber: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_SERIAL_NUMBER; + case NID_domainComponent: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_DOMAIN_COMPONENT; + case NID_userId: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_USER_ID; + case NID_dnQualifier: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_DN_QUALIFIER; + case NID_title: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_TITLE; + case NID_surname: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_SURNAME; + case NID_givenName: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_GIVEN_NAME; + case NID_initials: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_INITIAL; + default: + return MONO_BTLS_X509_NAME_ENTRY_TYPE_UNKNOWN; + } +} + +MonoBtlsX509NameEntryType +mono_btls_x509_name_get_entry_type (MonoBtlsX509Name *name, int index) +{ + X509_NAME_ENTRY *entry; + ASN1_OBJECT *obj; + + if (index >= X509_NAME_entry_count (name->name)) + return -1; + + entry = X509_NAME_get_entry (name->name, index); + if (!entry) + return -1; + + obj = X509_NAME_ENTRY_get_object (entry); + if (!obj) + return -1; + + return nid2mono (OBJ_obj2nid (obj)); +} + +int +mono_btls_x509_name_get_entry_oid (MonoBtlsX509Name *name, int index, char *buffer, int size) +{ + X509_NAME_ENTRY *entry; + ASN1_OBJECT *obj; + + if (index >= X509_NAME_entry_count (name->name)) + return 0; + + entry = X509_NAME_get_entry (name->name, index); + if (!entry) + return 0; + + obj = X509_NAME_ENTRY_get_object (entry); + if (!obj) + return 0; + + return OBJ_obj2txt (buffer, size, obj, 1); +} + +int +mono_btls_x509_name_get_entry_oid_data (MonoBtlsX509Name *name, int index, const void **data) +{ + X509_NAME_ENTRY *entry; + ASN1_OBJECT *obj; + + if (index >= X509_NAME_entry_count (name->name)) + return -1; + + entry = X509_NAME_get_entry (name->name, index); + if (!entry) + return -1; + + obj = X509_NAME_ENTRY_get_object (entry); + if (!obj) + return -1; + + *data = obj->data; + return obj->length; +} + +int +mono_btls_x509_name_get_entry_value (MonoBtlsX509Name *name, int index, unsigned char **str) +{ + X509_NAME_ENTRY *entry; + ASN1_STRING *data; + + *str = NULL; + + if (index >= X509_NAME_entry_count (name->name)) + return 0; + + entry = X509_NAME_get_entry (name->name, index); + if (!entry) + return 0; + + data = X509_NAME_ENTRY_get_data (entry); + if (!data) + return 0; + + return ASN1_STRING_to_UTF8 (str, data); +} diff --git a/mono/btls/btls-x509-name.h b/mono/btls/btls-x509-name.h new file mode 100644 index 00000000000..20c6a686563 --- /dev/null +++ b/mono/btls/btls-x509-name.h @@ -0,0 +1,80 @@ +// +// btls-x509-name.h +// MonoBtls +// +// Created by Martin Baulig on 3/5/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_name__ +#define __btls__btls_x509_name__ + +#include +#include + +typedef enum { + MONO_BTLS_X509_NAME_ENTRY_TYPE_UNKNOWN = 0, + MONO_BTLS_X509_NAME_ENTRY_TYPE_COUNTRY_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_ORGANIZATION_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_ORGANIZATIONAL_UNIT_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_COMMON_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_LOCALITY_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_STATE_OR_PROVINCE_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_STREET_ADDRESS, + MONO_BTLS_X509_NAME_ENTRY_TYPE_SERIAL_NUMBER, + MONO_BTLS_X509_NAME_ENTRY_TYPE_DOMAIN_COMPONENT, + MONO_BTLS_X509_NAME_ENTRY_TYPE_USER_ID, + MONO_BTLS_X509_NAME_ENTRY_TYPE_EMAIL, + MONO_BTLS_X509_NAME_ENTRY_TYPE_DN_QUALIFIER, + MONO_BTLS_X509_NAME_ENTRY_TYPE_TITLE, + MONO_BTLS_X509_NAME_ENTRY_TYPE_SURNAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_GIVEN_NAME, + MONO_BTLS_X509_NAME_ENTRY_TYPE_INITIAL +} MonoBtlsX509NameEntryType; + +MonoBtlsX509Name * +mono_btls_x509_name_from_name (X509_NAME *name); + +MonoBtlsX509Name * +mono_btls_x509_name_copy (X509_NAME *xn); + +void +mono_btls_x509_name_free (MonoBtlsX509Name *name); + +X509_NAME * +mono_btls_x509_name_peek_name (MonoBtlsX509Name *name); + +MonoBtlsX509Name * +mono_btls_x509_name_from_data (const void *data, int len, int use_canon_enc); + +int +mono_btls_x509_name_print_bio (MonoBtlsX509Name *name, BIO *bio); + +int +mono_btls_x509_name_print_string (MonoBtlsX509Name *name, char *buffer, int size); + +int +mono_btls_x509_name_get_raw_data (MonoBtlsX509Name *name, void **buffer, int use_canon_enc); + +long +mono_btls_x509_name_hash (MonoBtlsX509Name *name); + +long +mono_btls_x509_name_hash_old (MonoBtlsX509Name *name); + +int +mono_btls_x509_name_get_entry_count (MonoBtlsX509Name *name); + +MonoBtlsX509NameEntryType +mono_btls_x509_name_get_entry_type (MonoBtlsX509Name *name, int index); + +int +mono_btls_x509_name_get_entry_oid (MonoBtlsX509Name *name, int index, char *buffer, int size); + +int +mono_btls_x509_name_get_entry_oid_data (MonoBtlsX509Name *name, int index, const void **data); + +int +mono_btls_x509_name_get_entry_value (MonoBtlsX509Name *name, int index, unsigned char **str); + +#endif /* __btls__btls_x509_name__ */ diff --git a/mono/btls/btls-x509-revoked.c b/mono/btls/btls-x509-revoked.c new file mode 100644 index 00000000000..e6fb4b0035f --- /dev/null +++ b/mono/btls/btls-x509-revoked.c @@ -0,0 +1,72 @@ +// +// btls-x509-revoked.c +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include + +struct MonoBtlsX509Revoked { + MonoBtlsX509Crl *owner; + X509_REVOKED *revoked; +}; + +MonoBtlsX509Revoked * +mono_btls_x509_revoked_new (MonoBtlsX509Crl *owner, X509_REVOKED *revoked) +{ + MonoBtlsX509Revoked *instance; + + instance = OPENSSL_malloc (sizeof (MonoBtlsX509Revoked)); + memset (instance, 0, sizeof (MonoBtlsX509Revoked)); + + instance->owner = mono_btls_x509_crl_ref (owner); + instance->revoked = revoked; + return instance; +} + +void +mono_btls_x509_revoked_free (MonoBtlsX509Revoked *revoked) +{ + mono_btls_x509_crl_free (revoked->owner); + OPENSSL_free (revoked); +} + +int +mono_btls_x509_revoked_get_serial_number (MonoBtlsX509Revoked *revoked, char *buffer, int size) +{ + ASN1_INTEGER *serial; + + serial = revoked->revoked->serialNumber; + if (serial->length == 0 || serial->length+1 > size) + return 0; + + memcpy (buffer, serial->data, serial->length); + return serial->length; +} + +long +mono_btls_x509_revoked_get_revocation_date (MonoBtlsX509Revoked *revoked) +{ + ASN1_TIME *date; + + date = revoked->revoked->revocationDate; + if (!date) + return 0; + + return mono_btls_util_asn1_time_to_ticks (date); +} + +int +mono_btls_x509_revoked_get_reason (MonoBtlsX509Revoked *revoked) +{ + return revoked->revoked->reason; +} + +int +mono_btls_x509_revoked_get_sequence (MonoBtlsX509Revoked *revoked) +{ + return revoked->revoked->sequence; +} + diff --git a/mono/btls/btls-x509-revoked.h b/mono/btls/btls-x509-revoked.h new file mode 100644 index 00000000000..e1229c6a47f --- /dev/null +++ b/mono/btls/btls-x509-revoked.h @@ -0,0 +1,34 @@ +// +// btls-x509-revoked.h +// MonoBtls +// +// Created by Martin Baulig on 3/23/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_revoked__ +#define __btls__btls_x509_revoked__ + +#include +#include +#include + +MonoBtlsX509Revoked * +mono_btls_x509_revoked_new (MonoBtlsX509Crl *owner, X509_REVOKED *revoked); + +void +mono_btls_x509_revoked_free (MonoBtlsX509Revoked *revoked); + +int +mono_btls_x509_revoked_get_serial_number (MonoBtlsX509Revoked *revoked, char *buffer, int size); + +long +mono_btls_x509_revoked_get_revocation_date (MonoBtlsX509Revoked *revoked); + +int +mono_btls_x509_revoked_get_reason (MonoBtlsX509Revoked *revoked); + +int +mono_btls_x509_revoked_get_sequence (MonoBtlsX509Revoked *revoked); + +#endif /* __btls__btls_x509_revoked__ */ diff --git a/mono/btls/btls-x509-store-ctx.c b/mono/btls/btls-x509-store-ctx.c new file mode 100644 index 00000000000..8ed77d01ba3 --- /dev/null +++ b/mono/btls/btls-x509-store-ctx.c @@ -0,0 +1,229 @@ +// +// btls-x509-store-ctx.c +// MonoBtls +// +// Created by Martin Baulig on 3/5/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include + +struct MonoBtlsX509StoreCtx { + int owns; + X509_STORE_CTX *ctx; + CRYPTO_refcount_t references; + MonoBtlsX509Store *store; + MonoBtlsX509Chain *chain; +}; + +MonoBtlsX509StoreCtx * +mono_btls_x509_store_ctx_from_ptr (X509_STORE_CTX *ptr) +{ + MonoBtlsX509StoreCtx *ctx; + + ctx = OPENSSL_malloc (sizeof(MonoBtlsX509StoreCtx)); + if (!ctx) + return NULL; + + memset (ctx, 0, sizeof (MonoBtlsX509StoreCtx)); + ctx->ctx = ptr; + ctx->references = 1; + return ctx; +} + +MonoBtlsX509StoreCtx * +mono_btls_x509_store_ctx_new (void) +{ + MonoBtlsX509StoreCtx *ctx; + + ctx = OPENSSL_malloc (sizeof(MonoBtlsX509StoreCtx)); + if (!ctx) + return NULL; + + memset (ctx, 0, sizeof (MonoBtlsX509StoreCtx)); + ctx->ctx = X509_STORE_CTX_new (); + ctx->references = 1; + ctx->owns = 1; + return ctx; +} + +MonoBtlsX509StoreCtx * +mono_btls_x509_store_ctx_up_ref (MonoBtlsX509StoreCtx *ctx) +{ + CRYPTO_refcount_inc (&ctx->references); + return ctx; +} + +int +mono_btls_x509_store_ctx_free (MonoBtlsX509StoreCtx *ctx) +{ + if (!CRYPTO_refcount_dec_and_test_zero (&ctx->references)) + return 0; + + if (ctx->owns) { + X509_STORE_CTX_cleanup (ctx->ctx); + X509_STORE_CTX_free (ctx->ctx); + ctx->owns = 0; + } + if (ctx->store) { + mono_btls_x509_store_free (ctx->store); + ctx->store = NULL; + } + if (ctx->chain) { + mono_btls_x509_chain_free (ctx->chain); + ctx->chain = NULL; + } + OPENSSL_free (ctx); + return 1; +} + +int +mono_btls_x509_store_ctx_get_error (MonoBtlsX509StoreCtx *ctx, const char **error_string) +{ + int error; + + error = X509_STORE_CTX_get_error (ctx->ctx); + if (error_string) + *error_string = X509_verify_cert_error_string (error); + return error; +} + +int +mono_btls_x509_store_ctx_get_error_depth (MonoBtlsX509StoreCtx *ctx) +{ + return X509_STORE_CTX_get_error_depth (ctx->ctx); +} + +MonoBtlsX509Chain * +mono_btls_x509_store_ctx_get_chain (MonoBtlsX509StoreCtx *ctx) +{ + STACK_OF(X509) *certs; + + certs = X509_STORE_CTX_get_chain (ctx->ctx); + if (!certs) + return NULL; + + return mono_btls_x509_chain_from_certs (certs); +} + +MonoBtlsX509Chain * +mono_btls_x509_store_ctx_get_untrusted (MonoBtlsX509StoreCtx *ctx) +{ + STACK_OF(X509) *untrusted; + + /* + * Unfortunately, there is no accessor function for this. + * + * This is the set of certificate that's passed in by + * X509_STORE_CTX_init() and X509_STORE_CTX_set_chain(). + */ + untrusted = ctx->ctx->untrusted; + if (!untrusted) + return NULL; + + return mono_btls_x509_chain_from_certs (untrusted); +} + +void +mono_btls_x509_store_ctx_test (MonoBtlsX509StoreCtx *ctx) +{ + X509_VERIFY_PARAM *param; + char *peer; + + fprintf (stderr, "TEST: %p!\n", ctx); + param = X509_STORE_CTX_get0_param (ctx->ctx); + peer = X509_VERIFY_PARAM_get0_peername(param); + fprintf (stderr, "TEST #1: %s\n", peer); +} + +int +mono_btls_x509_store_ctx_init (MonoBtlsX509StoreCtx *ctx, + MonoBtlsX509Store *store, MonoBtlsX509Chain *chain) +{ + STACK_OF(X509) *certs; + X509 *leaf; + int ret; + + if (ctx->store) + return 0; + + certs = mono_btls_x509_chain_peek_certs (chain); + if (!certs || !sk_X509_num (certs)) + return 0; + + ctx->store = mono_btls_x509_store_up_ref(store); + ctx->chain = mono_btls_x509_chain_up_ref(chain); + + leaf = sk_X509_value (certs, 0); + ret = X509_STORE_CTX_init (ctx->ctx, mono_btls_x509_store_peek_store (store), leaf, certs); + if (ret != 1) + return ret; + + X509_STORE_CTX_set_app_data (ctx->ctx, ctx); + return 1; +} + +int +mono_btls_x509_store_ctx_set_param (MonoBtlsX509StoreCtx *ctx, MonoBtlsX509VerifyParam *param) +{ + return X509_VERIFY_PARAM_set1 (X509_STORE_CTX_get0_param (ctx->ctx), mono_btls_x509_verify_param_peek_param (param)); +} + +int +mono_btls_x509_store_ctx_verify_cert (MonoBtlsX509StoreCtx *ctx) +{ + return X509_verify_cert (ctx->ctx); +} + +X509 * +mono_btls_x509_store_ctx_get_by_subject (MonoBtlsX509StoreCtx *ctx, MonoBtlsX509Name *name) +{ + X509_OBJECT obj; + X509 *x509; + int ret; + + ret = X509_STORE_get_by_subject (ctx->ctx, X509_LU_X509, mono_btls_x509_name_peek_name (name), &obj); + if (ret != X509_LU_X509) { + X509_OBJECT_free_contents (&obj); + return NULL; + } + + x509 = X509_up_ref (obj.data.x509); + return x509; +} + +X509 * +mono_btls_x509_store_ctx_get_current_cert (MonoBtlsX509StoreCtx *ctx) +{ + X509 *x509 = X509_STORE_CTX_get_current_cert (ctx->ctx); + if (!x509) + return NULL; + return X509_up_ref (x509); +} + +X509 * +mono_btls_x509_store_ctx_get_current_issuer (MonoBtlsX509StoreCtx *ctx) +{ + X509 *x509 = X509_STORE_CTX_get0_current_issuer (ctx->ctx); + if (!x509) + return NULL; + return X509_up_ref (x509); +} + +MonoBtlsX509VerifyParam * +mono_btls_x509_store_ctx_get_verify_param (MonoBtlsX509StoreCtx *ctx) +{ + X509_VERIFY_PARAM *param; + + param = X509_STORE_CTX_get0_param (ctx->ctx); + if (!param) + return NULL; + + return mono_btls_x509_verify_param_from_store_ctx (ctx, param); +} + +int +mono_btls_x509_store_ctx_get_foo (MonoBtlsX509StoreCtx *ctx) +{ + return 0; +} \ No newline at end of file diff --git a/mono/btls/btls-x509-store-ctx.h b/mono/btls/btls-x509-store-ctx.h new file mode 100644 index 00000000000..c5ed499612a --- /dev/null +++ b/mono/btls/btls-x509-store-ctx.h @@ -0,0 +1,69 @@ +// +// btls-x509-store-ctx.h +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_store_ctx__ +#define __btls__btls_x509_store_ctx__ + +#include +#include +#include +#include +#include +#include + +MonoBtlsX509StoreCtx * +mono_btls_x509_store_ctx_from_ptr (X509_STORE_CTX *ptr); + +MonoBtlsX509StoreCtx * +mono_btls_x509_store_ctx_new (void); + +MonoBtlsX509StoreCtx * +mono_btls_x509_store_ctx_up_ref (MonoBtlsX509StoreCtx *ctx); + +int +mono_btls_x509_store_ctx_free (MonoBtlsX509StoreCtx *ctx); + +int +mono_btls_x509_store_ctx_get_error (MonoBtlsX509StoreCtx *ctx, const char **error_string); + +int +mono_btls_x509_store_ctx_get_error_depth (MonoBtlsX509StoreCtx *ctx); + +MonoBtlsX509Chain * +mono_btls_x509_store_ctx_get_chain (MonoBtlsX509StoreCtx *ctx); + +X509 * +mono_btls_x509_store_ctx_get_current_cert (MonoBtlsX509StoreCtx *ctx); + +X509 * +mono_btls_x509_store_ctx_get_current_issuer (MonoBtlsX509StoreCtx *ctx); + +void +mono_btls_x509_store_ctx_test (MonoBtlsX509StoreCtx *ctx); + +int +mono_btls_x509_store_ctx_init (MonoBtlsX509StoreCtx *ctx, + MonoBtlsX509Store *store, MonoBtlsX509Chain *chain); + +int +mono_btls_x509_store_ctx_set_param (MonoBtlsX509StoreCtx *ctx, MonoBtlsX509VerifyParam *param); + +X509 * +mono_btls_x509_store_ctx_get_by_subject (MonoBtlsX509StoreCtx *ctx, MonoBtlsX509Name *name); + +int +mono_btls_x509_store_ctx_verify_cert (MonoBtlsX509StoreCtx *ctx); + +MonoBtlsX509VerifyParam * +mono_btls_x509_store_ctx_get_verify_param (MonoBtlsX509StoreCtx *ctx); + +MonoBtlsX509Chain * +mono_btls_x509_store_ctx_get_untrusted (MonoBtlsX509StoreCtx *ctx); + +#endif /* defined(__btls__btls_x509_store_ctx__) */ + diff --git a/mono/btls/btls-x509-store.c b/mono/btls/btls-x509-store.c new file mode 100644 index 00000000000..f2c826e11f4 --- /dev/null +++ b/mono/btls/btls-x509-store.c @@ -0,0 +1,110 @@ +// +// btls-x509-store.c +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include + +struct MonoBtlsX509Store { + X509_STORE *store; + CRYPTO_refcount_t references; +}; + +MonoBtlsX509Store * +mono_btls_x509_store_from_store (X509_STORE *ctx) +{ + MonoBtlsX509Store *store; + + store = OPENSSL_malloc (sizeof(MonoBtlsX509Store)); + if (!store) + return NULL; + + memset (store, 0, sizeof(MonoBtlsX509Store)); + store->store = ctx; + CRYPTO_refcount_inc (&store->store->references); + store->references = 1; + return store; +} + +MonoBtlsX509Store * +mono_btls_x509_store_from_ctx (X509_STORE_CTX *ctx) +{ + return mono_btls_x509_store_from_store (ctx->ctx); +} + +MonoBtlsX509Store * +mono_btls_x509_store_new (void) +{ + MonoBtlsX509Store *store; + + store = OPENSSL_malloc (sizeof(MonoBtlsX509Store)); + if (!store) + return NULL; + + memset (store, 0, sizeof(MonoBtlsX509Store)); + store->store = X509_STORE_new (); + store->references = 1; + return store; +} + +X509_STORE * +mono_btls_x509_store_peek_store (MonoBtlsX509Store *store) +{ + return store->store; +} + +MonoBtlsX509Store * +mono_btls_x509_store_from_ssl_ctx (MonoBtlsSslCtx *ctx) +{ + X509_STORE *store = mono_btls_ssl_ctx_peek_store (ctx); + return mono_btls_x509_store_from_store (store); +} + +int +mono_btls_x509_store_free (MonoBtlsX509Store *store) +{ + if (!CRYPTO_refcount_dec_and_test_zero(&store->references)) + return 0; + + if (store->store) { + X509_STORE_free (store->store); + store->store = NULL; + } + OPENSSL_free (store); + return 1; +} + +MonoBtlsX509Store * +mono_btls_x509_store_up_ref (MonoBtlsX509Store *store) +{ + CRYPTO_refcount_inc (&store->references); + return store; +} + +int +mono_btls_x509_store_add_cert (MonoBtlsX509Store *store, X509 *cert) +{ + return X509_STORE_add_cert (store->store, cert); +} + +int +mono_btls_x509_store_load_locations (MonoBtlsX509Store *store, const char *file, const char *path) +{ + return X509_STORE_load_locations (store->store, file, path); +} + +int +mono_btls_x509_store_set_default_paths (MonoBtlsX509Store *store) +{ + return X509_STORE_set_default_paths (store->store); +} + +int +mono_btls_x509_store_get_count (MonoBtlsX509Store *store) +{ + return (int)sk_X509_OBJECT_num (store->store->objs); +} + diff --git a/mono/btls/btls-x509-store.h b/mono/btls/btls-x509-store.h new file mode 100644 index 00000000000..67ffe00cd39 --- /dev/null +++ b/mono/btls/btls-x509-store.h @@ -0,0 +1,46 @@ +// +// btls-x509-store.h +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_store__ +#define __btls__btls_x509_store__ + +#include +#include + +MonoBtlsX509Store * +mono_btls_x509_store_new (void); + +MonoBtlsX509Store * +mono_btls_x509_store_from_ctx (X509_STORE_CTX *ctx); + +MonoBtlsX509Store * +mono_btls_x509_store_from_ssl_ctx (MonoBtlsSslCtx *ctx); + +MonoBtlsX509Store * +mono_btls_x509_store_up_ref (MonoBtlsX509Store *store); + +int +mono_btls_x509_store_free (MonoBtlsX509Store *store); + +X509_STORE * +mono_btls_x509_store_peek_store (MonoBtlsX509Store *store); + +int +mono_btls_x509_store_add_cert (MonoBtlsX509Store *store, X509 *cert); + +int +mono_btls_x509_store_load_locations (MonoBtlsX509Store *store, const char *file, const char *path); + +int +mono_btls_x509_store_set_default_paths (MonoBtlsX509Store *store); + +int +mono_btls_x509_store_get_count (MonoBtlsX509Store *store); + +#endif /* defined(__btls__btls_x509_store__) */ + diff --git a/mono/btls/btls-x509-verify-param.c b/mono/btls/btls-x509-verify-param.c new file mode 100644 index 00000000000..643fdcd43d2 --- /dev/null +++ b/mono/btls/btls-x509-verify-param.c @@ -0,0 +1,221 @@ +// +// btls-x509-verify-param.c +// MonoBtls +// +// Created by Martin Baulig on 3/5/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#include +#include + +struct MonoBtlsX509VerifyParam { + int owns; + MonoBtlsX509StoreCtx *owner; + X509_VERIFY_PARAM *param; +}; + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_new (void) +{ + MonoBtlsX509VerifyParam *param; + + param = OPENSSL_malloc (sizeof(MonoBtlsX509VerifyParam)); + if (!param) + return NULL; + memset (param, 0, sizeof (MonoBtlsX509VerifyParam)); + param->param = X509_VERIFY_PARAM_new(); + param->owns = 1; + return param; +} + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_from_store_ctx (MonoBtlsX509StoreCtx *ctx, X509_VERIFY_PARAM *param) +{ + MonoBtlsX509VerifyParam *instance; + + instance = OPENSSL_malloc (sizeof(MonoBtlsX509VerifyParam)); + if (!instance) + return NULL; + memset (instance, 0, sizeof (MonoBtlsX509VerifyParam)); + instance->param = param; + instance->owner = mono_btls_x509_store_ctx_up_ref (ctx); + return instance; +} + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_copy (const MonoBtlsX509VerifyParam *from) +{ + MonoBtlsX509VerifyParam *param; + + param = mono_btls_x509_verify_param_new (); + if (!param) + return NULL; + + X509_VERIFY_PARAM_set1 (param->param, from->param); + return param; +} + +const X509_VERIFY_PARAM * +mono_btls_x509_verify_param_peek_param (const MonoBtlsX509VerifyParam *param) +{ + return param->param; +} + +int +mono_btls_x509_verify_param_can_modify (MonoBtlsX509VerifyParam *param) +{ + return param->owns; +} + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_lookup (const char *name) +{ + MonoBtlsX509VerifyParam *param; + const X509_VERIFY_PARAM *p; + + p = X509_VERIFY_PARAM_lookup(name); + if (!p) + return NULL; + + param = OPENSSL_malloc (sizeof(MonoBtlsX509VerifyParam)); + if (!param) + return NULL; + memset (param, 0, sizeof (MonoBtlsX509VerifyParam)); + param->param = (X509_VERIFY_PARAM *)p; + return param; +} + +void +mono_btls_x509_verify_param_free (MonoBtlsX509VerifyParam *param) +{ + if (param->owns) { + if (param->param) { + X509_VERIFY_PARAM_free (param->param); + param->param = NULL; + } + } + if (param->owner) { + mono_btls_x509_store_ctx_free (param->owner); + param->owner = NULL; + } + OPENSSL_free (param); +} + +int +mono_btls_x509_verify_param_set_name (MonoBtlsX509VerifyParam *param, const char *name) +{ + if (!param->owns) + return -1; + return X509_VERIFY_PARAM_set1_name (param->param, name); +} + +int +mono_btls_x509_verify_param_set_host (MonoBtlsX509VerifyParam *param, const char *host, int namelen) +{ + if (!param->owns) + return -1; + return X509_VERIFY_PARAM_set1_host (param->param, host, namelen); +} + +int +mono_btls_x509_verify_param_add_host (MonoBtlsX509VerifyParam *param, const char *host, int namelen) +{ + if (!param->owns) + return -1; + return X509_VERIFY_PARAM_set1_host (param->param, host, namelen); +} + +unsigned long +mono_btls_x509_verify_param_get_flags (MonoBtlsX509VerifyParam *param) +{ + return X509_VERIFY_PARAM_get_flags (param->param); +} + +int +mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, unsigned long flags) +{ + if (!param->owns) + return -1; + return X509_VERIFY_PARAM_set_flags (param->param, flags); +} + +MonoBtlsX509VerifyFlags +mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param) +{ + MonoBtlsX509VerifyFlags current; + unsigned long flags; + + if (!param->owns) + return -1; + + current = 0; + flags = X509_VERIFY_PARAM_get_flags (param->param); + + if (flags & X509_V_FLAG_CRL_CHECK) + current |= MONO_BTLS_X509_VERIFY_FLAGS_CRL_CHECK; + if (flags & X509_V_FLAG_CRL_CHECK_ALL) + current |= MONO_BTLS_X509_VERIFY_FLAGS_CRL_CHECK_ALL; + if (flags & X509_V_FLAG_X509_STRICT) + current |= MONO_BTLS_X509_VERIFY_FLAGS_X509_STRICT; + + return current; +} + +int +mono_btls_x509_verify_param_set_mono_flags (MonoBtlsX509VerifyParam *param, MonoBtlsX509VerifyFlags flags) +{ + unsigned long current; + + if (!param->owns) + return -1; + + current = X509_VERIFY_PARAM_get_flags (param->param); + if (flags & MONO_BTLS_X509_VERIFY_FLAGS_CRL_CHECK) + current |= X509_V_FLAG_CRL_CHECK; + if (flags & MONO_BTLS_X509_VERIFY_FLAGS_CRL_CHECK_ALL) + current |= X509_V_FLAG_CRL_CHECK_ALL; + if (flags & MONO_BTLS_X509_VERIFY_FLAGS_X509_STRICT) + current |= X509_V_FLAG_X509_STRICT; + + return X509_VERIFY_PARAM_set_flags (param->param, current); +} + +int +mono_btls_x509_verify_param_set_purpose (MonoBtlsX509VerifyParam *param, MonoBtlsX509Purpose purpose) +{ + if (!param->owns) + return -1; + return X509_VERIFY_PARAM_set_purpose (param->param, purpose); +} + +int +mono_btls_x509_verify_param_get_depth (MonoBtlsX509VerifyParam *param) +{ + return X509_VERIFY_PARAM_get_depth (param->param); +} + +int +mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth) +{ + if (!param->owns) + return -1; + X509_VERIFY_PARAM_set_depth (param->param, depth); + return 1; +} + +int +mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, long time) +{ + if (!param->owns) + return -1; + X509_VERIFY_PARAM_set_time (param->param, time); + return 1; +} + +char * +mono_btls_x509_verify_param_get_peername (MonoBtlsX509VerifyParam *param) +{ + char *peer = X509_VERIFY_PARAM_get0_peername (param->param); + return peer; +} diff --git a/mono/btls/btls-x509-verify-param.h b/mono/btls/btls-x509-verify-param.h new file mode 100644 index 00000000000..6f4f1b51a8e --- /dev/null +++ b/mono/btls/btls-x509-verify-param.h @@ -0,0 +1,81 @@ +// +// btls-x509-verify-param.h +// MonoBtls +// +// Created by Martin Baulig on 3/3/16. +// Copyright © 2016 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509_verify_param__ +#define __btls__btls_x509_verify_param__ + +#include +#include +#include + +typedef enum { + MONO_BTLS_X509_VERIFY_FLAGS_DEFAULT = 0, + MONO_BTLS_X509_VERIFY_FLAGS_CRL_CHECK = 1, + MONO_BTLS_X509_VERIFY_FLAGS_CRL_CHECK_ALL = 2, + MONO_BTLS_X509_VERIFY_FLAGS_X509_STRICT = 4 +} MonoBtlsX509VerifyFlags; + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_new (void); + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_from_store_ctx (MonoBtlsX509StoreCtx *ctx, X509_VERIFY_PARAM *param); + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_copy (const MonoBtlsX509VerifyParam *from); + +void +mono_btls_x509_verify_param_free (MonoBtlsX509VerifyParam *param); + +const X509_VERIFY_PARAM * +mono_btls_x509_verify_param_peek_param (const MonoBtlsX509VerifyParam *param); + +int +mono_btls_x509_verify_param_can_modify (MonoBtlsX509VerifyParam *param); + +MonoBtlsX509VerifyParam * +mono_btls_x509_verify_param_lookup (const char *name); + +int +mono_btls_x509_verify_param_set_name (MonoBtlsX509VerifyParam *param, const char *name); + +int +mono_btls_x509_verify_param_set_host (MonoBtlsX509VerifyParam *param, const char *host, int namelen); + +int +mono_btls_x509_verify_param_add_host (MonoBtlsX509VerifyParam *param, const char *host, int namelen); + +unsigned long +mono_btls_x509_verify_param_get_flags (MonoBtlsX509VerifyParam *param); + +int +mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, unsigned long flags); + +MonoBtlsX509VerifyFlags +mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param); + +int +mono_btls_x509_verify_param_set_mono_flags (MonoBtlsX509VerifyParam *param, MonoBtlsX509VerifyFlags flags); + +int +mono_btls_x509_verify_param_set_purpose (MonoBtlsX509VerifyParam *param, MonoBtlsX509Purpose purpose); + +int +mono_btls_x509_verify_param_get_depth (MonoBtlsX509VerifyParam *param); + +int +mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth); + +int +mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, long time); + +char * +mono_btls_x509_verify_param_get_peername (MonoBtlsX509VerifyParam *param); + +#endif /* defined(__btls__btls_x509_verify_param__) */ + diff --git a/mono/btls/btls-x509.c b/mono/btls/btls-x509.c new file mode 100644 index 00000000000..54174223fb9 --- /dev/null +++ b/mono/btls/btls-x509.c @@ -0,0 +1,436 @@ +// +// btls-x509.c +// MonoBtls +// +// Created by Martin Baulig on 14/11/15. +// Copyright (c) 2015 Xamarin. All rights reserved. +// + +#include +#include +#include + +X509 * +mono_btls_x509_from_data (const void *buf, int len, MonoBtlsX509Format format) +{ + BIO *bio; + X509 *cert = NULL; + + bio = BIO_new_mem_buf ((void *)buf, len); + switch (format) { + case MONO_BTLS_X509_FORMAT_DER: + cert = d2i_X509_bio (bio, NULL); + break; + case MONO_BTLS_X509_FORMAT_PEM: + cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL); + break; + } + BIO_free (bio); + return cert; +} + +X509 * +mono_btls_x509_up_ref (X509 *x509) +{ + X509_up_ref (x509); + return x509; +} + +void +mono_btls_x509_free (X509 *x509) +{ + X509_free (x509); +} + +X509 * +mono_btls_x509_dup (X509 *x509) +{ + return X509_dup (x509); +} + +MonoBtlsX509Name * +mono_btls_x509_get_subject_name (X509 *x509) +{ + return mono_btls_x509_name_copy (X509_get_subject_name (x509)); +} + +MonoBtlsX509Name * +mono_btls_x509_get_issuer_name (X509 *x509) +{ + return mono_btls_x509_name_copy (X509_get_issuer_name (x509)); +} + +int +mono_btls_x509_get_subject_name_string (X509 *name, char *buffer, int size) +{ + *buffer = 0; + return X509_NAME_oneline (X509_get_subject_name (name), buffer, size) != NULL; +} + +int +mono_btls_x509_get_issuer_name_string (X509 *name, char *buffer, int size) +{ + *buffer = 0; + return X509_NAME_oneline (X509_get_issuer_name (name), buffer, size) != NULL; +} + +int +mono_btls_x509_get_raw_data (X509 *x509, BIO *bio, MonoBtlsX509Format format) +{ + switch (format) { + case MONO_BTLS_X509_FORMAT_DER: + return i2d_X509_bio (bio, x509); + case MONO_BTLS_X509_FORMAT_PEM: + return PEM_write_bio_X509 (bio, x509); + default: + return 0; + } +} + +int +mono_btls_x509_cmp (const X509 *a, const X509 *b) +{ + return X509_cmp (a, b); +} + +int +mono_btls_x509_get_hash (X509 *x509, const void **data) +{ + X509_check_purpose (x509, -1, 0); + *data = x509->sha1_hash; + return SHA_DIGEST_LENGTH; +} + +long +mono_btls_x509_get_not_before (X509 *x509) +{ + return mono_btls_util_asn1_time_to_ticks (X509_get_notBefore (x509)); +} + +long +mono_btls_x509_get_not_after (X509 *x509) +{ + return mono_btls_util_asn1_time_to_ticks (X509_get_notAfter (x509)); +} + +int +mono_btls_x509_get_public_key (X509 *x509, BIO *bio) +{ + EVP_PKEY *pkey; + uint8_t *data = NULL; + int ret; + + pkey = X509_get_pubkey (x509); + if (!pkey) + return -1; + + ret = i2d_PublicKey (pkey, &data); + + if (ret > 0 && data) { + ret = BIO_write (bio, data, ret); + OPENSSL_free (data); + } + + EVP_PKEY_free (pkey); + return ret; +} + +int +mono_btls_x509_get_serial_number (X509 *x509, char *buffer, int size, int mono_style) +{ + ASN1_INTEGER *serial; + char *pos; + int len, idx; + + serial = X509_get_serialNumber (x509); + if (serial->length == 0 || serial->length+1 > size) + return 0; + + if (!mono_style) { + memcpy (buffer, serial->data, serial->length); + return serial->length; + } + + pos = buffer; + len = 0; + + for (idx = serial->length - 1; idx >= 0; idx--) { + *pos++ = serial->data [idx]; + len++; + } + + if (serial->data [0] >= 0x80) { + *pos++ = 0; + len++; + } + + return len; +} + +int +mono_btls_x509_get_public_key_algorithm (X509 *x509, char *buffer, int size) +{ + X509_PUBKEY *pkey; + ASN1_OBJECT *ppkalg; + int ret; + + *buffer = 0; + pkey = X509_get_X509_PUBKEY (x509); + if (!pkey) + return 0; + + ret = X509_PUBKEY_get0_param (&ppkalg, NULL, NULL, NULL, pkey); + if (!ret || !ppkalg) + return ret; + + return OBJ_obj2txt (buffer, size, ppkalg, 1); +} + +int +mono_btls_x509_get_version (X509 *x509) +{ + return (int)X509_get_version (x509) + 1; +} + +int +mono_btls_x509_get_signature_algorithm (X509 *x509, char *buffer, int size) +{ + const ASN1_OBJECT *obj; + int nid; + + *buffer = 0; + + nid = X509_get_signature_nid (x509); + + obj = OBJ_nid2obj (nid); + if (!obj) + return 0; + + return OBJ_obj2txt (buffer, size, obj, 1); +} + +int +mono_btls_x509_get_public_key_asn1 (X509 *x509, char *out_oid, int oid_len, uint8_t **buffer, int *size) +{ + X509_PUBKEY *pkey; + ASN1_OBJECT *ppkalg; + const unsigned char *pk; + int pk_len; + int ret; + + if (out_oid) + *out_oid = 0; + + pkey = X509_get_X509_PUBKEY (x509); + if (!pkey || !pkey->public_key) + return 0; + + ret = X509_PUBKEY_get0_param (&ppkalg, &pk, &pk_len, NULL, pkey); + if (ret != 1 || !ppkalg || !pk) + return 0; + + if (out_oid) { + OBJ_obj2txt (out_oid, oid_len, ppkalg, 1); + } + + if (buffer) { + *size = pk_len; + *buffer = OPENSSL_malloc (pk_len); + if (!*buffer) + return 0; + + memcpy (*buffer, pk, pk_len); + } + + return 1; + +} + +int +mono_btls_x509_get_public_key_parameters (X509 *x509, char *out_oid, int oid_len, uint8_t **buffer, int *size) +{ + X509_PUBKEY *pkey; + X509_ALGOR *algor; + ASN1_OBJECT *paobj; + int ptype; + void *pval; + int ret; + + if (out_oid) + *out_oid = 0; + + pkey = X509_get_X509_PUBKEY (x509); + + ret = X509_PUBKEY_get0_param (NULL, NULL, NULL, &algor, pkey); + if (ret != 1 || !algor) + return 0; + + X509_ALGOR_get0 (&paobj, &ptype, &pval, algor); + + if (ptype != V_ASN1_NULL && ptype != V_ASN1_SEQUENCE) + return 0; + + if (ptype == V_ASN1_NULL) { + uint8_t *ptr; + + *size = 2; + *buffer = OPENSSL_malloc (2); + if (!*buffer) + return 0; + + ptr = *buffer; + *ptr++ = 0x05; + *ptr++ = 0x00; + + if (out_oid) + OBJ_obj2txt (out_oid, oid_len, paobj, 1); + + return 1; + } else if (ptype == V_ASN1_SEQUENCE) { + ASN1_STRING *pstr = pval; + + *size = pstr->length; + *buffer = OPENSSL_malloc (pstr->length); + if (!*buffer) + return 0; + + memcpy (*buffer, pstr->data, pstr->length); + + if (out_oid) + OBJ_obj2txt (out_oid, oid_len, paobj, 1); + + return 1; + } else { + return 0; + } +} + +EVP_PKEY * +mono_btls_x509_get_pubkey (X509 *x509) +{ + return X509_get_pubkey (x509); +} + +int +mono_btls_x509_get_subject_key_identifier (X509 *x509, uint8_t **buffer, int *size) +{ + ASN1_OCTET_STRING *skid; + + *size = 0; + *buffer = NULL; + + if (X509_get_version (x509) != 2) + return 0; + + skid = X509_get_ext_d2i (x509, NID_subject_key_identifier, NULL, NULL); + if (!skid) + return 0; + + *size = skid->length; + *buffer = OPENSSL_malloc (*size); + if (!*buffer) + return 0; + + memcpy (*buffer, skid->data, *size); + return 1; +} + +int +mono_btls_x509_print (X509 *x509, BIO *bio) +{ + return X509_print_ex (bio, x509, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +static int +get_trust_nid (MonoBtlsX509Purpose purpose) +{ + switch (purpose) { + case MONO_BTLS_X509_PURPOSE_SSL_CLIENT: + return NID_client_auth; + case MONO_BTLS_X509_PURPOSE_SSL_SERVER: + return NID_server_auth; + default: + return 0; + } +} + +int +mono_btls_x509_add_trust_object (X509 *x509, MonoBtlsX509Purpose purpose) +{ + ASN1_OBJECT *trust; + int nid; + + nid = get_trust_nid (purpose); + if (!nid) + return 0; + + trust = ASN1_OBJECT_new (); + if (!trust) + return 0; + + trust->nid = nid; + return X509_add1_trust_object (x509, trust); +} + +int +mono_btls_x509_add_reject_object (X509 *x509, MonoBtlsX509Purpose purpose) +{ + ASN1_OBJECT *reject; + int nid; + + nid = get_trust_nid (purpose); + if (!nid) + return 0; + + reject = ASN1_OBJECT_new (); + if (!reject) + return 0; + + reject->nid = nid; + return X509_add1_reject_object (x509, reject); +} + +int +mono_btls_x509_add_explicit_trust (X509 *x509, MonoBtlsX509TrustKind kind) +{ + int ret = 0; + + if ((kind & MONO_BTLS_X509_TRUST_KIND_REJECT_ALL) != 0) + kind |= MONO_BTLS_X509_TRUST_KIND_REJECT_CLIENT | MONO_BTLS_X509_TRUST_KIND_REJECT_SERVER; + + if ((kind & MONO_BTLS_X509_TRUST_KIND_TRUST_ALL) != 0) + kind |= MONO_BTLS_X509_TRUST_KIND_TRUST_CLIENT | MONO_BTLS_X509_TRUST_KIND_TRUST_SERVER; + + + if ((kind & MONO_BTLS_X509_TRUST_KIND_REJECT_CLIENT) != 0) { + ret = mono_btls_x509_add_reject_object (x509, MONO_BTLS_X509_PURPOSE_SSL_CLIENT); + if (!ret) + return ret; + } + + if ((kind & MONO_BTLS_X509_TRUST_KIND_REJECT_SERVER) != 0) { + ret = mono_btls_x509_add_reject_object (x509, MONO_BTLS_X509_PURPOSE_SSL_SERVER); + if (!ret) + return ret; + } + + if (ret) { + // Ignore any MONO_BTLS_X509_TRUST_KIND_TRUST_* settings if we added + // any kind of MONO_BTLS_X509_TRUST_KIND_REJECT_* before. + return ret; + } + + if ((kind & MONO_BTLS_X509_TRUST_KIND_TRUST_CLIENT) != 0) { + ret = mono_btls_x509_add_trust_object (x509, MONO_BTLS_X509_PURPOSE_SSL_CLIENT); + if (!ret) + return ret; + } + + if ((kind & MONO_BTLS_X509_TRUST_KIND_TRUST_SERVER) != 0) { + ret = mono_btls_x509_add_trust_object (x509, MONO_BTLS_X509_PURPOSE_SSL_SERVER); + if (!ret) + return ret; + } + + return ret; +} diff --git a/mono/btls/btls-x509.h b/mono/btls/btls-x509.h new file mode 100644 index 00000000000..a9a9200127d --- /dev/null +++ b/mono/btls/btls-x509.h @@ -0,0 +1,127 @@ +// +// btls-x509.h +// MonoBtls +// +// Created by Martin Baulig on 14/11/15. +// Copyright (c) 2015 Xamarin. All rights reserved. +// + +#ifndef __btls__btls_x509__ +#define __btls__btls_x509__ + +#include +#include +#include + +typedef enum { + MONO_BTLS_X509_FORMAT_DER = 1, + MONO_BTLS_X509_FORMAT_PEM = 2 +} MonoBtlsX509Format; + +typedef enum { + MONO_BTLS_x509_FILE_TYPE_PEM = 1, // X509_FILETYPE_PEM + MONO_BTLS_x509_FILE_TYPE_ASN1 = 2, // X509_FILETYPE_ASN1 + MONO_BTLS_x509_FILE_TYPE_DEFAULT = 3, // X509_FILETYPE_DEFAULT +} MonoBtlsX509FileType; + +typedef enum { + MONO_BTLS_X509_PURPOSE_SSL_CLIENT = 1, + MONO_BTLS_X509_PURPOSE_SSL_SERVER = 2, + MONO_BTLS_X509_PURPOSE_NS_SSL_SERVER = 3, + MONO_BTLS_X509_PURPOSE_SMIME_SIGN = 4, + MONO_BTLS_X509_PURPOSE_SMIME_ENCRYPT = 5, + MONO_BTLS_X509_PURPOSE_CRL_SIGN = 6, + MONO_BTLS_X509_PURPOSE_ANY = 7, + MONO_BTLS_X509_PURPOSE_OCSP_HELPER = 8, + MONO_BTLS_X509_PURPOSE_TIMESTAMP_SIGN = 9, +} MonoBtlsX509Purpose; + +typedef enum { + MONO_BTLS_X509_TRUST_KIND_DEFAULT = 0, + MONO_BTLS_X509_TRUST_KIND_TRUST_CLIENT = 1, + MONO_BTLS_X509_TRUST_KIND_TRUST_SERVER = 2, + MONO_BTLS_X509_TRUST_KIND_TRUST_ALL = 4, + MONO_BTLS_X509_TRUST_KIND_REJECT_CLIENT = 32, + MONO_BTLS_X509_TRUST_KIND_REJECT_SERVER = 64, + MONO_BTLS_X509_TRUST_KIND_REJECT_ALL = 128 +} MonoBtlsX509TrustKind; + +X509 * +mono_btls_x509_from_data (const void *buf, int len, MonoBtlsX509Format format); + +X509 * +mono_btls_x509_up_ref (X509 *x509); + +void +mono_btls_x509_free (X509 *x509); + +X509 * +mono_btls_x509_dup (X509 *x509); + +MonoBtlsX509Name * +mono_btls_x509_get_subject_name (X509 *x509); + +MonoBtlsX509Name * +mono_btls_x509_get_issuer_name (X509 *x509); + +int +mono_btls_x509_get_subject_name_string (X509 *name, char *buffer, int size); + +int +mono_btls_x509_get_issuer_name_string (X509 *name, char *buffer, int size); + +int +mono_btls_x509_get_raw_data (X509 *x509, BIO *bio, MonoBtlsX509Format format); + +int +mono_btls_x509_cmp (const X509 *a, const X509 *b); + +int +mono_btls_x509_get_hash (X509 *x509, const void **data); + +long +mono_btls_x509_get_not_before (X509 *x509); + +long +mono_btls_x509_get_not_after (X509 *x509); + +int +mono_btls_x509_get_public_key (X509 *x509, BIO *bio); + +int +mono_btls_x509_get_public_key_parameters (X509 *x509, char *out_oid, int oid_len, uint8_t **buffer, int *size); + +int +mono_btls_x509_get_serial_number (X509 *x509, char *buffer, int size, int mono_style); + +int +mono_btls_x509_get_public_key_algorithm (X509 *x509, char *buffer, int size); + +int +mono_btls_x509_get_version (X509 *x509); + +int +mono_btls_x509_get_signature_algorithm (X509 *x509, char *buffer, int size); + +int +mono_btls_x509_get_public_key_asn1 (X509 *x509, char *out_oid, int oid_len, uint8_t **buffer, int *size); + +EVP_PKEY * +mono_btls_x509_get_pubkey (X509 *x509); + +int +mono_btls_x509_get_subject_key_identifier (X509 *x509, uint8_t **buffer, int *size); + +int +mono_btls_x509_print (X509 *x509, BIO *bio); + +int +mono_btls_x509_add_trust_object (X509 *x509, MonoBtlsX509Purpose purpose); + +int +mono_btls_x509_add_reject_object (X509 *x509, MonoBtlsX509Purpose purpose); + +int +mono_btls_x509_add_explicit_trust (X509 *x509, MonoBtlsX509TrustKind kind); + +#endif /* defined(__btls__btls_x509__) */ diff --git a/mono/btls/create-object-library.sh b/mono/btls/create-object-library.sh new file mode 100755 index 00000000000..94da6b33f5e --- /dev/null +++ b/mono/btls/create-object-library.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +DIR=$1; shift +FILELIST=$1; shift +LOFILELIST=$1 ; shift +TARGET=$1; shift +STATIC=$1; shift +AR=$1; shift +RANLIB=$1; shift + +HEADER="# Generated by Martin's tool $0, not libtool" + +test -f $TARGET && exit 0 + +rm -f $FILELIST +rm -f $LOFILELIST + +while [ "$1" != "--" ]; do + file=$1; shift + filename=`basename $file` + LOFILE=$file.lo + if [ "$STATIC" = "static" ]; then + echo "$HEADER\nnon_pic_object='$filename'" > $LOFILE + else + echo "$HEADER\npic_object='$filename'" > $LOFILE + fi + echo "$DIR/$file " >> $FILELIST + echo "$DIR/$LOFILE " >> $LOFILELIST +done + +(cd $DIR && $AR cr $TARGET `cat $FILELIST` && $RANLIB $TARGET) + diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am index d541472ada7..60d6b47a321 100644 --- a/mono/metadata/Makefile.am +++ b/mono/metadata/Makefile.am @@ -38,6 +38,14 @@ if PLATFORM_ANDROID platform_sources += ../../support/libm/complex.c endif +if BTLS +btls_file_list := $(shell cat ../btls/build-shared/mono-btls-shared-lo.txt) +btls_static_file_list := $(shell cat ../btls/build-static/mono-btls-static-lo.txt) +btls_libs = $(btls_file_list) +btls_static_libs = $(btls_static_file_list) +btls_cflags = -I$(top_srcdir)/external/boringssl/include -I$(top_srcdir)/mono/btls +endif + # # libtool is not capable of creating static/shared versions of the same # convenience lib, so we have to do it ourselves @@ -70,7 +78,7 @@ else noinst_LTLIBRARIES = libmonoruntime-config.la $(boehm_libraries) $(sgen_libraries) endif -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/mono $(LIBGC_CPPFLAGS) $(GLIB_CFLAGS) $(SHARED_CFLAGS) +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/mono $(LIBGC_CPPFLAGS) $(GLIB_CFLAGS) $(SHARED_CFLAGS) $(btls_cflags) # # Make sure any prefix changes are updated in the binaries too. @@ -270,21 +278,21 @@ sgen_sources = \ libmonoruntime_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(null_gc_sources) $(boehm_sources) libmonoruntime_la_CFLAGS = $(BOEHM_DEFINES) -libmonoruntime_la_LIBADD = libmonoruntime-config.la +libmonoruntime_la_LIBADD = libmonoruntime-config.la $(btls_libs) libmonoruntimesgen_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(sgen_sources) libmonoruntimesgen_la_CFLAGS = $(SGEN_DEFINES) -libmonoruntimesgen_la_LIBADD = libmonoruntime-config.la +libmonoruntimesgen_la_LIBADD = libmonoruntime-config.la $(btls_libs) libmonoruntime_static_la_SOURCES = $(libmonoruntime_la_SOURCES) libmonoruntime_static_la_LDFLAGS = -static libmonoruntime_static_la_CFLAGS = $(BOEHM_DEFINES) -libmonoruntime_static_la_LIBADD = $(bundle_obj) $(libmonoruntime_la_LIBADD) +libmonoruntime_static_la_LIBADD = $(bundle_obj) libmonoruntime-config.la $(btls_static_libs) libmonoruntimesgen_static_la_SOURCES = $(libmonoruntimesgen_la_SOURCES) libmonoruntimesgen_static_la_LDFLAGS = -static libmonoruntimesgen_static_la_CFLAGS = $(SGEN_DEFINES) -libmonoruntimesgen_static_la_LIBADD = $(libmonoruntimesgen_la_LIBADD) +libmonoruntimesgen_static_la_LIBADD = libmonoruntime-config.la $(btls_static_libs) libmonoruntimeincludedir = $(includedir)/mono-$(API_VER)/mono/metadata diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 5ef925009ac..f86eac1c6b7 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -78,6 +78,245 @@ ICALL(NATIVEMETHODS_10, "TerminateProcess", ves_icall_Microsoft_Win32_NativeMeth ICALL(NATIVEMETHODS_11, "WaitForInputIdle", ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle) #endif /* !DISABLE_PROCESS_HANDLING */ +#if HAVE_BTLS +ICALL_TYPE(BTLS_BIO, "Mono.Btls.MonoBtlsBio", BTLS_BIO_1) +ICALL(BTLS_BIO_1, "mono_btls_bio_flush", mono_btls_bio_flush) +ICALL(BTLS_BIO_2, "mono_btls_bio_free", mono_btls_bio_free) +ICALL(BTLS_BIO_3, "mono_btls_bio_hexdump", mono_btls_bio_hexdump) +ICALL(BTLS_BIO_4, "mono_btls_bio_indent", mono_btls_bio_indent) +ICALL(BTLS_BIO_5, "mono_btls_bio_print_errors", mono_btls_bio_print_errors) +ICALL(BTLS_BIO_6, "mono_btls_bio_read", mono_btls_bio_read) +ICALL(BTLS_BIO_7, "mono_btls_bio_write", mono_btls_bio_write) + +ICALL_TYPE(BTLS_BIO_MEM, "Mono.Btls.MonoBtlsBioMemory", BTLS_BIO_MEM_1) +ICALL(BTLS_BIO_MEM_1, "mono_btls_bio_mem_get_data", mono_btls_bio_mem_get_data) +ICALL(BTLS_BIO_MEM_2, "mono_btls_bio_mem_new", mono_btls_bio_mem_new) + +ICALL_TYPE(BTLS_BIO_MONO, "Mono.Btls.MonoBtlsBioMono", BTLS_BIO_MONO_1) +ICALL(BTLS_BIO_MONO_1, "mono_btls_bio_mono_initialize", mono_btls_bio_mono_initialize) +ICALL(BTLS_BIO_MONO_2, "mono_btls_bio_mono_new", mono_btls_bio_mono_new) + +ICALL_TYPE(BTLS_ERROR, "Mono.Btls.MonoBtlsError", BTLS_ERROR_1) +ICALL(BTLS_ERROR_1, "mono_btls_error_clear_error", mono_btls_error_clear_error) +ICALL(BTLS_ERROR_2, "mono_btls_error_get_error", mono_btls_error_get_error) +ICALL(BTLS_ERROR_3, "mono_btls_error_get_error_string_n", mono_btls_error_get_error_string_n) +ICALL(BTLS_ERROR_4, "mono_btls_error_peek_error", mono_btls_error_peek_error) + +ICALL_TYPE(BTLS_KEY, "Mono.Btls.MonoBtlsKey", BTLS_KEY_1) +ICALL(BTLS_KEY_1, "mono_btls_key_free", mono_btls_key_free) +ICALL(BTLS_KEY_2, "mono_btls_key_get_bits", mono_btls_key_get_bits) +ICALL(BTLS_KEY_3, "mono_btls_key_get_bytes", mono_btls_key_get_bytes) +ICALL(BTLS_KEY_4, "mono_btls_key_is_rsa", mono_btls_key_is_rsa) +ICALL(BTLS_KEY_5, "mono_btls_key_test", mono_btls_key_test) +ICALL(BTLS_KEY_6, "mono_btls_key_up_ref", mono_btls_key_up_ref) + +ICALL_TYPE(BTLS_OBJECT, "Mono.Btls.MonoBtlsObject", BTLS_OBJECT_1) +ICALL(BTLS_OBJECT_1, "mono_btls_free", mono_btls_free) + +ICALL_TYPE(BTLS_PKCS12, "Mono.Btls.MonoBtlsPkcs12", BTLS_PKCS12_1) +ICALL(BTLS_PKCS12_1, "mono_btls_pkcs12_add_cert", mono_btls_pkcs12_add_cert) +ICALL(BTLS_PKCS12_2, "mono_btls_pkcs12_free", mono_btls_pkcs12_free) +ICALL(BTLS_PKCS12_3, "mono_btls_pkcs12_get_cert", mono_btls_pkcs12_get_cert) +ICALL(BTLS_PKCS12_4, "mono_btls_pkcs12_get_certs", mono_btls_pkcs12_get_certs) +ICALL(BTLS_PKCS12_5, "mono_btls_pkcs12_get_count", mono_btls_pkcs12_get_count) +ICALL(BTLS_PKCS12_6, "mono_btls_pkcs12_get_private_key", mono_btls_pkcs12_get_private_key) +ICALL(BTLS_PKCS12_7, "mono_btls_pkcs12_has_private_key", mono_btls_pkcs12_has_private_key) +ICALL(BTLS_PKCS12_8, "mono_btls_pkcs12_import", mono_btls_pkcs12_import) +ICALL(BTLS_PKCS12_9, "mono_btls_pkcs12_new", mono_btls_pkcs12_new) +ICALL(BTLS_PKCS12_10, "mono_btls_pkcs12_up_ref", mono_btls_pkcs12_up_ref) + +ICALL_TYPE(BTLS_PROVIDER, "Mono.Btls.MonoBtlsProvider", BTLS_PROVIDER_1) +ICALL(BTLS_PROVIDER_1, "IsSupported", ves_icall_Mono_Btls_Provider_IsSupported) + +ICALL_TYPE(BTLS_SSL, "Mono.Btls.MonoBtlsSsl", BTLS_SSL_1) +ICALL(BTLS_SSL_1, "mono_btls_ssl_accept", mono_btls_ssl_accept) +ICALL(BTLS_SSL_2, "mono_btls_ssl_add_chain_certificate", mono_btls_ssl_add_chain_certificate) +ICALL(BTLS_SSL_3, "mono_btls_ssl_close", mono_btls_ssl_close) +ICALL(BTLS_SSL_4, "mono_btls_ssl_connect", mono_btls_ssl_connect) +ICALL(BTLS_SSL_5, "mono_btls_ssl_destroy", mono_btls_ssl_destroy) +ICALL(BTLS_SSL_6, "mono_btls_ssl_get_cipher", mono_btls_ssl_get_cipher) +ICALL(BTLS_SSL_7, "mono_btls_ssl_get_ciphers", mono_btls_ssl_get_ciphers) +ICALL(BTLS_SSL_8, "mono_btls_ssl_get_error", mono_btls_ssl_get_error) +ICALL(BTLS_SSL_9, "mono_btls_ssl_get_peer_certificate", mono_btls_ssl_get_peer_certificate) +ICALL(BTLS_SSL_10, "mono_btls_ssl_get_version", mono_btls_ssl_get_version) +ICALL(BTLS_SSL_11, "mono_btls_ssl_handshake", mono_btls_ssl_handshake) +ICALL(BTLS_SSL_12, "mono_btls_ssl_new", mono_btls_ssl_new) +ICALL(BTLS_SSL_13, "mono_btls_ssl_print_errors_cb", mono_btls_ssl_print_errors_cb) +ICALL(BTLS_SSL_14, "mono_btls_ssl_read", mono_btls_ssl_read) +ICALL(BTLS_SSL_15, "mono_btls_ssl_set_bio", mono_btls_ssl_set_bio) +ICALL(BTLS_SSL_16, "mono_btls_ssl_set_cipher_list", mono_btls_ssl_set_cipher_list) +ICALL(BTLS_SSL_17, "mono_btls_ssl_set_max_version", mono_btls_ssl_set_max_version) +ICALL(BTLS_SSL_18, "mono_btls_ssl_set_min_version", mono_btls_ssl_set_min_version) +ICALL(BTLS_SSL_19, "mono_btls_ssl_set_verify_param", mono_btls_ssl_set_verify_param) +ICALL(BTLS_SSL_20, "mono_btls_ssl_test", mono_btls_ssl_test) +ICALL(BTLS_SSL_21, "mono_btls_ssl_use_certificate", mono_btls_ssl_use_certificate) +ICALL(BTLS_SSL_22, "mono_btls_ssl_use_private_key", mono_btls_ssl_use_private_key) +ICALL(BTLS_SSL_23, "mono_btls_ssl_write", mono_btls_ssl_write) + +ICALL_TYPE(BTLS_SSL_CTX, "Mono.Btls.MonoBtlsSslCtx", BTLS_SSL_CTX_1) +ICALL(BTLS_SSL_CTX_1, "mono_btls_ssl_ctx_debug_printf", mono_btls_ssl_ctx_debug_printf) +ICALL(BTLS_SSL_CTX_2, "mono_btls_ssl_ctx_free", mono_btls_ssl_ctx_free) +ICALL(BTLS_SSL_CTX_3, "mono_btls_ssl_ctx_get_ctx", mono_btls_ssl_ctx_get_ctx) +ICALL(BTLS_SSL_CTX_4, "mono_btls_ssl_ctx_initialize", mono_btls_ssl_ctx_initialize) +ICALL(BTLS_SSL_CTX_5, "mono_btls_ssl_ctx_is_cipher_supported", mono_btls_ssl_ctx_is_cipher_supported) +ICALL(BTLS_SSL_CTX_6, "mono_btls_ssl_ctx_is_debug_enabled", mono_btls_ssl_ctx_is_debug_enabled) +ICALL(BTLS_SSL_CTX_7, "mono_btls_ssl_ctx_new", mono_btls_ssl_ctx_new) +ICALL(BTLS_SSL_CTX_8, "mono_btls_ssl_ctx_peek_store", mono_btls_ssl_ctx_peek_store) +ICALL(BTLS_SSL_CTX_9, "mono_btls_ssl_ctx_set_cert_select_callback", mono_btls_ssl_ctx_set_cert_select_callback) +ICALL(BTLS_SSL_CTX_10, "mono_btls_ssl_ctx_set_cert_verify_callback", mono_btls_ssl_ctx_set_cert_verify_callback) +ICALL(BTLS_SSL_CTX_11, "mono_btls_ssl_ctx_set_ciphers", mono_btls_ssl_ctx_set_ciphers) +ICALL(BTLS_SSL_CTX_12, "mono_btls_ssl_ctx_set_debug_bio", mono_btls_ssl_ctx_set_debug_bio) +ICALL(BTLS_SSL_CTX_13, "mono_btls_ssl_ctx_set_max_version", mono_btls_ssl_ctx_set_max_version) +ICALL(BTLS_SSL_CTX_14, "mono_btls_ssl_ctx_set_min_version", mono_btls_ssl_ctx_set_min_version) +ICALL(BTLS_SSL_CTX_15, "mono_btls_ssl_ctx_set_verify_param", mono_btls_ssl_ctx_set_verify_param) +ICALL(BTLS_SSL_CTX_16, "mono_btls_ssl_ctx_up_ref", mono_btls_ssl_ctx_up_ref) + +ICALL_TYPE(BTLS_X509, "Mono.Btls.MonoBtlsX509", BTLS_X509_1) +ICALL(BTLS_X509_1, "mono_btls_x509_add_explicit_trust", mono_btls_x509_add_explicit_trust) +ICALL(BTLS_X509_2, "mono_btls_x509_add_reject_object", mono_btls_x509_add_reject_object) +ICALL(BTLS_X509_3, "mono_btls_x509_add_trust_object", mono_btls_x509_add_trust_object) +ICALL(BTLS_X509_4, "mono_btls_x509_cmp", mono_btls_x509_cmp) +ICALL(BTLS_X509_5, "mono_btls_x509_dup", mono_btls_x509_dup) +ICALL(BTLS_X509_6, "mono_btls_x509_free", mono_btls_x509_free) +ICALL(BTLS_X509_7, "mono_btls_x509_from_data", mono_btls_x509_from_data) +ICALL(BTLS_X509_8, "mono_btls_x509_get_hash", mono_btls_x509_get_hash) +ICALL(BTLS_X509_9, "mono_btls_x509_get_issuer_name", mono_btls_x509_get_issuer_name) +ICALL(BTLS_X509_10, "mono_btls_x509_get_issuer_name_string", mono_btls_x509_get_issuer_name_string) +ICALL(BTLS_X509_11, "mono_btls_x509_get_not_after", mono_btls_x509_get_not_after) +ICALL(BTLS_X509_12, "mono_btls_x509_get_not_before", mono_btls_x509_get_not_before) +ICALL(BTLS_X509_13, "mono_btls_x509_get_pubkey", mono_btls_x509_get_pubkey) +ICALL(BTLS_X509_14, "mono_btls_x509_get_public_key", mono_btls_x509_get_public_key) +ICALL(BTLS_X509_15, "mono_btls_x509_get_public_key_algorithm", mono_btls_x509_get_public_key_algorithm) +ICALL(BTLS_X509_16, "mono_btls_x509_get_public_key_asn1", mono_btls_x509_get_public_key_asn1) +ICALL(BTLS_X509_17, "mono_btls_x509_get_public_key_parameters", mono_btls_x509_get_public_key_parameters) +ICALL(BTLS_X509_18, "mono_btls_x509_get_raw_data", mono_btls_x509_get_raw_data) +ICALL(BTLS_X509_19, "mono_btls_x509_get_serial_number", mono_btls_x509_get_serial_number) +ICALL(BTLS_X509_20, "mono_btls_x509_get_signature_algorithm", mono_btls_x509_get_signature_algorithm) +ICALL(BTLS_X509_21, "mono_btls_x509_get_subject_key_identifier", mono_btls_x509_get_subject_key_identifier) +ICALL(BTLS_X509_22, "mono_btls_x509_get_subject_name", mono_btls_x509_get_subject_name) +ICALL(BTLS_X509_23, "mono_btls_x509_get_subject_name_string", mono_btls_x509_get_subject_name_string) +ICALL(BTLS_X509_24, "mono_btls_x509_get_version", mono_btls_x509_get_version) +ICALL(BTLS_X509_25, "mono_btls_x509_print", mono_btls_x509_print) +ICALL(BTLS_X509_26, "mono_btls_x509_up_ref", mono_btls_x509_up_ref) + +ICALL_TYPE(BTLS_X509_CHAIN, "Mono.Btls.MonoBtlsX509Chain", BTLS_X509_CHAIN_1) +ICALL(BTLS_X509_CHAIN_1, "mono_btls_x509_chain_add_cert", mono_btls_x509_chain_add_cert) +ICALL(BTLS_X509_CHAIN_2, "mono_btls_x509_chain_free", mono_btls_x509_chain_free) +ICALL(BTLS_X509_CHAIN_3, "mono_btls_x509_chain_from_certs", mono_btls_x509_chain_from_certs) +ICALL(BTLS_X509_CHAIN_4, "mono_btls_x509_chain_get_cert", mono_btls_x509_chain_get_cert) +ICALL(BTLS_X509_CHAIN_5, "mono_btls_x509_chain_get_count", mono_btls_x509_chain_get_count) +ICALL(BTLS_X509_CHAIN_6, "mono_btls_x509_chain_new", mono_btls_x509_chain_new) +ICALL(BTLS_X509_CHAIN_7, "mono_btls_x509_chain_peek_certs", mono_btls_x509_chain_peek_certs) +ICALL(BTLS_X509_CHAIN_8, "mono_btls_x509_chain_up_ref", mono_btls_x509_chain_up_ref) + +ICALL_TYPE(BTLS_X509_CRL, "Mono.Btls.MonoBtlsX509Crl", BTLS_X509_CRL_1) +ICALL(BTLS_X509_CRL_1, "mono_btls_x509_crl_free", mono_btls_x509_crl_free) +ICALL(BTLS_X509_CRL_2, "mono_btls_x509_crl_from_data", mono_btls_x509_crl_from_data) +ICALL(BTLS_X509_CRL_3, "mono_btls_x509_crl_get_by_cert", mono_btls_x509_crl_get_by_cert) +ICALL(BTLS_X509_CRL_4, "mono_btls_x509_crl_get_by_serial", mono_btls_x509_crl_get_by_serial) +ICALL(BTLS_X509_CRL_5, "mono_btls_x509_crl_get_issuer", mono_btls_x509_crl_get_issuer) +ICALL(BTLS_X509_CRL_6, "mono_btls_x509_crl_get_last_update", mono_btls_x509_crl_get_last_update) +ICALL(BTLS_X509_CRL_7, "mono_btls_x509_crl_get_next_update", mono_btls_x509_crl_get_next_update) +ICALL(BTLS_X509_CRL_8, "mono_btls_x509_crl_get_revoked", mono_btls_x509_crl_get_revoked) +ICALL(BTLS_X509_CRL_9, "mono_btls_x509_crl_get_revoked_count", mono_btls_x509_crl_get_revoked_count) +ICALL(BTLS_X509_CRL_10, "mono_btls_x509_crl_get_version", mono_btls_x509_crl_get_version) +ICALL(BTLS_X509_CRL_11, "mono_btls_x509_crl_ref", mono_btls_x509_crl_ref) + +ICALL_TYPE(BTLS_X509_LOOKUP, "Mono.Btls.MonoBtlsX509Lookup", BTLS_X509_LOOKUP_1) +ICALL(BTLS_X509_LOOKUP_1, "mono_btls_x509_lookup_add_dir", mono_btls_x509_lookup_add_dir) +ICALL(BTLS_X509_LOOKUP_2, "mono_btls_x509_lookup_add_mono", mono_btls_x509_lookup_add_mono) +ICALL(BTLS_X509_LOOKUP_3, "mono_btls_x509_lookup_by_fingerprint", mono_btls_x509_lookup_by_fingerprint) +ICALL(BTLS_X509_LOOKUP_4, "mono_btls_x509_lookup_by_subject", mono_btls_x509_lookup_by_subject) +ICALL(BTLS_X509_LOOKUP_5, "mono_btls_x509_lookup_free", mono_btls_x509_lookup_free) +ICALL(BTLS_X509_LOOKUP_6, "mono_btls_x509_lookup_init", mono_btls_x509_lookup_init) +ICALL(BTLS_X509_LOOKUP_7, "mono_btls_x509_lookup_load_file", mono_btls_x509_lookup_load_file) +ICALL(BTLS_X509_LOOKUP_8, "mono_btls_x509_lookup_mono_init", mono_btls_x509_lookup_mono_init) +ICALL(BTLS_X509_LOOKUP_9, "mono_btls_x509_lookup_new", mono_btls_x509_lookup_new) +ICALL(BTLS_X509_LOOKUP_10, "mono_btls_x509_lookup_peek_lookup", mono_btls_x509_lookup_peek_lookup) +ICALL(BTLS_X509_LOOKUP_11, "mono_btls_x509_lookup_shutdown", mono_btls_x509_lookup_shutdown) +ICALL(BTLS_X509_LOOKUP_12, "mono_btls_x509_lookup_up_ref", mono_btls_x509_lookup_up_ref) + +ICALL_TYPE(BTLS_X509_LOOKUP_MONO, "Mono.Btls.MonoBtlsX509LookupMono", BTLS_X509_LOOKUP_MONO_1) +ICALL(BTLS_X509_LOOKUP_MONO_1, "mono_btls_x509_lookup_mono_free", mono_btls_x509_lookup_mono_free) +ICALL(BTLS_X509_LOOKUP_MONO_2, "mono_btls_x509_lookup_mono_init", mono_btls_x509_lookup_mono_init) +ICALL(BTLS_X509_LOOKUP_MONO_3, "mono_btls_x509_lookup_mono_new", mono_btls_x509_lookup_mono_new) + +ICALL_TYPE(BTLS_X509_NAME, "Mono.Btls.MonoBtlsX509Name", BTLS_X509_NAME_1) +ICALL(BTLS_X509_NAME_1, "mono_btls_x509_name_copy", mono_btls_x509_name_copy) +ICALL(BTLS_X509_NAME_2, "mono_btls_x509_name_free", mono_btls_x509_name_free) +ICALL(BTLS_X509_NAME_3, "mono_btls_x509_name_from_data", mono_btls_x509_name_from_data) +ICALL(BTLS_X509_NAME_4, "mono_btls_x509_name_from_name", mono_btls_x509_name_from_name) +ICALL(BTLS_X509_NAME_5, "mono_btls_x509_name_get_entry_count", mono_btls_x509_name_get_entry_count) +ICALL(BTLS_X509_NAME_6, "mono_btls_x509_name_get_entry_oid", mono_btls_x509_name_get_entry_oid) +ICALL(BTLS_X509_NAME_7, "mono_btls_x509_name_get_entry_oid_data", mono_btls_x509_name_get_entry_oid_data) +ICALL(BTLS_X509_NAME_8, "mono_btls_x509_name_get_entry_type", mono_btls_x509_name_get_entry_type) +ICALL(BTLS_X509_NAME_9, "mono_btls_x509_name_get_entry_value", mono_btls_x509_name_get_entry_value) +ICALL(BTLS_X509_NAME_10, "mono_btls_x509_name_get_raw_data", mono_btls_x509_name_get_raw_data) +ICALL(BTLS_X509_NAME_11, "mono_btls_x509_name_hash", mono_btls_x509_name_hash) +ICALL(BTLS_X509_NAME_12, "mono_btls_x509_name_hash_old", mono_btls_x509_name_hash_old) +ICALL(BTLS_X509_NAME_13, "mono_btls_x509_name_peek_name", mono_btls_x509_name_peek_name) +ICALL(BTLS_X509_NAME_14, "mono_btls_x509_name_print_bio", mono_btls_x509_name_print_bio) +ICALL(BTLS_X509_NAME_15, "mono_btls_x509_name_print_string", mono_btls_x509_name_print_string) + +ICALL_TYPE(BTLS_X509_REVOKED, "Mono.Btls.MonoBtlsX509Revoked", BTLS_X509_REVOKED_1) +ICALL(BTLS_X509_REVOKED_1, "mono_btls_x509_revoked_free", mono_btls_x509_revoked_free) +ICALL(BTLS_X509_REVOKED_2, "mono_btls_x509_revoked_get_reason", mono_btls_x509_revoked_get_reason) +ICALL(BTLS_X509_REVOKED_3, "mono_btls_x509_revoked_get_sequence", mono_btls_x509_revoked_get_sequence) +ICALL(BTLS_X509_REVOKED_4, "mono_btls_x509_revoked_get_serial_number", mono_btls_x509_revoked_get_serial_number) +ICALL(BTLS_X509_REVOKED_5, "mono_btls_x509_revoked_new", mono_btls_x509_revoked_new) + +ICALL_TYPE(BTLS_X509_STORE, "Mono.Btls.MonoBtlsX509Store", BTLS_X509_STORE_1) +ICALL(BTLS_X509_STORE_1, "mono_btls_x509_store_add_cert", mono_btls_x509_store_add_cert) +ICALL(BTLS_X509_STORE_2, "mono_btls_x509_store_free", mono_btls_x509_store_free) +ICALL(BTLS_X509_STORE_3, "mono_btls_x509_store_from_ctx", mono_btls_x509_store_from_ctx) +ICALL(BTLS_X509_STORE_4, "mono_btls_x509_store_from_ssl_ctx", mono_btls_x509_store_from_ssl_ctx) +ICALL(BTLS_X509_STORE_5, "mono_btls_x509_store_get_count", mono_btls_x509_store_get_count) +ICALL(BTLS_X509_STORE_6, "mono_btls_x509_store_load_locations", mono_btls_x509_store_load_locations) +ICALL(BTLS_X509_STORE_7, "mono_btls_x509_store_new", mono_btls_x509_store_new) +ICALL(BTLS_X509_STORE_8, "mono_btls_x509_store_peek_store", mono_btls_x509_store_peek_store) +ICALL(BTLS_X509_STORE_9, "mono_btls_x509_store_set_default_paths", mono_btls_x509_store_set_default_paths) +ICALL(BTLS_X509_STORE_10, "mono_btls_x509_store_up_ref", mono_btls_x509_store_up_ref) + +ICALL_TYPE(BTLS_X509_STORE_CTX, "Mono.Btls.MonoBtlsX509StoreCtx", BTLS_X509_STORE_CTX_1) +ICALL(BTLS_X509_STORE_CTX_1, "mono_btls_x509_store_ctx_free", mono_btls_x509_store_ctx_free) +ICALL(BTLS_X509_STORE_CTX_2, "mono_btls_x509_store_ctx_from_ptr", mono_btls_x509_store_ctx_from_ptr) +ICALL(BTLS_X509_STORE_CTX_3, "mono_btls_x509_store_ctx_get_by_subject", mono_btls_x509_store_ctx_get_by_subject) +ICALL(BTLS_X509_STORE_CTX_4, "mono_btls_x509_store_ctx_get_chain", mono_btls_x509_store_ctx_get_chain) +ICALL(BTLS_X509_STORE_CTX_5, "mono_btls_x509_store_ctx_get_current_cert", mono_btls_x509_store_ctx_get_current_cert) +ICALL(BTLS_X509_STORE_CTX_6, "mono_btls_x509_store_ctx_get_current_issuer", mono_btls_x509_store_ctx_get_current_issuer) +ICALL(BTLS_X509_STORE_CTX_7, "mono_btls_x509_store_ctx_get_error", mono_btls_x509_store_ctx_get_error) +ICALL(BTLS_X509_STORE_CTX_8, "mono_btls_x509_store_ctx_get_error_depth", mono_btls_x509_store_ctx_get_error_depth) +ICALL(BTLS_X509_STORE_CTX_9, "mono_btls_x509_store_ctx_get_untrusted", mono_btls_x509_store_ctx_get_untrusted) +ICALL(BTLS_X509_STORE_CTX_10, "mono_btls_x509_store_ctx_get_verify_param", mono_btls_x509_store_ctx_get_verify_param) +ICALL(BTLS_X509_STORE_CTX_11, "mono_btls_x509_store_ctx_init", mono_btls_x509_store_ctx_init) +ICALL(BTLS_X509_STORE_CTX_12, "mono_btls_x509_store_ctx_new", mono_btls_x509_store_ctx_new) +ICALL(BTLS_X509_STORE_CTX_13, "mono_btls_x509_store_ctx_set_param", mono_btls_x509_store_ctx_set_param) +ICALL(BTLS_X509_STORE_CTX_14, "mono_btls_x509_store_ctx_test", mono_btls_x509_store_ctx_test) +ICALL(BTLS_X509_STORE_CTX_15, "mono_btls_x509_store_ctx_up_ref", mono_btls_x509_store_ctx_up_ref) +ICALL(BTLS_X509_STORE_CTX_16, "mono_btls_x509_store_ctx_verify_cert", mono_btls_x509_store_ctx_verify_cert) + +ICALL_TYPE(BTLS_X509_VERIFY_PARAM, "Mono.Btls.MonoBtlsX509VerifyParam", BTLS_X509_VERIFY_PARAM_1) +ICALL(BTLS_X509_VERIFY_PARAM_1, "mono_btls_x509_verify_param_add_host", mono_btls_x509_verify_param_add_host) +ICALL(BTLS_X509_VERIFY_PARAM_2, "mono_btls_x509_verify_param_can_modify", mono_btls_x509_verify_param_can_modify) +ICALL(BTLS_X509_VERIFY_PARAM_3, "mono_btls_x509_verify_param_copy", mono_btls_x509_verify_param_copy) +ICALL(BTLS_X509_VERIFY_PARAM_4, "mono_btls_x509_verify_param_free", mono_btls_x509_verify_param_free) +ICALL(BTLS_X509_VERIFY_PARAM_5, "mono_btls_x509_verify_param_from_store_ctx", mono_btls_x509_verify_param_from_store_ctx) +ICALL(BTLS_X509_VERIFY_PARAM_6, "mono_btls_x509_verify_param_get_depth", mono_btls_x509_verify_param_get_depth) +ICALL(BTLS_X509_VERIFY_PARAM_7, "mono_btls_x509_verify_param_get_flags", mono_btls_x509_verify_param_get_flags) +ICALL(BTLS_X509_VERIFY_PARAM_8, "mono_btls_x509_verify_param_get_mono_flags", mono_btls_x509_verify_param_get_mono_flags) +ICALL(BTLS_X509_VERIFY_PARAM_9, "mono_btls_x509_verify_param_get_peername", mono_btls_x509_verify_param_get_peername) +ICALL(BTLS_X509_VERIFY_PARAM_10, "mono_btls_x509_verify_param_lookup", mono_btls_x509_verify_param_lookup) +ICALL(BTLS_X509_VERIFY_PARAM_11, "mono_btls_x509_verify_param_new", mono_btls_x509_verify_param_new) +ICALL(BTLS_X509_VERIFY_PARAM_12, "mono_btls_x509_verify_param_peek_param", mono_btls_x509_verify_param_peek_param) +ICALL(BTLS_X509_VERIFY_PARAM_13, "mono_btls_x509_verify_param_set_depth", mono_btls_x509_verify_param_set_depth) +ICALL(BTLS_X509_VERIFY_PARAM_14, "mono_btls_x509_verify_param_set_flags", mono_btls_x509_verify_param_set_flags) +ICALL(BTLS_X509_VERIFY_PARAM_15, "mono_btls_x509_verify_param_set_host", mono_btls_x509_verify_param_set_host) +ICALL(BTLS_X509_VERIFY_PARAM_16, "mono_btls_x509_verify_param_set_mono_flags", mono_btls_x509_verify_param_set_mono_flags) +ICALL(BTLS_X509_VERIFY_PARAM_17, "mono_btls_x509_verify_param_set_name", mono_btls_x509_verify_param_set_name) +ICALL(BTLS_X509_VERIFY_PARAM_18, "mono_btls_x509_verify_param_set_purpose", mono_btls_x509_verify_param_set_purpose) +ICALL(BTLS_X509_VERIFY_PARAM_19, "mono_btls_x509_verify_param_set_time", mono_btls_x509_verify_param_set_time) +#endif + #ifndef DISABLE_COM ICALL_TYPE(COMPROX, "Mono.Interop.ComInteropProxy", COMPROX_1) ICALL(COMPROX_1, "AddProxy", ves_icall_Mono_Interop_ComInteropProxy_AddProxy) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 4e5d773cb73..27bafb33291 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -112,6 +112,22 @@ #include #endif +#if HAVE_BTLS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + extern MonoString* ves_icall_System_Environment_GetOSVersionString (void); ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void); @@ -8077,6 +8093,16 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3 return SetPriorityClass (handle, priorityClass); } +ICALL_EXPORT MonoBoolean +ves_icall_Mono_Btls_Provider_IsSupported (void) +{ +#if HAVE_BTLS + return TRUE; +#else + return FALSE; +#endif +} + #ifndef DISABLE_ICALL_TABLES #define ICALL_TYPE(id,name,first) -- 2.25.1