[BTLS]: Add the native BTLS sources.
authorMartin Baulig <martin.baulig@xamarin.com>
Fri, 30 Sep 2016 09:46:46 +0000 (11:46 +0200)
committerMartin Baulig <martin.baulig@xamarin.com>
Fri, 30 Sep 2016 09:46:46 +0000 (11:46 +0200)
46 files changed:
.gitmodules
configure.ac
external/boringssl [new submodule]
mono/Makefile.am
mono/btls/.gitignore [new file with mode: 0644]
mono/btls/CMakeLists.txt [new file with mode: 0644]
mono/btls/Makefile.am [new file with mode: 0644]
mono/btls/btls-android-utils.c [new file with mode: 0644]
mono/btls/btls-bio.c [new file with mode: 0644]
mono/btls/btls-bio.h [new file with mode: 0644]
mono/btls/btls-error.c [new file with mode: 0644]
mono/btls/btls-error.h [new file with mode: 0644]
mono/btls/btls-key.c [new file with mode: 0644]
mono/btls/btls-key.h [new file with mode: 0644]
mono/btls/btls-pkcs12.c [new file with mode: 0644]
mono/btls/btls-pkcs12.h [new file with mode: 0644]
mono/btls/btls-ssl-ctx.c [new file with mode: 0644]
mono/btls/btls-ssl-ctx.h [new file with mode: 0644]
mono/btls/btls-ssl.c [new file with mode: 0644]
mono/btls/btls-ssl.h [new file with mode: 0644]
mono/btls/btls-util.c [new file with mode: 0644]
mono/btls/btls-util.h [new file with mode: 0644]
mono/btls/btls-x509-chain.c [new file with mode: 0644]
mono/btls/btls-x509-chain.h [new file with mode: 0644]
mono/btls/btls-x509-crl.c [new file with mode: 0644]
mono/btls/btls-x509-crl.h [new file with mode: 0644]
mono/btls/btls-x509-lookup-mono.c [new file with mode: 0644]
mono/btls/btls-x509-lookup-mono.h [new file with mode: 0644]
mono/btls/btls-x509-lookup.c [new file with mode: 0644]
mono/btls/btls-x509-lookup.h [new file with mode: 0644]
mono/btls/btls-x509-name.c [new file with mode: 0644]
mono/btls/btls-x509-name.h [new file with mode: 0644]
mono/btls/btls-x509-revoked.c [new file with mode: 0644]
mono/btls/btls-x509-revoked.h [new file with mode: 0644]
mono/btls/btls-x509-store-ctx.c [new file with mode: 0644]
mono/btls/btls-x509-store-ctx.h [new file with mode: 0644]
mono/btls/btls-x509-store.c [new file with mode: 0644]
mono/btls/btls-x509-store.h [new file with mode: 0644]
mono/btls/btls-x509-verify-param.c [new file with mode: 0644]
mono/btls/btls-x509-verify-param.h [new file with mode: 0644]
mono/btls/btls-x509.c [new file with mode: 0644]
mono/btls/btls-x509.h [new file with mode: 0644]
mono/btls/create-object-library.sh [new file with mode: 0755]
mono/metadata/Makefile.am
mono/metadata/icall-def.h
mono/metadata/icall.c

index d084d3948e49230f088e7e875dd49c409901a7b9..6d87209417eec370475d4ece03cc108c5ea06dd4 100644 (file)
@@ -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
index 0946284c263312177f477509f9048670d0f1751f..7700a3fa1e54b2f6b685d7ac2ec73caa7b62a483 100644 (file)
@@ -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 (submodule)
index 0000000..bb4fcdf
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit bb4fcdfaaa6190109f3e2413195cdc62fec30d82
index 7bf7b5c3dedfa0122abb5dba36dd6120370cb231..651271c25f895fe4a332287feba54f1eed76833f 100644 (file)
@@ -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 (file)
index 0000000..545f630
--- /dev/null
@@ -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 (file)
index 0000000..7679aaa
--- /dev/null
@@ -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} <OBJECTS> --"
+       )
+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} <OBJECTS> --"
+       )
+endif ()
+
diff --git a/mono/btls/Makefile.am b/mono/btls/Makefile.am
new file mode 100644 (file)
index 0000000..064a05d
--- /dev/null
@@ -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 (file)
index 0000000..df30f85
--- /dev/null
@@ -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 <asm/unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#if !defined(__LP64__)
+#include <time64.h>
+#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 (file)
index 0000000..5af2d86
--- /dev/null
@@ -0,0 +1,206 @@
+//
+//  btls-bio.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 14/11/15.
+//  Copyright (c) 2015 Xamarin. All rights reserved.
+//
+
+#include <btls-ssl.h>
+#include <btls-bio.h>
+#include <errno.h>
+
+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 (file)
index 0000000..d4429f6
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+
+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 (file)
index 0000000..8ed950c
--- /dev/null
@@ -0,0 +1,35 @@
+//
+//  btls-error.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 6/19/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-error.h>
+#include <assert.h>
+
+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 (file)
index 0000000..6f791c3
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/ssl.h>
+
+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 (file)
index 0000000..708abe4
--- /dev/null
@@ -0,0 +1,83 @@
+//
+//  btls-key.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/7/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-key.h>
+
+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 (file)
index 0000000..a262d6a
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+
+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 (file)
index 0000000..d037ddb
--- /dev/null
@@ -0,0 +1,101 @@
+//
+//  btls-pkcs12.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/8/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-pkcs12.h>
+#include <openssl/pkcs12.h>
+
+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 (file)
index 0000000..20c4fd9
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+
+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 (file)
index 0000000..ddbb02f
--- /dev/null
@@ -0,0 +1,255 @@
+//
+//  btls-ssl-ctx.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 4/11/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-ssl-ctx.h>
+#include <btls-x509-verify-param.h>
+
+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 (file)
index 0000000..0954192
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/ssl.h>
+#include <btls-util.h>
+
+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 (file)
index 0000000..ddb88d6
--- /dev/null
@@ -0,0 +1,229 @@
+//
+//  btls-ssl.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 14/11/15.
+//  Copyright (c) 2015 Xamarin. All rights reserved.
+//
+
+#include <btls-ssl.h>
+#include <btls-x509-verify-param.h>
+
+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 (file)
index 0000000..1557995
--- /dev/null
@@ -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 <btls-ssl-ctx.h>
+
+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 (file)
index 0000000..d28763a
--- /dev/null
@@ -0,0 +1,76 @@
+//
+//  btls-util.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/23/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-util.h>
+#include <assert.h>
+#include <time.h>
+
+#if defined(__ANDROID__) && !defined(__LP64__)
+#include <time64.h>
+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 (file)
index 0000000..a77bfcd
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/ssl.h>
+
+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 (file)
index 0000000..0584791
--- /dev/null
@@ -0,0 +1,96 @@
+//
+//  btls-x509-chain.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/3/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-x509-chain.h>
+
+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 (file)
index 0000000..68ef577
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+
+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 (file)
index 0000000..ccd3e28
--- /dev/null
@@ -0,0 +1,150 @@
+//
+//  btls-x509-crl.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/23/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-x509-crl.h>
+#include <btls-x509-revoked.h>
+
+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 (file)
index 0000000..0813fe5
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+
+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 (file)
index 0000000..cce7368
--- /dev/null
@@ -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 <btls-x509-lookup.h>
+#include <btls-x509-lookup-mono.h>
+#include <openssl/stack.h>
+
+// 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 (file)
index 0000000..06df552
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+#include <btls-x509-store.h>
+
+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 (file)
index 0000000..1cfc174
--- /dev/null
@@ -0,0 +1,160 @@
+//
+//  btls-x509-lookup.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/6/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-x509-lookup.h>
+#include <btls-x509-lookup-mono.h>
+
+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 (file)
index 0000000..df3d37f
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+#include <btls-x509-store.h>
+
+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 (file)
index 0000000..d76d885
--- /dev/null
@@ -0,0 +1,294 @@
+//
+//  btls-x509-name.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/5/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-x509-name.h>
+
+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 (file)
index 0000000..20c6a68
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+
+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 (file)
index 0000000..e6fb4b0
--- /dev/null
@@ -0,0 +1,72 @@
+//
+//  btls-x509-revoked.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/23/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-x509-revoked.h>
+
+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 (file)
index 0000000..e1229c6
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509-crl.h>
+
+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 (file)
index 0000000..8ed77d0
--- /dev/null
@@ -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 <btls-x509-store-ctx.h>
+
+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 (file)
index 0000000..c5ed499
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509-chain.h>
+#include <btls-x509-name.h>
+#include <btls-x509-store.h>
+#include <btls-x509-verify-param.h>
+
+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 (file)
index 0000000..f2c826e
--- /dev/null
@@ -0,0 +1,110 @@
+//
+//  btls-x509-store.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 3/3/16.
+//  Copyright Â© 2016 Xamarin. All rights reserved.
+//
+
+#include <btls-x509-store.h>
+
+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 (file)
index 0000000..67ffe00
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+
+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 (file)
index 0000000..643fdcd
--- /dev/null
@@ -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 <btls-x509-verify-param.h>
+#include <btls-x509-store-ctx.h>
+
+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 (file)
index 0000000..6f4f1b5
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509.h>
+
+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 (file)
index 0000000..5417422
--- /dev/null
@@ -0,0 +1,436 @@
+//
+//  btls-x509.c
+//  MonoBtls
+//
+//  Created by Martin Baulig on 14/11/15.
+//  Copyright (c) 2015 Xamarin. All rights reserved.
+//
+
+#include <btls-x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pkcs12.h>
+
+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 (file)
index 0000000..a9a9200
--- /dev/null
@@ -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 <stdio.h>
+#include <btls-ssl.h>
+#include <btls-x509-name.h>
+
+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 (executable)
index 0000000..94da6b3
--- /dev/null
@@ -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)
+
index d541472ada7a675f588cbd457f4b44b5887ed3ee..60d6b47a321a2c0de23a36b3034e2f82f2c8962c 100644 (file)
@@ -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
 
index 5ef925009ac74bbc211215fe8752f0a75022828a..f86eac1c6b745d818f6f8fb12aeac888168e7ffd 100644 (file)
@@ -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)
index 4e5d773cb73447db0fb8e0f8cc4e80689d21b15b..27bafb33291f7151a889412b11f11102bf7f4883 100644 (file)
 #include <sys/utsname.h>
 #endif
 
+#if HAVE_BTLS
+#include <btls/btls-ssl.h>
+#include <btls/btls-bio.h>
+#include <btls/btls-error.h>
+#include <btls/btls-key.h>
+#include <btls/btls-pkcs12.h>
+#include <btls/btls-x509-crl.h>
+#include <btls/btls-x509-chain.h>
+#include <btls/btls-x509-lookup.h>
+#include <btls/btls-x509-lookup-mono.h>
+#include <btls/btls-x509-name.h>
+#include <btls/btls-x509-revoked.h>
+#include <btls/btls-x509-store-ctx.h>
+#include <btls/btls-x509-verify-param.h>
+#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)