aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile3
-rw-r--r--config.h.guess881
-rw-r--r--doc/luaossl.tex8
-rwxr-xr-xexamples/vrfy.sig16
-rwxr-xr-xmk/luapath (renamed from mk/lua.path)538
-rwxr-xr-xregress/00-store-verify.lua19
-rw-r--r--regress/53-csr-extensions.lua168
-rw-r--r--regress/regress.lua161
-rw-r--r--src/GNUmakefile9
-rw-r--r--src/openssl.auxlib.lua21
-rw-r--r--src/openssl.c1004
-rw-r--r--src/openssl.x509.altname.lua3
-rw-r--r--src/openssl.x509.name.lua3
13 files changed, 2462 insertions, 372 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 2955d86..c58686c 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -133,6 +133,9 @@ endif
#
include $(d)/src/GNUmakefile
+$(d)/config.h: $(d)/config.h.guess
+ $(CP) $< $@
+
#
# C L E A N R U L E S
diff --git a/config.h.guess b/config.h.guess
new file mode 100644
index 0000000..9b5fcdc
--- /dev/null
+++ b/config.h.guess
@@ -0,0 +1,881 @@
+/* ==========================================================================
+ * config.h.guess - Preprocessor-based feature detection
+ * --------------------------------------------------------------------------
+ * Copyright (c) 2015-2016 William Ahern
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the
+ * following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ==========================================================================
+ */
+#ifndef CONFIG_H_GUESS
+#define CONFIG_H_GUESS
+
+/*
+ * A U T O G U E S S V E R S I O N
+ *
+ * Change AG_VENDOR if maintaining a fork.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define AG_VENDOR "william+autoguess@25thandClement.com"
+#define AG_VERSION 20161019L
+
+
+/*
+ * C O M P I L E R V E N D O R / V E R S I O N D E T E C T I O N
+ *
+ * See http://sourceforge.net/p/predef/wiki/Compilers/
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define AG_GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
+#define AG_GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && AG_GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= AG_GNUC_2VER((M), (m), (p)))
+
+#define AG_MSC_2VER(M, m, p) ((((M) + 6) * 10000000) + ((m) * 1000000) + (p))
+#define AG_MSC_PREREQ(M, m, p) (_MSC_VER_FULL > 0 && _MSC_VER_FULL >= AG_MSC_2VER((M), (m), (p)))
+
+#define AG_SUNPRO_PREREQ(M, m, p) (__SUNPRO_C > 0 && __SUNPRO_C >= 0x ## M ## m ## p)
+
+
+/*
+ * C O M P I L E R / L A N G U A G E F E A T U R E D E T E C T I O N
+ *
+ * NOTE: The has_ and test_ macros are separate because if the test
+ * expression uses the preprocessor "defined" operator the operand
+ * identifier may be replaced before the expression is evaluated. Most tests
+ * will only use arithmetic operations, but if this is not possible then the
+ * test must be written inline, for example
+ *
+ * #if has_attribute(x) || (!HAVE_C___HAS_ATTRIBUTE && defined FOO)
+ * #define HAVE___ATTRIBUTE___X
+ * #endif
+ *
+ * NOTE: Solaris Studio 12.4 supports __has_attribute, but we must enclose
+ * it in parentheses because the expansion results in a token sequence that
+ * chokes the compiler: __has_attribute(nonnull) becomes
+ * __has_attribute__ (nonnull), with a literal space between the preprocessor
+ * identifier and the open parenthesis.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if defined __has_attribute
+#define ag_has_attribute(a) __has_attribute(a)
+#define ag_test_attribute(a, E) (ag_has_attribute(a))
+#else
+#define ag_has_attribute(a) 0
+#define ag_test_attribute(a, E) (E)
+#endif
+
+#if defined __has_extension
+#define ag_has_extension(x) __has_extension(x)
+#define ag_test_extension(x, E) (ag_has_extension(x))
+#else
+#define ag_has_extension(x) 0
+#define ag_test_extension(x, E) (E)
+#endif
+
+#if defined __has_include
+#define ag_has_include(p) __has_include(p)
+#define ag_test_include(p, E) (ag_has_include(p))
+#else
+#define ag_has_include(p) 0
+#define ag_test_include(p, E) (E)
+#endif
+
+#if defined __has_builtin
+#define ag_has_builtin(f) __has_builtin(f)
+#define ag_test_builtin(f, E) (ag_has_builtin(f))
+#else
+#define ag_has_builtin(f) 0
+#define ag_test_builtin(f, E) (E)
+#endif
+
+#ifndef HAVE_C___ATTRIBUTE__
+#define HAVE_C___ATTRIBUTE__ (__GNUC__ || AG_SUNPRO_PREREQ(5,9,0))
+#endif
+
+#ifndef HAVE_C___ATTRIBUTE___CONSTRUCTOR
+#define HAVE_C___ATTRIBUTE___CONSTRUCTOR ag_test_attribute(constructor, __GNUC__)
+#endif
+
+#ifndef HAVE_C___ATTRIBUTE___NONNULL
+#define HAVE_C___ATTRIBUTE___NONNULL ag_test_attribute(nonnull, AG_GNUC_PREREQ(3,3,1))
+#endif
+
+#ifndef HAVE_C___ATTRIBUTE___UNUSED
+#define HAVE_C___ATTRIBUTE___UNUSED ag_test_attribute(unused, __GNUC__)
+#endif
+
+#ifndef HAVE_C___ATTRIBUTE___USED
+#define HAVE_C___ATTRIBUTE___USED ag_test_attribute(used, __GNUC__)
+#endif
+
+#ifndef HAVE_C___ATTRIBUTE___VISIBILITY
+#define HAVE_C___ATTRIBUTE___VISIBILITY ag_test_attribute(visibility, __GNUC__)
+#endif
+
+#ifndef HAVE_C___HAS_EXTENSION
+#define HAVE_C___HAS_EXTENSION (defined __has_extension)
+#endif
+
+#ifndef HAVE_C___HAS_INCLUDE
+#define HAVE_C___HAS_INCLUDE (defined __has_include)
+#endif
+
+#ifndef HAVE_C___EXTENSION__
+#define HAVE_C___EXTENSION__ (__GNUC__)
+#endif
+
+#ifndef HAVE_C___TYPEOF
+#define HAVE_C___TYPEOF (_MSC_VER || __GNUC__ || AG_SUNPRO_PREREQ(5,9,0))
+#endif
+
+#ifndef HAVE_C___TYPEOF__
+#define HAVE_C___TYPEOF__ (__GNUC__ || __xlc__ || AG_SUNPRO_PREREQ(5,9,0))
+#endif
+
+#ifndef HAVE_C__GENERIC
+#define HAVE_C__GENERIC ag_test_extension(c_generic_selections, (AG_GNUC_PREREQ(4,9,0) || __STDC_VERSION__ >= 201112L))
+#endif
+
+#ifndef HAVE_C_STATEMENT_EXPRESSION
+#define HAVE_C_STATEMENT_EXPRESSION (__GNUC__ || AG_SUNPRO_PREREQ(5,9,0))
+#endif
+
+#ifndef HAVE_C_TYPEOF
+#define HAVE_C_TYPEOF (__GNUC__ || __xlc__ || AG_SUNPRO_PREREQ(5,9,0))
+#endif
+
+#ifndef HAVE___ATOMIC_FETCH_ADD
+#define HAVE___ATOMIC_FETCH_ADD (defined __ATOMIC_RELAXED)
+#endif
+
+#ifndef HAVE___ATOMIC_FETCH_SUB
+#define HAVE___ATOMIC_FETCH_SUB HAVE___ATOMIC_FETCH_ADD
+#endif
+
+#ifndef HAVE___BUILTIN_CHOOSE_EXPR
+#define HAVE___BUILTIN_CHOOSE_EXPR (AG_GNUC_PREREQ(3,1,1) || __clang__)
+#endif
+
+#ifndef HAVE___BUILTIN_EXPECT
+#define HAVE___BUILTIN_EXPECT ag_test_builtin(__builtin_expect, __GNUC__)
+#endif
+
+#ifndef HAVE___BUILTIN_NAN
+#define HAVE___BUILTIN_NAN ag_test_builtin(__builtin_nan, AG_GNUC_PREREQ(3,3,1))
+#endif
+
+#ifndef HAVE___BUILTIN_TRAP
+#define HAVE___BUILTIN_TRAP ag_test_builtin(__builtin_trap, AG_GNUC_PREREQ(3,3,1))
+#endif
+
+#ifndef HAVE___BUILTIN_TYPES_COMPATIBLE_P
+#define HAVE___BUILTIN_TYPES_COMPATIBLE_P (AG_GNUC_PREREQ(3,1,1) || __clang__)
+#endif
+
+#ifndef HAVE___BUILTIN_UNREACHABLE
+#define HAVE___BUILTIN_UNREACHABLE ag_test_builtin(__builtin_unreachable, AG_GNUC_PREREQ(4,5,0))
+#endif
+
+#ifndef HAVE__STATIC_ASSERT
+#define HAVE__STATIC_ASSERT ag_test_extension(c_static_assert, (AG_GNUC_PREREQ(4,6,0) || __C11FEATURES__ || __STDC_VERSION__ >= 201112L))
+#endif
+
+
+/*
+ * S Y S T E M E X T E N S I O N S
+ *
+ * We must set these before including any headers for feature detection.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if AG_USE_SYSTEM_EXTENSIONS
+
+/* Solaris */
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__ 1
+#endif
+
+/* AIX */
+#ifndef _ALL_SOURCE
+#define _ALL_SOURCE 1
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#ifndef _MINIX
+#define _MINIX 1
+#endif
+
+/* Solaris */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+
+#endif /* AG_USE_SYSTEM_EXTENSIONS */
+
+#if AG_SYS_LARGEFILE
+
+/* NOTE: BSDs and musl-libc always provide a 64-bit file API */
+
+/* Apple */
+#ifndef _DARWIN_USE_64_BIT_INODE
+#define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Solaris and glibc (per Large File Summit recommendation) */
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+
+/* AIX */
+#ifndef _LARGE_FILES
+#define _LARGE_FILES 1
+#endif
+
+#endif /* AG_SYS_LARGEFILE */
+
+
+/*
+ * S Y S T E M D E T E C T I O N (S T A G E 0)
+ *
+ * Define HAVE_FOO macros as arithmetic truth values for any predefined
+ * system macros which have truth values solely based on whether they're
+ * defined.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* NOTE: None so far. See stage 3 below. */
+
+
+/*
+ * S Y S T E M D E T E C T I O N (S T A G E 1)
+ *
+ * Include any headers necessary for minimal libc feature checking, defining
+ * any prerequisite feature macros.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * NOTE: <limits.h> will indirectly include <features.h>, <standards.h>,
+ * <sys/cdefs.h>, <sys/feature_tests.h>, <sys/featuretest.h>, and similar
+ * system headers which define most of what we care about. Among the typical
+ * feature macros, we also get _DTRACE_VERSION.
+ */
+#include <limits.h>
+
+#ifndef AG_MUSL_MAYBE
+#define AG_MUSL_MAYBE (__linux__ && !__GLIBC__ && !__BIONIC__)
+#endif
+
+#ifndef HAVE_SYS_PARAM_H
+#define HAVE_SYS_PARAM_H ag_test_include(<sys/param.h>, !AG_MUSL_MAYBE)
+#endif
+
+/*
+ * NOTE: Conditionally load <sys/param.h> so we don't unnecessarily pollute
+ * the namespace.
+ */
+#if HAVE_SYS_PARAM_H && !__linux__ && !__sun && !_AIX
+#include <sys/param.h> /* __FreeBSD_version __NetBSD_Prereq__ BSD OpenBSD */
+#endif
+
+#include <fcntl.h> /* F_DUPFD_CLOEXEC */
+
+
+/*
+ * S Y S T E M D E T E C T I O N (S T A G E 2)
+ *
+ * Macros which determine libc vendor and version.
+ *
+ * See http://sourceforge.net/p/predef/wiki/Libraries/
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define AG_AIX_PREREQ(M, m) (_AIX # M # m)
+
+#if defined __GLIBC_PREREQ && !defined __UCLIBC__
+#define AG_GLIBC_PREREQ(M, m) (__GLIBC_PREREQ(M, m))
+#else
+#define AG_GLIBC_PREREQ(M, m) 0
+#endif
+
+#define AG_FREEBSD_2VER(M, m, p) (((M) * 100000) + ((m) * 1000) + (p))
+#define AG_FREEBSD_PREREQ(M, m, p) (__FreeBSD__ > 0 && __FreeBSD_version >= AG_FREEBSD_2VER((M), (m), (p)))
+
+#define AG_IPHONE_2VER(M, m) (((M) * 10000) + ((m) * 100))
+#if defined __IPHONE_OS_VERSION_MIN_REQUIRED
+#define AG_IPHONE_PREREQ(M, m) (AG_IPHONE_2VER((M), (m)) <= __IPHONE_OS_VERSION_MIN_REQUIRED)
+#else
+#define AG_IPHONE_PREREQ(M, m) 0
+#endif
+
+#if defined __NetBSD_Prereq__
+#define AG_NETBSD_PREREQ(M, m, p) (!__minix && __NetBSD_Prereq__(M, m, p))
+#else
+#define AG_NETBSD_PREREQ(M, m, p) 0
+#endif
+
+#define AG_MACOS_2VER_10_9(M, m, p) (((M) * 100) + ((m) * 10))
+#define AG_MACOS_2VER_10_10(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
+#define AG_MACOS_PREREQ_10_10(M, m, p) (((M) > 10 || ((M) == 10 && (m) >= 10)) && AG_MACOS_2VER_10_10((M), (m), (p)) <= __MAC_OS_X_VERSION_MIN_REQUIRED)
+#define AG_MACOS_PREREQ_10_9(M, m, p) (((M) == 10 && (m) < 10) && AG_MACOS_2VER_10_9((M), (m), (p)) <= __MAC_OS_X_VERSION_MIN_REQUIRED)
+#if defined __MAC_OS_X_VERSION_MIN_REQUIRED
+#define AG_MACOS_PREREQ(M, m, p) (AG_MACOS_PREREQ_10_10((M), (m), (p)) || AG_MACOS_PREREQ_10_9((M), (m), (p)))
+#else
+#define AG_MACOS_PREREQ(M, m, p) 0
+#endif
+
+#define AG_OPENBSD_PREREQ_0_0 (__OpenBSD__)
+#define AG_OPENBSD_PREREQ_5_5 (OpenBSD >= 201405)
+#define AG_OPENBSD_PREREQ_5_7 (OpenBSD >= 201505)
+#define AG_OPENBSD_PREREQ(M, m) (AG_OPENBSD_PREREQ_ ## M ## _ ## m)
+
+#define AG_SUNOS_PREREQ_5_10 (__sun && _DTRACE_VERSION)
+#define AG_SUNOS_PREREQ_5_11 (__sun && F_DUPFD_CLOEXEC)
+#define AG_SUNOS_PREREQ(M, m) (AG_SUNOS_PREREQ_ ## M ## _ ## m)
+
+#define AG_UCLIBC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
+#if defined __UCLIBC__
+#define AG_UCLIBC_PREREQ(M, m, p) (AG_UCLIBC_2VER(__UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__) >= AG_UCLIBC_2VER((M), (m), (p)))
+#else
+#define AG_UCLIBC_PREREQ(M, m, p) 0
+#endif
+
+
+/*
+ * S Y S T E M D E T E C T I O N (S T A G E 3)
+ *
+ * Define HAVE_FOO macros as arithmetic truth values for any system macros
+ * which have a truth value solely based on whether they're defined.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HAVE___EXTENSIONS__
+#ifdef __EXTENSIONS__
+#define HAVE___EXTENSIONS__ 1
+#endif
+#endif
+
+#ifndef HAVE__ALL_SOURCE
+#ifdef _ALL_SOURCE
+#define HAVE__ALL_SOURCE 1
+#endif
+#endif
+
+#ifndef HAVE__GNU_SOURCE
+#ifdef _GNU_SOURCE
+#define HAVE__GNU_SOURCE 1
+#endif
+#endif
+
+#ifndef HAVE__MINIX
+#if defined _MINIX || (defined __minix && defined _NETBSD_SOURCE)
+#define HAVE__MINIX 1
+#endif
+#endif
+
+#ifndef HAVE__POSIX_PTHREAD_SEMANTICS
+#ifdef _POSIX_PTHREAD_SEMANTICS
+#define HAVE__POSIX_PTHREAD_SEMANTICS 1
+#endif
+#endif
+
+#ifndef HAVE__REENTRANT
+#ifdef _REENTRANT
+#define HAVE__REENTRANT 1
+#endif
+#endif
+
+
+/*
+ * H E A D E R D E T E C T I O N
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HAVE_DLFCN_H
+#define HAVE_DLFCN_H ag_test_include(<dlfcn.h>, 1)
+#endif
+
+#ifndef HAVE_IFADDRS_H
+#define HAVE_IFADDRS_H_ (!_AIX && (!__sun || AG_SUNOS_PREREQ(5,11)))
+#define HAVE_IFADDRS_H ag_test_include(<ifaddrs.h>, HAVE_IFADDRS_H_)
+#endif
+
+#ifndef HAVE_INTTYPES_H
+#define HAVE_INTTYPES_H 1
+#endif
+
+#ifndef HAVE_MACH_CLOCK_H
+#define HAVE_MACH_CLOCK_H ag_test_include(<mach/clock.h>, __APPLE__)
+#endif
+
+#ifndef HAVE_MACH_MACH_H
+#define HAVE_MACH_MACH_H ag_test_include(<mach/mach.h>, __APPLE__)
+#endif
+
+#ifndef HAVE_MACH_MACH_TIME_H
+#define HAVE_MACH_MACH_TIME_H ag_test_include(<mach/mach_time.h>, __APPLE__)
+#endif
+
+#ifndef HAVE_MEMORY_H
+#define HAVE_MEMORY_H 1
+#endif
+
+#ifndef HAVE_PORT_H
+#define HAVE_PORT_H ag_test_include(<port.h>, AG_SUNOS_PREREQ(5,10))
+#endif
+
+/* TODO: Maybe test _POSIX_THREADS from <unistd.h>. */
+#ifndef HAVE_PTHREAD_H
+#define HAVE_PTHREAD_H ag_test_include(<pthread.h>, !__minix)
+#endif
+
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H 1
+#endif
+
+#ifndef HAVE_STDLIB_H
+#define HAVE_STDLIB_H 1
+#endif
+
+#ifndef HAVE_STRING_H
+#define HAVE_STRING_H 1
+#endif
+
+#ifndef HAVE_STRINGS_H
+#define HAVE_STRINGS_H 1
+#endif
+
+#ifndef HAVE_SYS_AUXV_H
+#define HAVE_SYS_AUXV_H_ (AG_GLIBC_PREREQ(2,16) || (!AG_GLIBC_PREREQ(0,0) && __linux__) || __sun)
+#define HAVE_SYS_AUXV_H ag_test_include(<sys/auxv.h>, HAVE_SYS_AUXV_H_)
+#endif
+
+#ifndef HAVE_SYS_EPOLL_H
+#define HAVE_SYS_EPOLL_H ag_test_include(<sys/epoll.h>, __linux__)
+#endif
+
+#ifndef HAVE_SYS_EVENT_H
+#define HAVE_SYS_EVENT_H ag_test_include(<sys/event.h>, BSD)
+#endif
+
+#ifndef HAVE_SYS_EVENTFD_H
+#define HAVE_SYS_EVENTFD_H_ (AG_GLIBC_PREREQ(2,8) || (!AG_GLIBC_PREREQ(0,0) && __linux__) || defined EFD_CLOEXEC)
+#define HAVE_SYS_EVENTFD_H ag_test_include(<sys/eventfd.h>, HAVE_SYS_EVENTFD_H_)
+#endif
+
+#ifndef HAVE_SYS_INOTIFY_H
+#define HAVE_SYS_INOTIFY_H ag_test_include(<sys/inotify.h>, __linux__)
+#endif
+
+#ifndef HAVE_SYS_SIGNALFD_H
+#define HAVE_SYS_SIGNALFD_H_ (AG_GLIBC_PREREQ(2,8) || (!AG_GLIBC_PREREQ(0,0) && __linux__) || defined SFD_CLOEXEC)
+#define HAVE_SYS_SIGNALFD_H ag_test_include(<sys/signalfd.h>, HAVE_SYS_SIGNALFD_H_)
+#endif
+
+#ifndef HAVE_SYS_SOCKIO_H
+#define HAVE_SYS_SOCKIO_H ag_test_include(<sys/sockio.h>, (__sun || BSD))
+#endif
+
+#ifndef HAVE_SYS_STAT_H
+#define HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef HAVE_SYS_SYSCALL_H
+#define HAVE_SYS_SYSCALL_H_ (BSD || __linux__ || __sun)
+#define HAVE_SYS_SYSCALL_H ag_test_include(<sys/syscall.h>, HAVE_SYS_SYSCALL_H_)
+#endif
+
+#ifndef HAVE_SYS_SYSCTL_H
+#define HAVE_SYS_SYSCTL_H ag_test_include(<sys/sysctl.h>, (BSD || __GLIBC__))
+#endif
+
+#ifndef HAVE_SYS_TIMERFD_H
+#define HAVE_SYS_TIMERFD_H_ (AG_GLIBC_PREREQ(2,8) || (!AG_GLIBC_PREREQ(0,0) && __linux__) || defined TFD_CLOEXEC)
+#define HAVE_SYS_TIMERFD_H ag_test_include(<sys/timerfd.h>, HAVE_SYS_TIMERFD_H_)
+#endif
+
+#ifndef HAVE_SYS_TYPES_H
+#define HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
+#endif
+
+
+/*
+ * T Y P E D E T E C T I O N
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HAVE_CLOCKID_T
+#define HAVE_CLOCKID_T (defined CLOCK_MONOTONIC)
+#endif
+
+#ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
+#define HAVE_STRUCT_SOCKADDR_SA_LEN (!__linux__ && !__sun)
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_ATIM
+#define HAVE_STRUCT_STAT_ST_ATIM (defined st_atime && ((!__APPLE__ && (!__NetBSD__ || AG_NETBSD_PREREQ(7,0,0))) || !HAVE_STRUCT_STAT_ST_ATIMESPEC))
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_CTIM
+#define HAVE_STRUCT_STAT_ST_CTIM HAVE_STRUCT_STAT_ST_ATIM
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_MTIM
+#define HAVE_STRUCT_STAT_ST_MTIM HAVE_STRUCT_STAT_ST_ATIM
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_ATIMESPEC
+#define HAVE_STRUCT_STAT_ST_ATIMESPEC (__APPLE__ || defined st_atimespec || defined st_atimensec)
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_CTIMESPEC
+#define HAVE_STRUCT_STAT_ST_CTIMESPEC HAVE_STRUCT_STAT_ST_ATIMESPEC
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_MTIMESPEC
+#define HAVE_STRUCT_STAT_ST_MTIMESPEC HAVE_STRUCT_STAT_ST_ATIMESPEC
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_BLOCKS
+#define HAVE_STRUCT_STAT_ST_BLOCKS 1
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_BLKSIZE
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+#endif
+
+#ifndef HAVE_STRUCT_STAT_ST_RDEV
+#define HAVE_STRUCT_STAT_ST_RDEV 1
+#endif
+
+
+/*
+ * D E C L A R A T I O N D E T E C T I O N
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HAVE___DECL_LIBC_ENABLE_SECURE
+#define HAVE___DECL_LIBC_ENABLE_SECURE 0
+#endif
+
+#ifndef HAVE_DECL_CLOCK_GETTIME
+#define HAVE_DECL_CLOCK_GETTIME HAVE_DECL_CLOCK_MONOTONIC
+#endif
+
+#ifndef HAVE_DECL_CLOCK_MONOTONIC
+#define HAVE_DECL_CLOCK_MONOTONIC (defined CLOCK_MONOTONIC)
+#endif
+
+#ifndef HAVE_DECL_CLOCK_REALTIME
+#define HAVE_DECL_CLOCK_REALTIME (defined CLOCK_REALTIME)
+#endif
+
+#ifndef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+#define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME (__linux__ && HAVE__GNU_SOURCE)
+#endif
+
+#ifndef HAVE_DECL_PTHREAD_MUTEX_ROBUST
+#define HAVE_DECL_PTHREAD_MUTEX_ROBUST (defined PTHREAD_MUTEX_ROBUST || AG_GLIBC_PREREQ(2,12))
+#endif
+
+#ifndef HAVE_DECL_RANDOM_UUID
+#define HAVE_DECL_RANDOM_UUID (HAVE_SYS_SYSCTL_H && defined __linux__) /* RANDOM_UUID is an enum, not macro */
+#endif
+
+#ifndef HAVE_DECL_STRERROR_R
+#define HAVE_DECL_STRERROR_R 1
+#endif
+
+#ifndef HAVE_DECL_SYS_SIGLIST
+#define HAVE_DECL_SYS_SIGLIST (!AG_MUSL_MAYBE && !__sun && !_AIX)
+#endif
+
+#ifndef HAVE_DECL_SYS_GETRANDOM
+#define HAVE_DECL_SYS_GETRANDOM (defined SYS_getrandom)
+#endif
+
+
+/*
+ * V A R I A B L E D E T E C T I O N
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HAVE___LIBC_ENABLE_SECURE
+#define HAVE___LIBC_ENABLE_SECURE AG_GLIBC_PREREQ(2,1) /* added to glibc between 2.0.98 and 2.0.99 */
+#endif
+
+#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
+#define HAVE_PROGRAM_INVOCATION_SHORT_NAME (__linux__)
+#endif
+
+#ifndef HAVE_SYS_SIGLIST
+#define HAVE_SYS_SIGLIST HAVE_DECL_SYS_SIGLIST
+#endif
+
+
+/*
+ * F U N C T I O N D E T E C T I O N
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HAVE_ACCEPT4
+#define HAVE_ACCEPT4 (defined SOCK_CLOEXEC && !__NetBSD__)
+#endif
+
+#ifndef HAVE_ARC4RANDOM
+#define HAVE_ARC4RANDOM \
+ (__APPLE__ || __DragonFly__ || __FreeBSD__ || __NetBSD__ || \
+ __OpenBSD__ || __minix)
+#endif
+
+#ifndef HAVE_ARC4RANDOM_ADDRANDOM
+#define HAVE_ARC4RANDOM_ADDRANDOM (HAVE_ARC4RANDOM && !AG_OPENBSD_PREREQ(5,5))
+#endif
+
+#ifndef HAVE_ARC4RANDOM_BUF
+#define HAVE_ARC4RANDOM_BUF_APPLE_ (!__APPLE__ || AG_MACOS_PREREQ(10,7,0) || AG_IPHONE_PREREQ(4,3))
+#define HAVE_ARC4RANDOM_BUF_NETBSD_ (!__NetBSD__ || AG_NETBSD_PREREQ(6,0,0))
+#define HAVE_ARC4RANDOM_BUF_IFF_ (HAVE_ARC4RANDOM_BUF_APPLE_ && HAVE_ARC4RANDOM_BUF_NETBSD_)
+#define HAVE_ARC4RANDOM_BUF (HAVE_ARC4RANDOM && HAVE_ARC4RANDOM_BUF_IFF_)
+#endif
+
+#ifndef HAVE_ARC4RANDOM_STIR
+#define HAVE_ARC4RANDOM_STIR HAVE_ARC4RANDOM_ADDRANDOM
+#endif
+
+#ifndef HAVE_CLOCK_GETTIME
+#define HAVE_CLOCK_GETTIME (!__APPLE__ || AG_MACOS_PREREQ(10,12,0))
+#endif
+
+#ifndef HAVE_DLADDR
+#define HAVE_DLADDR (HAVE_DLOPEN && !_AIX && ((!__GLIBC__ && !AG_MUSL_MAYBE) || HAVE__GNU_SOURCE))
+#endif
+
+#ifndef HAVE_DLOPEN
+#define HAVE_DLOPEN HAVE_DLFCN_H
+#endif
+
+#ifndef HAVE_DLSYM
+#define HAVE_DLSYM HAVE_DLOPEN
+#endif
+
+#ifndef HAVE_DUP2
+#define HAVE_DUP2 1
+#endif
+
+#ifndef HAVE_DUP3
+#define HAVE_DUP3 (AG_GLIBC_PREREQ(2,9) || AG_FREEBSD_PREREQ(10,0,0) || AG_NETBSD_PREREQ(6,0,0) || AG_UCLIBC_PREREQ(0,9,34) || AG_MUSL_MAYBE || __BIONIC__ || AG_OPENBSD_PREREQ(5,7))
+#endif
+
+#ifndef HAVE_FDOPENDIR
+#define HAVE_FDOPENDIR ( \
+ (!__APPLE__ || AG_MACOS_PREREQ(10,10,0) || AG_IPHONE_PREREQ(8,0)) \
+ && (!__NetBSD__ || AG_NETBSD_PREREQ(6,0,0)) \
+)
+#endif
+
+#ifndef HAVE_EPOLL_CREATE
+#define HAVE_EPOLL_CREATE HAVE_SYS_EPOLL_H
+#endif
+
+#if HAVE_SYS_EPOLL_H
+#include <sys/epoll.h>
+#endif
+
+#ifndef HAVE_EPOLL_CREATE1
+#define HAVE_EPOLL_CREATE1 (HAVE_EPOLL_CREATE && (defined EPOLL_CLOEXEC || AG_GLIBC_PREREQ(2,9)))
+#endif
+
+#ifndef HAVE_EPOLL_CTL
+#define HAVE_EPOLL_CTL HAVE_EPOLL_CREATE
+#endif
+
+#ifndef HAVE_EPOLL_PWAIT
+#define HAVE_EPOLL_PWAIT (HAVE_EPOLL_WAIT && (AG_GLIBC_PREREQ(2,6) || (!AG_GLIBC_PREREQ(0,0) && defined EPOLL_CLOEXEC)))
+#endif
+
+#ifndef HAVE_EPOLL_WAIT
+#define HAVE_EPOLL_WAIT HAVE_EPOLL_CREATE
+#endif
+
+#ifndef HAVE_EVENTFD
+#define HAVE_EVENTFD HAVE_SYS_EVENTFD_H
+#endif
+
+#ifndef HAVE_GETAUXVAL
+#define HAVE_GETAUXVAL (HAVE_SYS_AUXV_H && !__sun)
+#endif
+
+#ifndef HAVE_GETENV_R
+#define HAVE_GETENV_R (AG_NETBSD_PREREQ(4,0,0) || __minix)
+#endif
+
+#ifndef HAVE_GETEXECNAME
+#define HAVE_GETEXECNAME (__sun)
+#endif
+
+#ifndef HAVE_GETIFADDRS
+#define HAVE_GETIFADDRS (HAVE_IFADDRS_H && !__sun)
+#endif
+
+#ifndef HAVE_GETPROGNAME
+#define HAVE_GETPROGNAME (HAVE_ARC4RANDOM || AG_SUNOS_PREREQ(5,11))
+#endif
+
+#ifndef HAVE_INOTIFY_INIT
+#define HAVE_INOTIFY_INIT HAVE_SYS_INOTIFY_H
+#endif
+
+#ifndef HAVE_INOTIFY_INIT1
+#define HAVE_INOTIFY_INIT1 (HAVE_INOTIFY_INIT && defined IN_CLOEXEC)
+#endif
+
+#ifndef HAVE_ISSETUGID
+#define HAVE_ISSETUGID ((!__linux__ || (AG_MUSL_MAYBE && HAVE__GNU_SOURCE)) && !_AIX)
+#endif
+
+#if HAVE_SYS_EVENT_H
+#include <sys/event.h>
+#endif
+
+#ifndef HAVE_KEVENT
+#define HAVE_KEVENT (defined EV_SET)
+#endif
+
+#ifndef HAVE_KQUEUE
+#define HAVE_KQUEUE HAVE_KEVENT
+#endif
+
+#ifndef HAVE_KQUEUE1
+#define HAVE_KQUEUE1 (HAVE_KQUEUE && AG_NETBSD_PREREQ(6,0,0))
+#endif
+
+#ifndef HAVE_OPENAT
+#define HAVE_OPENAT \
+ ((!__APPLE__ || AG_MACOS_PREREQ(10,10,0) || AG_IPHONE_PREREQ(8,0)) \
+ && (!__NetBSD__ || AG_NETBSD_PREREQ(7,0,0)))
+#endif
+
+#ifndef HAVE_PACCEPT
+#define HAVE_PACCEPT AG_NETBSD_PREREQ(6,0,0)
+#endif
+
+#ifndef HAVE_PIPE2
+#define HAVE_PIPE2 (AG_GLIBC_PREREQ(2,9) || AG_FREEBSD_PREREQ(10,0,0) || AG_NETBSD_PREREQ(6,0,0) || AG_UCLIBC_PREREQ(0,9,32) || AG_MUSL_MAYBE || __BIONIC__ || AG_OPENBSD_PREREQ(5,7))
+#endif
+
+#ifndef HAVE_PORT_ALERT
+#define HAVE_PORT_ALERT HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_PORT_ASSOCIATE
+#define HAVE_PORT_ASSOCIATE HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_PORT_CREATE
+#define HAVE_PORT_CREATE HAVE_PORT_H
+#endif
+
+#ifndef HAVE_PORT_DISSOCIATE
+#define HAVE_PORT_DISSOCIATE HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_PORT_GET
+#define HAVE_PORT_GET HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_PORT_GETN
+#define HAVE_PORT_GETN HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_PORT_SEND
+#define HAVE_PORT_SEND HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_PORT_SENDN
+#define HAVE_PORT_SENDN HAVE_PORT_CREATE
+#endif
+
+#ifndef HAVE_POSIX_FADVISE
+#define HAVE_POSIX_FADVISE (defined POSIX_FADV_NORMAL || AG_GLIBC_PREREQ(2,2) || __sun || AG_MUSL_MAYBE || AG_FREEBSD_PREREQ(9,0,0))
+#endif
+
+#ifndef HAVE_POSIX_FALLOCATE
+#define HAVE_POSIX_FALLOCATE (_AIX || AG_FREEBSD_PREREQ(9,0,0) || AG_GLIBC_PREREQ(2,2) || AG_MUSL_MAYBE || AG_NETBSD_PREREQ(7,0,0) || __sun)
+#endif
+
+#ifndef HAVE_SIGNALFD
+#define HAVE_SIGNALFD HAVE_SYS_SIGNALFD_H
+#endif
+
+#ifndef HAVE_SIGTIMEDWAIT
+#define HAVE_SIGTIMEDWAIT (!__APPLE__ && !__OpenBSD__)
+#endif
+
+#ifndef HAVE_SIGWAIT
+#define HAVE_SIGWAIT (!__minix)
+#endif
+
+#ifndef HAVE_STATIC_ASSERT
+#if AG_GLIBC_PREREQ(0,0) && !HAVE__STATIC_ASSERT
+#define HAVE_STATIC_ASSERT 0 /* glibc doesn't check GCC version */
+#else
+#define HAVE_STATIC_ASSERT (defined static_assert)
+#endif
+#endif
+
+#ifndef HAVE_STRERROR_R
+#define HAVE_STRERROR_R 1
+#endif
+
+#ifndef HAVE_SYSCALL
+#define HAVE_SYSCALL HAVE_SYS_SYSCALL_H
+#endif
+
+#ifndef HAVE_SYSCTL
+#define HAVE_SYSCTL HAVE_SYS_SYSCTL_H
+#endif
+
+#ifndef HAVE_TIMERFD_CREATE
+#define HAVE_TIMERFD_CREATE HAVE_SYS_TIMERFD_H
+#endif
+
+#ifndef HAVE_TIMERFD_GETTIME
+#define HAVE_TIMERFD_GETTIME HAVE_TIMERFD_CREATE
+#endif
+
+#ifndef HAVE_TIMERFD_SETTIME
+#define HAVE_TIMERFD_SETTIME HAVE_TIMERFD_CREATE
+#endif
+
+#ifndef STRERROR_R_CHAR_P
+#define STRERROR_R_CHAR_P ((AG_GLIBC_PREREQ(0,0) || AG_UCLIBC_PREREQ(0,0,0)) && (HAVE__GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)))
+#endif
+
+
+#endif /* CONFIG_H_GUESS */
diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 433dd03..7db7463 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -597,6 +597,14 @@ Returns the subject distinguished name as an \module{x509.name} object.
Sets the subject distinguished name. $name$ should be an \module{x509.name} object.
+\subsubsection[\fn{csr:getSubjectAlt}]{\fn{csr:getSubjectAlt()}}
+
+Returns the subject alternative name as an \module{x509.altname} object.
+
+\subsubsection[\fn{csr:setSubjectAlt}]{\fn{csr:setSubjectAlt($name$)}}
+
+Sets the subject alternative names. $name$ should be an \module{x509.altname} object.
+
\subsubsection[\fn{csr:getPublicKey}]{\fn{csr:getPublicKey()}}
Returns the public key component as an \module{openssl.pkey} object.
diff --git a/examples/vrfy.sig b/examples/vrfy.sig
index 258490a..84bcfcc 100755
--- a/examples/vrfy.sig
+++ b/examples/vrfy.sig
@@ -14,15 +14,16 @@ local function genkey(type)
type = string.upper(type or (not openssl.NO_EC and "EC") or "RSA")
if type == "RSA" then
- return pkey.new{ type = "RSA", bits = 1024 }, "sha256"
+ return pkey.new{ type = "RSA", bits = 1024 }
elseif type == "DSA" then
- return pkey.new{ type = "DSA", bits = 1024 }, "dss1"
+ return pkey.new{ type = "DSA", bits = 1024 }
else
- return pkey.new{ type = "EC", curve = "prime192v1" }, "ecdsa-with-SHA1"
+ return pkey.new{ type = "EC", curve = "prime192v1" }
end
end
-local key, hash = genkey(keytype)
+local key = genkey(keytype)
+local hash = key:getDefaultDigestName()
-- digest our message using an appropriate digest ("ecdsa-with-SHA1" for EC;
-- "dss1" for DSA; and "sha1", "sha256", etc for RSA).
@@ -45,6 +46,7 @@ local function tohex(b)
return x
end
-print("okay", pub:verify(sig, data))
-print("type", pub:type())
-print("sig", tohex(sig))
+print("verified", pub:verify(sig, data))
+print("key-type", pub:type())
+print("hash-type", hash)
+print("signature", tohex(sig))
diff --git a/mk/lua.path b/mk/luapath
index 8df41c9..b36da19 100755
--- a/mk/lua.path
+++ b/mk/luapath
@@ -26,10 +26,10 @@
# Changelog:
#
# * 2013-08-02 - Published. Derived from an earlier script, lua.path,
-# written for the cqueues project.
+# written for the cqueues project.
#
# * 2013-08-05 - Redirect stdin from /dev/null when probing so we don't
-# freeze if a utility tries to read from stdin.
+# freeze if a utility tries to read from stdin.
#
# chdir to a read-only directory by default to try to prevent creation
# of temporary files. These features address the issues of LuaTeX
@@ -82,9 +82,55 @@
# hardcode /usr/local/lib/lua/5.1, ordered before the LuaJIT
# installation prefix.
#
+# * 2015-07-14 - Add recursive glob function implemented in shell code
+# and use instead of find(1).
+#
+# * 2016-03-18 - Fix bug in tryluac where a continue statement was used
+# instead of return 0.
+#
+# * 2016-03-25 - Support ${CC} values with trailing flags, which invoke
+# the compiler through env(1), or which otherwise are intended to
+# expand as multiple words.
+#
+# OpenBSD 5.8 sh does not suppress strict errors within an eval
+# invoked from an if condition compound-list. Workaround by changing
+# trylua to return 0 on matching failure, like tryluainclude and
+# tryluac do.
+#
+# Undeprecate ldir and cdir. The names are more intuitive and
+# convenient as evidenced by the fact that I keep using them instead
+# of package.path and package.cpath. Try to maintain backwards
+# compatibility by using a simple heuristic to differentiate lua
+# interpreter glob patterns from preferred install directory
+# string.match expressions.
+#
+# * 2016-10-10 - Fix issue with passing empty CPPFLAGS to ${CC}. /usr/bin/cc
+# in NetBSD 7.0.1 does not tolerate an empty string argument. This
+# exposed a bug in NetBSD's and FreeBSD's /bin/sh, triggered by how we
+# pass CPPFLAGS (see evalmacro and runcc routines, below).
+#
+# Some Ash variants (confirmed /bin/sh in NetBSD 7.0.1 and FreeBSD
+# 10.1) will expand unquoted ${UNSET-} and ${UNSET:-} as an empty
+# string rather than eliding it during argument processing. That is,
+#
+# nargs() { printf "%d\n" "$#"; }
+# nargs ${UNSET} 2 3
+# nargs ${UNSET-} 2 3
+#
+# prints "2" and "3", whereas every other shell tested prints "2" and
+# "2" (confirmed dash in Ubuntu Xenial; bash 4.3 in Ubuntu Xenial;
+# pdksh in FreeBSD 10.1, NetBSD 7.0, OS X 10.1, OpenBSD 6.0; ksh93 in
+# Solaris 11.3 and AIX 7.1; ksh88 in AIX 7.1).
+#
+# A workaround in set -u mode (where unbound variable expansion aborts
+# execution) is to substitute a known empty value. E.g.
+#
+# EMPTY=
+# nargs ${UNSET-$EMPTY}
+#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
-# Copyright (C) 2012-2015 William Ahern
+# Copyright (C) 2012-2016 William Ahern
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -116,10 +162,11 @@ unset IFS # no field splitting surprises
unset LUA_PATH || true # interferes search for module install directory
unset LUA_CPATH || true
-MYVERSION=20150119
+MYVERSION=20161010
MYVENDOR="william@25thandClement.com"
+EMPTY= # empty string for parameter expansion workaround for Ash bug
DEVRANDOM=/dev/urandom
SANDBOX="${TMPDIR}/${0##*/}-"
@@ -129,8 +176,7 @@ LDDIRS= # -L directories from LDFLAGS
LIBDIRS=
BINDIRS=
RECURSE=no
-MAXDEPTH= # full command switch, like "-maxdepth 3", if supported
-XDEV= # do not cross device boundaries; i.e. "-xdev"
+MAXDEPTH=5 # maximum recursion depth
SHORTEST= # continue searching until shortest pathname found
PKGCONFIG= # path to pkg-config, found by `command -v` when -k option invoked
GLOB= # -e GLOB expression for lua, luac, ldir, and cdir
@@ -165,6 +211,27 @@ LUA_VER=
#
+# warn FORMAT [...]
+#
+# Print message to original stderr.
+#
+exec 9>&2
+warn() {
+ printf "%s: %.0s${1}\n" "${0##*/}" "$@" >&9
+}
+
+#
+# panic FORMAT [...]
+#
+# Print message to original stderr, then exit with failure.
+#
+panic() {
+ warn "$@"
+ exit 1
+}
+
+
+#
# parse CPPFLAGS -I or LDFLAGS -L directories
#
xdirs() {
@@ -231,6 +298,46 @@ append() {
}
#
+# glob PATTERN [MAXDEPTH] [EXEC-COMMAND] [INTERNAL:GLOB-COUNT]
+#
+glob() {
+ glob_N="${4:-0}"
+
+ IFS=
+ set +f
+ for F in ${1}; do
+ [ -e "${F}" ] || continue
+ if eval "${3:-printf '%s\\n'} \"\${F}\""; then
+ glob_N=$((${glob_N} + 1))
+ fi
+ done
+ set -f
+ unset IFS
+
+ if [ "${2-0}" -gt 0 ]; then
+ glob "${1%/*}/*/${1##*/}" "$((${2} - 1))" "${3:-}" "${glob_N}" || :
+ fi
+
+ [ "${glob_N}" -gt 0 ]
+} # glob
+
+
+#
+# runcc [...]
+#
+# Wrapper for invoking ${CC}. Some build system include flags in ${CC},
+# invoke the compiler through env(1), or employ other hacks.
+#
+# TODO: Optionally handle unescaping of words in a manner similar to how
+# ${CC} would be evaluated from a make rule--typically by being passed
+# through system(3).
+#
+runcc() {
+ (unset IFS; exec ${CC} "$@")
+}
+
+
+#
# evalmacro PATH MACRO [REGEX] [SUBST]
#
# PATH Header identifier--#include <PATH>
@@ -240,7 +347,7 @@ append() {
#
evalmacro() {
printf "#include <$1>\n[===[$2]===]\n" \
- | "${CC:-cc}" ${CPPFLAGS:-} -E - 2>>/dev/null \
+ | runcc ${CPPFLAGS:-${EMPTY}} -E - 2>>/dev/null \
| sed -ne "
s/^.*\\[===\\[ *\\(${3:-.*}\\) *\\]===\\].*$/${4:-\\1}/
t Found
@@ -267,7 +374,7 @@ testsym() {
# and within [A-T].
(nm -Pg ${1} 2>>/dev/null || nm -g 2>>/dev/null) \
| sed -ne '/ [A-T] /p' \
- | grep -qE "${2}"
+ | grep -q "${2}"
}
@@ -398,7 +505,9 @@ luapc() {
findinstalldir() {
V_DIR=$((${LUA_VER} / 100 % 100)).$((${LUA_VER} % 100))
- if [ "${1}" = "package.cpath" ]; then
+ if [ "${1}" = "package.cpath" -o "${1}" = "cdir" ]; then
+ ARRAY="package.cpath"
+
DIR="$(luapc --variable INSTALL_CMOD)"
[ -n "${DIR}" ] && set -- "$@" "${DIR}"
@@ -418,6 +527,8 @@ findinstalldir() {
set -- "$@" "${LUA_PATH}/../../lib/lua/${V_DIR}"
set -- "$@" "${LUA_PATH}/../../lib/*/lua/${V_DIR}" # e.g. lib/x86_64-linux-gnu
else
+ ARRAY="package.path"
+
DIR="$(luapc --variable INSTALL_LMOD)"
[ -n "${DIR}" ] && set -- "$@" "${DIR}"
@@ -429,7 +540,6 @@ findinstalldir() {
set -- "$@" "${LUA_PATH}/../../share/lua/${V_DIR}"
fi
- ARRAY="${1}"
shift
if [ $# -eq 0 ]; then
@@ -576,13 +686,11 @@ findversion() {
if [ $# -gt 0 ]; then
for D; do
- for F in $(find "${D}" ${MAXDEPTH} ${XDEV} -name lua.h -print 2>>/dev/null); do
- tryluainclude "${F}"
+ glob "${D}/lua.h" "${MAXDEPTH}" tryluainclude || :
- if foundversion; then
- return 0
- fi
- done
+ if foundversion; then
+ return 0
+ fi
done
fi
@@ -594,13 +702,11 @@ findversion() {
if [ $# -gt 0 ]; then
for D; do
- for F in $(find "${D}/." ${MAXDEPTH} ${XDEV} -name lua.h -print 2>>/dev/null); do
- tryluainclude "${F}"
+ glob "${D}/lua.h" "${MAXDEPTH}" tryluainclude || :
- if foundversion; then
- return 0
- fi
- done
+ if foundversion; then
+ return 0
+ fi
done
fi
@@ -612,13 +718,11 @@ findversion() {
D="${D%/*}/include"
if [ -d "${D}" ]; then
- for F in $(find "${D}" ${MAXDEPTH} ${XDEV} -name lua.h -print 2>>/dev/null); do
- tryluainclude "${F}"
+ glob "${D}/lua.h" "${MAXDEPTH}" tryluainclude || :
- if foundversion; then
- return 0
- fi
- done
+ if foundversion; then
+ return 0
+ fi
fi
fi
@@ -631,9 +735,10 @@ findversion() {
# compatible.
#
trylib() {
- if ! testsym "${1}" "lua_newstate"; then
- return 0
- fi
+ testsym "${1}" "lua_newstate" || return 1
+
+ # exclude C++
+ [ "${1#*++}" = "${1}" ] || return 1
V=0
J=0
@@ -662,16 +767,20 @@ trylib() {
if testsym "${1}" "lua_getfenv"; then
V=501
elif testsym "${1}" "lua_yieldk"; then
- V=502
+ if testsym "${1}" "lua_getctx"; then
+ V=502
+ else
+ V=503
+ fi
else
- return 0
+ return 1
fi
- [ "$V" -gt 0 -a "$V" -ge "${LIBLUA_VER:-0}" ] || return 0
+ [ "$V" -gt 0 -a "$V" -ge "${LIBLUA_VER:-0}" ] || return 1
- [ "$V" -gt "${LIBLUA_VER:-0}" -o "${#D}" -lt "${#LIBLUA_DIR}" -o \( "${JIT_REQ}" = "yes" -a "${LIBJIT_VER:-0}" -lt "${JIT_MAX}" \) ] || return 0
+ [ "$V" -gt "${LIBLUA_VER:-0}" -o "${#D}" -lt "${#LIBLUA_DIR}" -o \( "${JIT_REQ}" = "yes" -a "${LIBJIT_VER:-0}" -lt "${JIT_MAX}" \) ] || return 1
- [ "$V" -ge "${API_MIN}" -a "$V" -le "${API_MAX}" ] || return 0
+ [ "$V" -ge "${API_MIN}" -a "$V" -le "${API_MAX}" ] || return 1
if [ -n "${JIT_REQ}" ]; then
@@ -681,12 +790,12 @@ trylib() {
fi
if [ "${JIT_REQ}" = "skip" ]; then
- [ "${J}" -eq 0 ] || return 0
+ [ "${J}" -eq 0 ] || return 1
elif [ "${JIT_REQ}" = "yes" ]; then
- [ "$J" -ge "${LIBJIT_VER:-0}" ] || return 0
- [ "$J" -gt "${LIBJIT_VER:-0}" -o "${#D}" -lt "${#LIBJIT_DIR}" ] || return 0
- [ "$J" -ge ${JIT_MIN} ] || return 0
- [ "$J" -le "${JIT_MAX}" ] || return 0
+ [ "$J" -ge "${LIBJIT_VER:-0}" ] || return 1
+ [ "$J" -gt "${LIBJIT_VER:-0}" -o "${#D}" -lt "${#LIBJIT_DIR}" ] || return 1
+ [ "$J" -ge ${JIT_MIN} ] || return 1
+ [ "$J" -le "${JIT_MAX}" ] || return 1
LIBJIT_VER="$J"
LIBJIT_DIR="$D"
@@ -745,15 +854,17 @@ findlib() {
#printf -- "I=$I K=$K $findlib_L/lib$findlib_l*.*\n"
- for findlib_R in no ${RECURSE}; do
- for findlib_lib in $(findpath "lib${findlib_l}*.*" ${findlib_R} "${findlib_L}"); do
- trylib "${findlib_lib}"
- done
+ glob "${findlib_L}/lib${findlib_l}*.*" 0 trylib || :
- if foundlib; then
- return 0
- fi
- done
+ if foundlib; then
+ return 0;
+ fi
+
+ glob "${findlib_L}/lib${findlib_l}*.*" ${MAXDEPTH} trylib || :
+
+ if foundlib; then
+ return 0;
+ fi
K=$(($K + 1))
done
@@ -768,48 +879,73 @@ findlib() {
unset IFS
for findlib_D; do
- for findlib_R in no ${RECURSE}; do
- for findlib_lib in $(findpath "liblua*.*" ${findlib_R} "${findlib_D}"); do
- trylib "${findlib_lib}"
- done
+ glob "${findlib_D}/liblua*.*" "${MAXDEPTH}" trylib || :
+
+ if foundlib; then
+ return 0
+ fi
+ done
+
+ # if we can find the lua interpreter, use it as a reference for
+ # library locations.
+ if findlua; then
+ findlib_D="${LUA_PATH%/*}"
+ findlib_D="${findlib_D%/*}/lib"
+
+ if [ -d "${findlib_D}" ]; then
+ glob "${findlib_D}/liblua*.*" "${MAXDEPTH}" trylib || :
if foundlib; then
return 0
fi
- done
- done
+ fi
+ fi
+}
+
+
+# check setuid and setgid mode
+safeperm() {
+ [ -f "$1" -a ! -u "$1" -a ! -g "$1" ]
}
-findpath() {
- NAME="$1"
- WHERE="$3"
+tryluac() {
+ tryluac_F="${1}"
- PRUNE=
+ [ -x "${tryluac_F}" ] && safeperm "${tryluac_F}" || return 0
- if [ "${2}" = "no" ]; then
- PRUNE="-name . -o -type d -prune -o"
- fi
+ tryluac_V="$("${tryluac_F}" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^Lua \([0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
+ : ${tryluac_V:=0}
+ tryluac_V="$((${tryluac_V%%.*} * 100 + ${tryluac_V##*.} % 100))"
- [ ${#WHERE} -gt 0 ] || return 0
+ [ "${tryluac_V}" -gt 0 -a "${tryluac_V}" -ge "${LUAC_VER:-0}" ] || return 0
- IFS=:
- set -- ${WHERE}
- unset IFS
+ [ "${tryluac_V}" -gt "${LUAC_VER:-0}" -o "${#tryluac_F}" -lt "${#LUAC_PATH}" ] || return 0
- if [ $# -gt 0 ]; then
- for findpath_D; do
- find "${findpath_D}/." ${MAXDEPTH} ${XDEV} ${PRUNE} -name "${NAME}" -print 2>>/dev/null | sed -e 's/\/\.//'
- done
- fi
-}
+ [ "${tryluac_V}" -ge "${API_MIN}" -a "${tryluac_V}" -le "${API_MAX}" ] || return 0
+ printf "return true" 2>>/dev/null | ${tryluac_F} -p - </dev/null >>/dev/null 2>&1 || return 0
-# check setuid and setgid mode
-safeperm() {
- [ -f "$1" -a ! -u "$1" -a ! -g "$1" ]
+ LUAC_PATH="${tryluac_F}"
+ LUAC_VER="${tryluac_V}"
}
+#
+# foundluac
+#
+# true if found the best (maximum) possible version, false otherwise
+#
+foundluac() {
+ if [ "${LUAC_VER:-0}" -lt "${API_MAX}" ]; then
+ return 1
+ fi
+
+ if [ "${SHORTEST}" = "yes" ]; then
+ return 1
+ fi
+
+ return 0
+}
findluac() {
if [ $# -eq 0 ]; then
@@ -818,36 +954,33 @@ findluac() {
unset IFS
fi
- while [ $# -gt 0 ]; do
- for F in $(findpath "${1}" no "${PATH}"; findpath "${1}" "${RECURSE}" "${BINDIRS}"); do
- [ -x "$F" ] && safeperm "$F" || continue
-
- V="$("$F" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^Lua \([0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
- : ${V:=0}
- V="$((${V%%.*} * 100 + ${V##*.} % 100))"
-
- [ "${V}" -gt 0 -a "${V}" -ge "${LUAC_VER:-0}" ] || continue
+ for findluac_G; do
+ IFS=:
+ for findluac_D in ${PATH}; do
+ unset IFS
- [ "${V}" -gt "${LUAC_VER:-0}" -o "${#F}" -lt "${#LUAC_PATH}" ] || continue
+ glob "${findluac_D}/${findluac_G}" 0 tryluac || :
- [ "${V}" -ge "${API_MIN}" -a "${V}" -le "${API_MAX}" ] || continue
+ if foundluac; then
+ return 0
+ fi
+ done
- printf "return true" 2>>/dev/null | ${F} -p - </dev/null >>/dev/null 2>&1 || continue
+ IFS=:
+ for findluac_D in ${BINDIRS}; do
+ unset IFS
- LUAC_PATH="$F"
- LUAC_VER="$V"
+ glob "${findluac_D}/${findluac_G}" "${MAXDEPTH}" tryluac || :
- [ "${SHORTEST}" = "yes" -o "${LUAC_VER}" -lt "${API_MAX}" ] || break 2
+ if foundluac; then
+ return 0
+ fi
done
- shift
+ unset IFS
done
- if [ -n "${LUAC_PATH}" -a -n "${LUAC_VER}" ]; then
- return 0
- else
- return 1
- fi
+ [ "${LUAC_VER:-0}" -gt 0 ] && [ "${#LUAC_PATH}" -gt 0 ]
}
@@ -871,7 +1004,7 @@ isinteger() {
checkints() {
while [ $# -gt 0 ]; do
if ! isinteger "${1}"; then
- printf -- "${0##*/}: ${1}: not a number\n" >&2
+ warn "%s: not a number" "${1}"
return 1
fi
@@ -946,6 +1079,54 @@ mmp2num() {
}
+trylua() {
+ trylua_F="${1}"
+ [ -x "${trylua_F}" ] && safeperm "${trylua_F}" || return 0
+
+ trylua_V="$("${trylua_F}" -e 'print(string.match(_VERSION, [[[%d.]+]]))' </dev/null 2>>/dev/null | head -n1 | sed -ne 's/^\([0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
+ : ${trylua_V:=0}
+ trylua_V="$((${trylua_V%%.*} * 100 + ${trylua_V##*.} % 100))"
+
+ [ "${trylua_V}" -gt 0 -a "${trylua_V}" -ge "${LUA_VER:-0}" ] || return 0
+
+ [ "${trylua_V}" -gt "${LUA_VER:-0}" -o "${#trylua_F}" -lt "${#LUA_PATH}" ] || return 0
+
+ [ "${trylua_V}" -ge "${API_MIN}" -a "${trylua_V}" -le "${API_MAX}" ] || return 0
+
+ if [ -n "${JIT_REQ}" ]; then
+ J="$("${trylua_F}" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^LuaJIT \([0123456789][0123456789]*\.[0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
+ J="$(jit2num ${J:-0})"
+
+ if [ "${JIT_REQ}" = "skip" ]; then
+ [ "${J}" -eq 0 ] || return 0
+ elif [ "${JIT_REQ}" = "yes" ]; then
+ [ "${J}" -gt 0 ] || return 0
+ [ "${J}" -ge "${JIT_MIN}" ] || return 0
+ [ "${J}" -le "${JIT_MAX}" ] || return 0
+ fi
+ fi
+
+ LUA_PATH="${trylua_F}"
+ LUA_VER="${trylua_V}"
+}
+
+#
+# foundlua
+#
+# true if found the best (maximum) possible version, false otherwise
+#
+foundlua() {
+ if [ "${LUA_VER:-0}" -lt "${API_MAX}" ]; then
+ return 1
+ fi
+
+ if [ "${SHORTEST}" = "yes" ]; then
+ return 1
+ fi
+
+ return 0
+}
+
findlua() {
if [ $# -eq 0 ]; then
IFS=:
@@ -953,52 +1134,38 @@ findlua() {
unset IFS
fi
- while [ $# -gt 0 ]; do
- for F in $(findpath "${1}" no "${PATH}"; findpath "${1}" "${RECURSE}" "${BINDIRS}"); do
- [ -x "$F" ] && safeperm "$F" || continue
-
- V="$("$F" -e 'print(string.match(_VERSION, [[[%d.]+]]))' </dev/null 2>>/dev/null | head -n1 | sed -ne 's/^\([0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
- : ${V:=0}
- V="$((${V%%.*} * 100 + ${V##*.} % 100))"
+ for findlua_G; do
+ IFS=:
+ for findlua_D in ${PATH}; do
+ unset IFS
- [ "${V}" -gt 0 -a "${V}" -ge "${LUA_VER:-0}" ] || continue
+ glob "${findlua_D}/${findlua_G}" 0 trylua || :
- [ "${V}" -gt "${LUA_VER:-0}" -o "${#F}" -lt "${#LUA_PATH}" ] || continue
+ if foundlua; then
+ return 0
+ fi
+ done
- [ "${V}" -ge "${API_MIN}" -a "${V}" -le "${API_MAX}" ] || continue
+ IFS=:
+ for findlua_D in ${BINDIRS}; do
+ unset IFS
- if [ -n "${JIT_REQ}" ]; then
- J="$("$F" -v </dev/null 2>&1 | head -n1 | sed -ne 's/^LuaJIT \([0123456789][0123456789]*\.[0123456789][0123456789]*\.[0123456789][0123456789]*\).*/\1/p')"
- J="$(jit2num ${J:-0})"
+ glob "${findlua_D}/${findlua_G}" "${MAXDEPTH}" trylua || :
- if [ "${JIT_REQ}" = "skip" ]; then
- [ "${J}" -eq 0 ] || continue
- elif [ "${JIT_REQ}" = "yes" ]; then
- [ "${J}" -gt 0 ] || continue
- [ "${J}" -ge "${JIT_MIN}" ] || continue
- [ "${J}" -le "${JIT_MAX}" ] || continue
- fi
+ if foundlua; then
+ return 0
fi
-
- LUA_PATH="$F"
- LUA_VER="$V"
-
- [ "${SHORTEST}" = "yes" -o "${LUA_VER}" -lt "${API_MAX}" ] || break 2
done
- shift
+ unset IFS
done
- if [ -n "${LUA_PATH}" -a -n "${LUA_VER}" ]; then
- return 0
- else
- return 1
- fi
+ [ "${LUA_VER:-0}" -gt 0 ] && [ "${#LUA_PATH}" -gt 0 ]
}
ccname() {
- "${CC}" -E - <<-EOF | awk '/sunpro/||/clang/||/gcc/||/other/{ print $1; exit; }'
+ runcc -E - <<-EOF | awk '/sunpro/||/clang/||/gcc/||/other/{ print $1; exit; }'
#if defined __SUNPRO_C
sunpro
#elif defined __clang__
@@ -1026,8 +1193,7 @@ usage() {
-e GLOB glob pattern for finding utilities (lua, luac, etc)
-k query pkg-config if available
-r recursively search directories
- -m MAXDEPTH limit recursion to MAXDEPTH (only for GNU and BSD find)
- -x do not cross device mounts when recursing
+ -m MAXDEPTH limit recursion to MAXDEPTH
-s find shortest pathname, otherwise print first best match
-v VERSION require specific Lua version or range
(e.g. "5.1" or "5.1-5.2")
@@ -1038,8 +1204,10 @@ usage() {
-h print this usage message
cppflags print derived additional CPPFLAGS necessary
+ version print derived Lua API version from cppflags discovery
ldflags print derived additional LDFLAGS necessary (TODO)
- version print derived Lua API version
+ libs print derived additional LIBS necessary (TODO)
+ libversion print derived Lua API version from ldflags/libs discovery
luac print path to luac utility ($(printf "${GLOB_LUA}" | tr ':' ' '))
lua print path to lua interpreter ($(printf "${GLOB_LUAC}" | tr ':' ' '))
package.path print preferred module install path
@@ -1114,20 +1282,21 @@ while getopts I:L:P:d:De:krm:xsv:j:JVh OPT; do
RECURSE=yes
;;
m)
- if [ -n "${OPTARG##[0123456789]}" ]; then
- printf -- "${0##*/}: ${OPTARG}: invalid maxdepth\n" >&2
- exit 1
- fi
-
- if find "${TMPDIR:-/tmp}" -maxdepth ${OPTARG} -prune >>/dev/null 2>&1; then
- MAXDEPTH="-maxdepth ${OPTARG}"
- else
- printf -- "${0##*/}: $(command -v find): -maxdepth unsupported\n" >&2
+ if [ "${#OPTARG}" -eq 0 -o -n "${OPTARG##[0123456789]}" ]; then
+ panic "%s: invalid maxdepth" "${OPTARG}"
fi
+ MAXDEPTH="${OPTARG}"
;;
x)
- XDEV="-xdev"
+ #
+ # NOTE: This option was
+ #
+ # -x do not cross device mounts when recursing
+ #
+ # but is currently unsupported as our built-in glob function
+ # does not implement this functionality. Previously this
+ # option caused -xdev to be added to invocations of find(1).
;;
s)
SHORTEST=yes
@@ -1140,8 +1309,7 @@ while getopts I:L:P:d:De:krm:xsv:j:JVh OPT; do
API_MAX="$(lua2num ${MAX:-99} 99)"
if [ "${API_MIN}" -gt "${API_MAX}" ]; then
- printf -- "${0##*/}: ${OPTARG}: invalid version range\n" >&2
- exit 1
+ panic "%s: invalid version range" "${OPTARG}"
fi
;;
@@ -1153,8 +1321,7 @@ while getopts I:L:P:d:De:krm:xsv:j:JVh OPT; do
JIT_MAX="$(jit2num ${MAX:-99} 99 99)"
if [ "${JIT_MIN}" -gt "${JIT_MAX}" ]; then
- printf -- "${0##*/}: ${OPTARG}: invalid version range\n" >&2
- exit 1
+ panic "%s: invalid version range" "${OPTARG}"
fi
JIT_REQ=yes
@@ -1180,10 +1347,16 @@ done
shift $(($OPTIND - 1))
-for U in "${CC:-cc}" find grep od rm rmdir sed xargs; do
- if ! command -v "${U}" >>/dev/null 2>&1; then
- printf -- "${0##*/}: ${U}: command not found\n" >&2
- fi
+[ "${RECURSE}" = "yes" ] || MAXDEPTH=0
+
+
+for U in "${CC}" grep od rm rmdir sed xargs; do
+ ! command -v "${U}" >>/dev/null 2>&1 || continue
+
+ # ${CC} might have trailing flags or invoke the compiler through env
+ ! command -v "${U%% *}" >>/dev/null 2>&1 || continue
+
+ warn "%s: command not found" "${U}"
done
@@ -1191,15 +1364,13 @@ if [ -n "${SANDBOX}" ]; then
if [ "${SANDBOX}" = "${SANDBOX%/}" ]; then
if [ ! -c "${DEVRANDOM}" ]; then
# TODO: expand DEVRANDOM into set of different possibilities to check
- printf -- "${0##*/}: ${DEVRANDDOM}: no character random device available\n" >&2
- exit 1
+ panic "%s: no character random device available" "${DEVRANDOM}"
fi
TMP="${SANDBOX}$(od -An -N8 -tx1 < ${DEVRANDOM} 2>>/dev/null | tr -d ' ')"
if [ ${#TMP} -ne $((${#SANDBOX} + 16)) ]; then
- printf -- "${0##*/}: ${SANDBOX}: unable to generate random suffix\n" >&2
- exit 1
+ panic "%s: unable to generate random suffix" "${SANDBOX}"
fi
SANDBOX="${TMP}"
@@ -1241,18 +1412,28 @@ cppflags)
[ -z "${API_DIR:-}" ] || printf -- "-I${API_DIR}\n"
;;
+version)
+ findversion || exit 1
+
+ printf "$(((${API_VER} / 100) % 100)).$((($API_VER) % 100))\n"
+
+ ;;
ldflags)
findlib
[ "${LIBLUA_VER:-0}" -gt 0 ] || exit 1
- printf -- "-L${LIBLUA_DIR} -l${LIBLUA_LIB}\n"
+ if [ "${#LIBLUA_DIR}" -gt 0 ]; then
+ printf -- "-L%s\n" "${LIBLUA_DIR}"
+ fi
;;
-version)
- findversion || exit 1
+libs)
+ findlib
- printf "$(((${API_VER} / 100) % 100)).$((($API_VER) % 100))\n"
+ [ "${LIBLUA_VER:-0}" -gt 0 ] || exit 1
+
+ printf -- "-l%s\n" "${LIBLUA_LIB}"
;;
libv*)
@@ -1288,21 +1469,38 @@ lua)
;;
ldir|cdir)
- printf -- "${0##*/}: ${1}: deprecated command\n" >&2
- MODE="${1}"
- shift
+ #
+ # ldir and cdir were deprecated on 2014-12-18. On 2016-03-25 they
+ # were revived because their names are more intuitive than
+ # package.path and package.cpath. For now try to support the
+ # semantics of both by assuming interpreter glob patterns only match
+ # file names, while preferred install directory string.match
+ # expressions have directory components.
+ #
+ if true; then
+ MODE="${1}"
+
+ # move command to end; rotates to ${1} after loop
+ set -- "$@" "${1}"
+ shift
- if [ $# -gt 0 ]; then
- append GLOB $*
+ cdir_I=0
+ cdir_N="$(($# - 1))"
+ while [ "${cdir_I}" -lt "${cdir_N}" ]; do
+ if [ "${1#*/}" = "${1}" ]; then
+ append GLOB "${1}"
+ warn "%s: passing glob patterns to %s is deprecated" "${1}" "${MODE}"
+ else
+ set -- "$@" "${1}"
+ fi
+ shift
+ cdir_I=$((${cdir_I} + 1))
+ done
fi
findlua || exit 1
- if [ "${MODE}" = "cdir" ]; then
- findinstalldir package.cpath
- else
- findinstalldir package.path
- fi
+ findinstalldir "$@" || exit 1
;;
package.path|package.cpath)
@@ -1333,9 +1531,9 @@ testsym)
;;
*)
if [ -n "${1:-}" ]; then
- printf -- "${0##*/}: ${1}: unknown command\n" >&2
+ warn "%s: unknown command" "${1}"
else
- printf -- "${0##*/}: no command specified\n" >&2
+ warn "no command specified"
fi
exit 1
diff --git a/regress/00-store-verify.lua b/regress/00-store-verify.lua
new file mode 100755
index 0000000..f45ad7e
--- /dev/null
+++ b/regress/00-store-verify.lua
@@ -0,0 +1,19 @@
+#!/usr/bin/env lua
+
+require"regress".export".*"
+
+local st = store.new()
+
+local ca_key, ca_crt = genkey()
+st:add(ca_crt)
+
+local key, crt = genkey("RSA", ca_key, ca_crt)
+
+local ok, proof_or_reason = st:verify(crt)
+check(ok, "%s", proof_or_reason)
+
+--for _,crt in pairs(proof_or_reason) do
+-- print(crt:text())
+--end
+
+say"OK"
diff --git a/regress/53-csr-extensions.lua b/regress/53-csr-extensions.lua
new file mode 100644
index 0000000..38346da
--- /dev/null
+++ b/regress/53-csr-extensions.lua
@@ -0,0 +1,168 @@
+local auxlib = require"openssl.auxlib"
+local pkey = require "openssl.pkey"
+local x509_csr = require"_openssl.x509.csr"
+local x509_altname = require"openssl.x509.altname"
+local x509_name = require"openssl.x509.name"
+
+local _basename = arg and arg[0] and arg[0]:match"([^/]+)$" or "UNKNOWN"
+
+local function cluck(fmt, ...)
+ io.stderr:write(_basename, ": ", string.format(fmt, ...), "\n")
+end
+
+local function croak(fmt, ...)
+ io.stderr:write(_basename, ": ", string.format(fmt, ...), "\n")
+ os.exit(1)
+end
+
+local function OK()
+ cluck("OK")
+ return true
+end
+
+local _testno = 0
+local function testnames(altnames, expected)
+ local matched = {}
+
+ _testno = _testno + 1
+
+ for type,data in auxlib.pairs(altnames) do
+ local found
+
+ for i,e in ipairs(expected) do
+ if not matched[i] and e.type == type and e.data == data then
+ cluck("expected match #%d.%d found (%s=%s)", _testno, i, type,data)
+
+ matched[i] = true
+ found = true
+ end
+ end
+
+ if not found then
+ return false, string.format("extra name in test #%d (%s=%s)", _testno, type, data)
+ end
+ end
+
+ for i,e in ipairs(expected) do
+ if not matched[i] then
+ return false, string.format("expected match #%d.%d not found (%s=%s)", _testno, i, e.type, e.data)
+ end
+ end
+
+ return true
+end
+
+local function checknames(altnames, expected)
+ local ok, why = testnames(altnames, expected)
+
+ if not ok then
+ croak(why or "UNKNOWN")
+ end
+
+ return true
+end
+
+key = pkey.new({ bits = 4096 })
+
+data = [[
+-----BEGIN CERTIFICATE REQUEST-----
+MIIFQjCCAyoCAQAwUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1OMRQwEgYDVQQH
+DAtNaW5uZWFwb2xpczEhMB8GA1UECwwYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVk
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4sXzE3GQtpFKiuGe389k
+MB0OaGXQxiI/yl6zm9PyYWe5aMpx1THDVhkWXemDVkduEqtLfa8GSNT0ps3BPdTx
+qxNwZ3J9xiVfNZZYO5ZSxs1g32M1lw20wIezLpbQ1ggyt01o9VTQDY6kA+D0G87B
+4FtIZxVaXM2z5HVaGYyivxAygDukDsO+RU0NC9mYOfAP4rt/u/xp8LsW0b4aIFqx
+gPcBZj92B+Wi2B4sKSe1m5kMfmh+e8v981hbY7V8FUMebB63iRGF6GU4kjXiMMW6
+gSoc+usq9li8VxjxPngql9pyLqFIa/2gW0c9sKKB2X9tB0nmudjAUrjZjHZEDlNr
+yx15JHhEIT31yP9xGQpy5H+jBldp/shqaV4Alsou9Hn9W71ap7VHOWLrIcaZGKTn
+CVSSYPygn4Rm8Cgwbv5mP6G+SqGHAFqirEysAARUFxsjBLlkNaVFOA38l2cufH8n
+1NE/B4iOG/ETvQDR/aKrbyKKo2k/hO941h3J9pwJcCikE0NsRcH6WAm8ifJ0Zd/q
+u8fqI8g9mYPbMWy11+njnfNOVFVhNOmM1/ZM66ac9zgGYncaHu4UzYnvWw75tDbF
+vA+oIJlcxBUtWeTcYRf4xEcRL8IcHEwh1BZq7bgP42Wu+0aBuaa3eYXNBApCNP39
+QmnHlo0iGH2rVeOfcq/wULcCAwEAAaCBqTCBpgYJKoZIhvcNAQkOMYGYMIGVMAkG
+A1UdEwQCMAAwCwYDVR0PBAQDAgXgMHsGA1UdEQR0MHKCE3NlcnZlcjEuZXhhbXBs
+ZS5jb22CEG1haWwuZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYITd3d3LnN1
+Yi5leGFtcGxlLmNvbYIObXguZXhhbXBsZS5jb22CE3N1cHBvcnQuZXhhbXBsZS5j
+b20wDQYJKoZIhvcNAQEFBQADggIBAMiFPtDKVsy4HBhVkHSnbbIl41baaGGFjI/O
+MG8fI7P9jplq5rNZcLxSW2zLzMVuYzCoC+q5roRE5zVVyJlB+5dY0A8e2xKaWVOT
+AB9WvgepPvXDoGNViMBoX/idj3J2BU3e/cX08QWRPjKigwQWQWvUGsZYitGJv+Yv
+/LbIDlxr8Jr+1Txcm1EdXcff6Owlh6Nu59bgCMRdZvABmWfU5ULmUDTJnmc3P9St
+onz07v8ku8/XL7wwOfLJWVSVOk7RONySIJiPfVkgrU3YWiT64JaluDbFEIwnEgJS
+04xL6Pl66bADXCaeG3pZ8ypCs41+4bqFvCnOYma0Sk8fv8hSCWvJfMQI+nQslPJu
+UuGK4C4EEnYvoh/Qs/XEshfrVaNcG0zER3XtsRPAjhZjTPTcRgEjpOI0w3TJAvlN
+LSQV4mXN6E2bcU+cRYvNSgqITwJ7c6wpsONwApIQwFryLsFSCHaIdSLpAZbEPNEW
+UPa3uWXk5lWrBBPPkxyPbt8D3zpzahY4ycYEFKdz8MLdgA7pDalI2XpwgmoUybkw
+AJnsFg7fnFc03R4FsqxCqvbRYj3Bccb8Uhg1zTeXU+7nxjP2yYdT+In16L9SYOsU
+4ozEPqnGY9aI11i6C7hBwrUTvHYD6ZSDlylsUXKw/VZXQvS3+C0h6NuRmjBx8jNU
+RG1EyxL4
+-----END CERTIFICATE REQUEST-----
+]]
+
+-- baseline
+do
+ local expected = {
+ { type = "DNS", data = "server1.example.com" },
+ { type = "DNS", data = "mail.example.com" },
+ { type = "DNS", data = "www.example.com" },
+ { type = "DNS", data = "www.sub.example.com" },
+ { type = "DNS", data = "mx.example.com" },
+ { type = "DNS", data = "support.example.com" },
+ }
+
+ checknames((x509_csr.new(data)):getSubjectAlt(), expected)
+end
+
+-- modifying existing altnames
+do
+ local expected = {
+ { type = "DNS", data = "foo.com" },
+ { type = "DNS", data = "*.foo.com" },
+ }
+
+ local csr = x509_csr.new(data)
+ local gn = x509_altname.new()
+ gn:add("DNS", "foo.com")
+ gn:add("DNS", "*.foo.com")
+ csr:setSubjectAlt(gn)
+ csr:setPublicKey(key)
+ csr:sign(key)
+
+ -- check modified object
+ checknames(csr:getSubjectAlt(), expected)
+ -- check after a round-trip through PEM
+ checknames(x509_csr.new(tostring(csr)):getSubjectAlt(), expected)
+end
+
+-- adding altnames where none existed
+do
+ local expected = {
+ name = {
+ { type = "CN", data = "example.com" },
+ },
+ altname = {
+ { type = "DNS", data = "foo.com" },
+ { type = "DNS", data = "*.foo.com" },
+ },
+ }
+
+ local csr = x509_csr.new()
+ local name = x509_name.new()
+ name:add("CN", "example.com")
+ csr:setSubject(name)
+ local gn = x509_altname.new()
+ gn:add("DNS", "foo.com")
+ gn:add("DNS", "*.foo.com")
+ csr:setSubjectAlt(gn)
+ csr:setPublicKey(key)
+ csr:sign(key)
+
+ checknames(csr:getSubject(), expected.name)
+ checknames(csr:getSubjectAlt(), expected.altname)
+
+ local csr1 = x509_csr.new(tostring(csr))
+ checknames(csr1:getSubject(), expected.name)
+ checknames(csr1:getSubjectAlt(), expected.altname)
+end
+
+return OK()
+
diff --git a/regress/regress.lua b/regress/regress.lua
new file mode 100644
index 0000000..8d955ea
--- /dev/null
+++ b/regress/regress.lua
@@ -0,0 +1,161 @@
+local regress = {
+ openssl = require"openssl",
+ pkey = require"openssl.pkey",
+ x509 = require"openssl.x509",
+ name = require"openssl.x509.name",
+ altname = require"openssl.x509.altname",
+ store = require"openssl.x509.store",
+ pack = table.pack or function (...)
+ local t = { ... }
+ t.n = select("#", ...)
+ return t
+ end,
+ unpack = table.unpack or unpack,
+}
+
+local emit_progname = os.getenv"REGRESS_PROGNAME" or "regress"
+local emit_verbose = tonumber(os.getenv"REGRESS_VERBOSE" or 1)
+local emit_info = {}
+local emit_ll = 0
+
+local function emit(fmt, ...)
+ local msg = string.format(fmt, ...)
+
+ for txt, nl in msg:gmatch("([^\n]*)(\n?)") do
+ if emit_ll == 0 and #txt > 0 then
+ io.stderr:write(emit_progname, ": ")
+ emit_ll = #emit_progname + 2
+ end
+
+ io.stderr:write(txt, nl)
+
+ if nl == "\n" then
+ emit_ll = 0
+ else
+ emit_ll = emit_ll + #txt
+ end
+ end
+end -- emit
+
+local function emitln(fmt, ...)
+ if emit_ll > 0 then
+ emit"\n"
+ end
+
+ emit(fmt .. "\n", ...)
+end -- emitln
+
+local function emitinfo()
+ for _, txt in ipairs(emit_info) do
+ emitln("%s", txt)
+ end
+end -- emitinfo
+
+function regress.say(...)
+ emitln(...)
+end -- say
+
+function regress.panic(...)
+ emitinfo()
+ emitln(...)
+ os.exit(1)
+end -- panic
+
+function regress.info(...)
+ if emit_verbose > 1 then
+ emitln(...)
+ else
+ emit_info[#emit_info + 1] = string.format(...)
+
+ if emit_verbose > 0 then
+ if emit_ll > 78 then
+ emit"\n."
+ else
+ emit"."
+ end
+ end
+ end
+end -- info
+
+function regress.check(v, ...)
+ if v then
+ return v, ...
+ else
+ regress.panic(...)
+ end
+end -- check
+
+function regress.export(...)
+ for _, pat in ipairs{ ... } do
+ for k, v in pairs(regress) do
+ if string.match(k, pat) then
+ _G[k] = v
+ end
+ end
+ end
+
+ return regress
+end -- export
+
+local counter = 0
+function regress.genkey(type, ca_key, ca_crt)
+ local pkey = require"openssl.pkey"
+ local x509 = require"openssl.x509"
+ local name = require"openssl.x509.name"
+ local altname = require"openssl.x509.altname"
+ local key
+
+ type = string.upper(type or "RSA")
+
+ if type == "EC" then
+ key = regress.check(pkey.new{ type = "EC", curve = "prime192v1" })
+ else
+ key = regress.check(pkey.new{ type = type, bits = 1024 })
+ end
+
+ local dn = name.new()
+ dn:add("C", "US")
+ dn:add("ST", "California")
+ dn:add("L", "San Francisco")
+ dn:add("O", "Acme, Inc.")
+ dn:add("CN", string.format("acme%d.inc", counter))
+ counter = counter + 1
+
+ local alt = altname.new()
+ alt:add("DNS", "acme.inc")
+ alt:add("DNS", "localhost")
+
+ local crt = x509.new()
+ crt:setVersion(3)
+ crt:setSerial(47)
+ crt:setSubject(dn)
+ crt:setIssuer((ca_crt or crt):getSubject())
+ crt:setSubjectAlt(alt)
+
+ local issued, expires = crt:getLifetime()
+ crt:setLifetime(issued, expires + 60)
+
+ crt:setBasicConstraints{ CA = true, pathLen = 2 }
+ crt:setBasicConstraintsCritical(true)
+
+ crt:setPublicKey(key)
+ crt:sign(ca_key or key)
+
+ return key, crt
+end -- regress.genkey
+
+local function getsubtable(t, name, ...)
+ name = name or false -- cannot be nil
+
+ if not t[name] then
+ t[name] = {}
+ end
+
+ if select('#', ...) > 0 then
+ return getsubtable(t[name], ...)
+ else
+ return t[name]
+ end
+end -- getsubtable
+
+return regress
diff --git a/src/GNUmakefile b/src/GNUmakefile
index 3aff30a..e7cb54d 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -18,9 +18,9 @@ include $(d)/../GNUmakefile
#
OS_$(d) = $(shell $(d)/../mk/vendor.os)
CC_$(d) = $(shell env CC="$(CC) "$(d)/../mk/vendor.cc)
-LUAPATH_$(d) = $(shell env CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(<D)/../mk/lua.path -krxm3 -I$(DESTDIR)$(includedir) -I/usr/include -I/usr/local/include -P$(DESTDIR)$(bindir) -P$(bindir) -L$(DESTDIR)$(libdir) -L$(libdir) -v$(1) $(2))
+LUAPATH_$(d) = $(shell env CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(<D)/../mk/luapath -krxm3 -I$(DESTDIR)$(includedir) -I/usr/include -I/usr/local/include -P$(DESTDIR)$(bindir) -P$(bindir) -L$(DESTDIR)$(libdir) -L$(libdir) -v$(1) $(2))
-CPPFLAGS_$(d) = $(CPPFLAGS_$(abspath $(@D)/../..)) -DLUA_COMPAT_APIINTCASTS
+CPPFLAGS_$(d) = $(CPPFLAGS_$(abspath $(@D)/../..)) -DLUA_COMPAT_APIINTCASTS -DHAVE_CONFIG_H
CFLAGS_$(d) = $(CFLAGS_$(abspath $(@D)/../..))
LDFLAGS_$(d) = $(LDFLAGS_$(abspath $(@D)/../..))
SOFLAGS_$(d) = $(SOFLAGS_$(abspath $(@D)/../..))
@@ -41,6 +41,8 @@ endif
#
# C O M P I L A T I O N R U L E S
#
+$(d)/config.h: $(abspath $(d)/..)/config.h
+ $(CP) $< $@
define BUILD_$(d)
@@ -49,7 +51,7 @@ define BUILD_$(d)
$$(d)/$(1)/openssl.so: $$(d)/$(1)/openssl.o
$$(CC) -o $$@ $$^ $$(SOFLAGS_$$(abspath $$(@D)/..)) $$(SOFLAGS) $$(LDFLAGS_$$(abspath $$(@D)/..)) $$(LDFLAGS)
-$$(d)/$(1)/openssl.o: $$(d)/openssl.c $$(d)/compat52.h
+$$(d)/$(1)/openssl.o: $$(d)/openssl.c $$(d)/compat52.h $$(d)/config.h
test "$$(notdir $$(@D))" = "$$(call LUAPATH_$$(<D), $$(notdir $$(@D)), version)"
$$(MKDIR) -p $$(@D)
$$(CC) $$(CFLAGS_$$(<D)) $$(CFLAGS) $$(call LUAPATH_$$(<D), $$(notdir $$(@D)), cppflags) $$(CPPFLAGS_$$(<D)) $$(CPPFLAGS) -c -o $$@ $$<
@@ -88,6 +90,7 @@ LUAC$(1)_$(d) = $$(or $$(call LUAPATH_$(d), $(1), luac), true)
MODS$(1)_$(d) = \
$$(DESTDIR)$(2)/_openssl.so \
$$(DESTDIR)$(3)/openssl.lua \
+ $$(DESTDIR)$(3)/openssl/auxlib.lua \
$$(DESTDIR)$(3)/openssl/bignum.lua \
$$(DESTDIR)$(3)/openssl/pkey.lua \
$$(DESTDIR)$(3)/openssl/pubkey.lua \
diff --git a/src/openssl.auxlib.lua b/src/openssl.auxlib.lua
new file mode 100644
index 0000000..4f00c25
--- /dev/null
+++ b/src/openssl.auxlib.lua
@@ -0,0 +1,21 @@
+local auxlib = {}
+
+if _VERSION == "Lua 5.1" then
+ local _pairs = pairs
+
+ function auxlib.pairs(t)
+ if type(t) == "userdata" then
+ local mt = getmetatable(t)
+
+ if mt and mt.__pairs then
+ return mt.__pairs(t)
+ else
+ return _pairs(t)
+ end
+ end
+ end
+else
+ auxlib.pairs = pairs
+end
+
+return auxlib
diff --git a/src/openssl.c b/src/openssl.c
index 2275d49..ed7222e 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -23,6 +23,10 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE.
* ==========================================================================
*/
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <limits.h> /* INT_MAX INT_MIN LLONG_MAX LLONG_MIN UCHAR_MAX ULLONG_MAX */
#include <stdint.h> /* uintptr_t */
#include <string.h> /* memset(3) strerror_r(3) */
@@ -79,24 +83,40 @@
#define LIBRESSL_PREREQ(M, m, p) \
(LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)))
-#ifndef HAVE_DLADDR
-#define HAVE_DLADDR (!defined _AIX) /* TODO: https://root.cern.ch/drupal/content/aix-and-dladdr */
+#ifndef HAVE_ASN1_STRING_GET0_DATA
+#define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
-#define HAVE_SSL_CTX_SET_ALPN_PROTOS OPENSSL_PREREQ(1, 0, 2)
+#ifndef HAVE_DH_GET0_KEY
+#define HAVE_DH_GET0_KEY OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
-#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifndef HAVE_DH_GET0_PQG
+#define HAVE_DH_GET0_PQG OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_SET_ALPN_PROTOS
-#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifndef HAVE_DH_SET0_KEY
+#define HAVE_DH_SET0_KEY OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_GET0_ALPN_SELECTED
-#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifndef HAVE_DH_SET0_PQG
+#define HAVE_DH_SET0_PQG OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_GET0_KEY
+#define HAVE_DSA_GET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_GET0_PQG
+#define HAVE_DSA_GET0_PQG OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_SET0_KEY
+#define HAVE_DSA_SET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_SET0_PQG
+#define HAVE_DSA_SET0_PQG OPENSSL_PREREQ(1,1,0)
#endif
#ifndef HAVE_DTLSV1_CLIENT_METHOD
@@ -108,7 +128,7 @@
#endif
#ifndef HAVE_DTLS_CLIENT_METHOD
-#define HAVE_DTLS_CLIENT_METHOD (OPENSSL_PREREQ(1, 0, 2) && !defined OPENSSL_NO_DTLS1)
+#define HAVE_DTLS_CLIENT_METHOD (OPENSSL_PREREQ(1,0,2) && !defined OPENSSL_NO_DTLS1)
#endif
#ifndef HAVE_DTLS_SERVER_METHOD
@@ -116,13 +136,133 @@
#endif
#ifndef HAVE_DTLSV1_2_CLIENT_METHOD
-#define HAVE_DTLSV1_2_CLIENT_METHOD (OPENSSL_PREREQ(1, 0, 2) && !defined OPENSSL_NO_DTLS1)
+#define HAVE_DTLSV1_2_CLIENT_METHOD (OPENSSL_PREREQ(1,0,2) && !defined OPENSSL_NO_DTLS1)
#endif
#ifndef HAVE_DTLSV1_2_SERVER_METHOD
#define HAVE_DTLSV1_2_SERVER_METHOD HAVE_DTLSV1_2_CLIENT_METHOD
#endif
+#ifndef HAVE_EVP_CIPHER_CTX_FREE
+#define HAVE_EVP_CIPHER_CTX_FREE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_CIPHER_CTX_NEW
+#define HAVE_EVP_CIPHER_CTX_NEW OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_MD_CTX_FREE
+#define HAVE_EVP_MD_CTX_FREE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_MD_CTX_NEW
+#define HAVE_EVP_MD_CTX_NEW OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID
+#define HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID OPENSSL_PREREQ(0,9,9)
+#endif
+
+#ifndef HAVE_EVP_PKEY_BASE_ID
+#define HAVE_EVP_PKEY_BASE_ID OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_PKEY_GET0
+#define HAVE_EVP_PKEY_GET0 OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_PKEY_ID
+#define HAVE_EVP_PKEY_ID OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_HMAC_CTX_FREE
+#define HAVE_HMAC_CTX_FREE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_HMAC_CTX_NEW
+#define HAVE_HMAC_CTX_NEW OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_I2D_RE_X509_REQ_TBS
+#define HAVE_I2D_RE_X509_REQ_TBS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_GET0_CRT_PARAMS
+#define HAVE_RSA_GET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_GET0_FACTORS
+#define HAVE_RSA_GET0_FACTORS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_GET0_KEY
+#define HAVE_RSA_GET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_SET0_CRT_PARAMS
+#define HAVE_RSA_SET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_SET0_FACTORS
+#define HAVE_RSA_SET0_FACTORS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_SET0_KEY
+#define HAVE_RSA_SET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_CLIENT_VERSION
+#define HAVE_SSL_CLIENT_VERSION OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
+#define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,1,3))
+#endif
+
+#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
+#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS
+#endif
+
+#ifndef HAVE_SSL_CTX_SET1_CERT_STORE
+#define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */
+#endif
+
+#ifndef HAVE_SSL_CTX_CERT_STORE
+#define HAVE_SSL_CTX_CERT_STORE (!OPENSSL_PREREQ(1,1,0))
+#endif
+
+#ifndef HAVE_SSL_SET_ALPN_PROTOS
+#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
+#endif
+
+#ifndef HAVE_SSL_GET0_ALPN_SELECTED
+#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
+#endif
+
+#ifndef HAVE_SSL_UP_REF
+#define HAVE_SSL_UP_REF OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSLV2_CLIENT_METHOD
+#define HAVE_SSLV2_CLIENT_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
+#endif
+
+#ifndef HAVE_SSLV2_SERVER_METHOD
+#define HAVE_SSLV2_SERVER_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
+#endif
+
+#ifndef HAVE_X509_STORE_REFERENCES
+#define HAVE_X509_STORE_REFERENCES (!OPENSSL_PREREQ(1,1,0))
+#endif
+
+#ifndef HAVE_X509_UP_REF
+#define HAVE_X509_UP_REF OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HMAC_INIT_EX_INT
+#define HMAC_INIT_EX_INT OPENSSL_PREREQ(1,0,0)
+#endif
+
#ifndef STRERROR_R_CHAR_P
#define STRERROR_R_CHAR_P (defined __GLIBC__ && (_GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)))
#endif
@@ -161,9 +301,9 @@
#define PKCS12_CLASS "PKCS12*"
#define SSL_CTX_CLASS "SSL_CTX*"
#define SSL_CLASS "SSL*"
-#define DIGEST_CLASS "EVP_MD_CTX" /* not a pointer */
-#define HMAC_CLASS "HMAC_CTX" /* not a pointer */
-#define CIPHER_CLASS "EVP_CIPHER_CTX" /* not a pointer */
+#define DIGEST_CLASS "EVP_MD_CTX*"
+#define HMAC_CLASS "HMAC_CTX*"
+#define CIPHER_CLASS "EVP_CIPHER_CTX*"
#if __GNUC__
@@ -488,6 +628,13 @@ static const char *aux_strerror_r(int error, char *dst, size_t lim) {
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+static void auxS_bn_free_and_set0(BIGNUM **dst, BIGNUM *src) {
+ if (*dst) {
+ BN_clear_free(*dst);
+ }
+ *dst = src;
+} /* auxS_bn_free_and_set0() */
+
static size_t auxS_nid2sn(void *dst, size_t lim, int nid) {
const char *sn;
@@ -1021,14 +1168,173 @@ static struct {
.X509_STORE_free = &X509_STORE_free,
};
+#if !HAVE_ASN1_STRING_GET0_DATA
+#define ASN1_STRING_get0_data(s) ASN1_STRING_data((s))
+#endif
+
+#if !HAVE_DH_GET0_KEY
+#define DH_get0_key(...) compat_DH_get0_key(__VA_ARGS__)
+
+static void compat_DH_get0_key(const DH *d, const BIGNUM **pub_key, const BIGNUM **priv_key) {
+ if (pub_key)
+ *pub_key = d->pub_key;
+ if (priv_key)
+ *priv_key = d->priv_key;
+} /* compat_DH_get0_key() */
+#endif
+
+#if !HAVE_DH_GET0_PQG
+#define DH_get0_pqg(...) compat_DH_get0_pqg(__VA_ARGS__)
+
+static void compat_DH_get0_pqg(const DH *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
+ if (p)
+ *p = d->p;
+ if (q)
+ *q = d->q;
+ if (g)
+ *g = d->g;
+} /* compat_DH_get0_pqg() */
+#endif
+
+#if !HAVE_DH_SET0_KEY
+#define DH_set0_key(...) compat_DH_set0_key(__VA_ARGS__)
+
+static void compat_DH_set0_key(DH *d, BIGNUM *pub_key, BIGNUM *priv_key) {
+ if (pub_key)
+ auxS_bn_free_and_set0(&d->pub_key, pub_key);
+ if (priv_key)
+ auxS_bn_free_and_set0(&d->priv_key, priv_key);
+} /* compat_DH_set0_key() */
+#endif
+
+#if !HAVE_DH_SET0_PQG
+#define DH_set0_pqg(...) compat_DH_set0_pqg(__VA_ARGS__)
+
+static void compat_DH_set0_pqg(DH *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
+ if (p)
+ auxS_bn_free_and_set0(&d->p, p);
+ if (q)
+ auxS_bn_free_and_set0(&d->q, q);
+ if (g)
+ auxS_bn_free_and_set0(&d->g, g);
+} /* compat_DH_set0_pqg() */
+#endif
+
+#if !HAVE_DSA_GET0_KEY
+#define DSA_get0_key(...) compat_DSA_get0_key(__VA_ARGS__)
+
+static void compat_DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) {
+ if (pub_key)
+ *pub_key = d->pub_key;
+ if (priv_key)
+ *priv_key = d->priv_key;
+} /* compat_DSA_get0_key() */
+#endif
+
+#if !HAVE_DSA_GET0_PQG
+#define DSA_get0_pqg(...) compat_DSA_get0_pqg(__VA_ARGS__)
+
+static void compat_DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
+ if (p)
+ *p = d->p;
+ if (q)
+ *q = d->q;
+ if (g)
+ *g = d->g;
+} /* compat_DSA_get0_pqg() */
+#endif
+
+#if !HAVE_DSA_SET0_KEY
+#define DSA_set0_key(...) compat_DSA_set0_key(__VA_ARGS__)
+
+static void compat_DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) {
+ if (pub_key)
+ auxS_bn_free_and_set0(&d->pub_key, pub_key);
+ if (priv_key)
+ auxS_bn_free_and_set0(&d->priv_key, priv_key);
+} /* compat_DSA_set0_key() */
+#endif
+
+#if !HAVE_DSA_SET0_PQG
+#define DSA_set0_pqg(...) compat_DSA_set0_pqg(__VA_ARGS__)
+
+static void compat_DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
+ if (p)
+ auxS_bn_free_and_set0(&d->p, p);
+ if (q)
+ auxS_bn_free_and_set0(&d->q, q);
+ if (g)
+ auxS_bn_free_and_set0(&d->g, g);
+} /* compat_DSA_set0_pqg() */
+#endif
+
+#if !HAVE_EVP_CIPHER_CTX_FREE
+#define EVP_CIPHER_CTX_free(ctx) compat_EVP_CIPHER_CTX_free((ctx))
+
+static void compat_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) {
+ EVP_CIPHER_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+} /* compat_EVP_CIPHER_CTX_free() */
+#endif
+
+#if !HAVE_EVP_CIPHER_CTX_NEW
+#define EVP_CIPHER_CTX_new() compat_EVP_CIPHER_CTX_new()
+
+static EVP_CIPHER_CTX *compat_EVP_CIPHER_CTX_new(void) {
+ EVP_CIPHER_CTX *ctx;
+
+ if (!(ctx = OPENSSL_malloc(sizeof *ctx)))
+ return NULL;
+ memset(ctx, 0, sizeof *ctx);
+ EVP_CIPHER_CTX_init(ctx);
+
+ return ctx;
+} /* compat_EVP_CIPHER_CTX_new() */
+#endif
+
+#if !HAVE_EVP_MD_CTX_FREE
+#define EVP_MD_CTX_free(md) EVP_MD_CTX_destroy((md))
+#endif
+
+#if !HAVE_EVP_MD_CTX_NEW
+#define EVP_MD_CTX_new(md) EVP_MD_CTX_create()
+#endif
+
+#if !HAVE_EVP_PKEY_ID
+#define EVP_PKEY_id(key) ((key)->type)
+#endif
+
#if !HAVE_EVP_PKEY_BASE_ID
#define EVP_PKEY_base_id(key) compat_EVP_PKEY_base_id((key))
static int compat_EVP_PKEY_base_id(EVP_PKEY *key) {
- return EVP_PKEY_type(key->type);
+ return EVP_PKEY_type(EVP_PKEY_id(key));
} /* compat_EVP_PKEY_base_id() */
#endif
+#if !HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID
+#define EVP_PKEY_get_default_digest_nid(...) \
+ compat_EVP_PKEY_get_default_digest_nid(__VA_ARGS__)
+
+static int compat_EVP_PKEY_get_default_digest_nid(EVP_PKEY *key, int *nid) {
+ switch (EVP_PKEY_base_id(key)) {
+ case EVP_PKEY_RSA:
+ *nid = EVP_MD_nid(EVP_sha1());
+ break;
+ case EVP_PKEY_DSA:
+ *nid = EVP_MD_nid(EVP_dss1());
+ break;
+ case EVP_PKEY_EC:
+ *nid = EVP_MD_nid(EVP_ecdsa());
+ break;
+ default:
+ *nid = EVP_MD_nid(EVP_sha1());
+ break;
+ }
+
+ return 1;
+} /* compat_EVP_PKEY_get_default_digest_nid() */
+#endif
#if !HAVE_EVP_PKEY_GET0
#define EVP_PKEY_get0(key) compat_EVP_PKEY_get0((key))
@@ -1065,6 +1371,123 @@ static void *compat_EVP_PKEY_get0(EVP_PKEY *key) {
} /* compat_EVP_PKEY_get0() */
#endif
+#if !HAVE_HMAC_CTX_FREE
+#define HMAC_CTX_free(ctx) compat_HMAC_CTX_free((ctx))
+
+static void compat_HMAC_CTX_free(HMAC_CTX *ctx) {
+ HMAC_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+} /* compat_HMAC_CTX_free() */
+#endif
+
+#if !HAVE_HMAC_CTX_NEW
+#define HMAC_CTX_new() compat_HMAC_CTX_new()
+
+static HMAC_CTX *compat_HMAC_CTX_new(void) {
+ HMAC_CTX *ctx;
+
+ if (!(ctx = OPENSSL_malloc(sizeof *ctx)))
+ return NULL;
+ memset(ctx, 0, sizeof *ctx);
+
+ return ctx;
+} /* compat_HMAC_CTX_new() */
+#endif
+
+#if !HAVE_RSA_GET0_CRT_PARAMS
+#define RSA_get0_crt_params(...) compat_RSA_get0_crt_params(__VA_ARGS__)
+
+static void compat_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) {
+ if (dmp1)
+ *dmp1 = r->dmp1;
+ if (dmq1)
+ *dmq1 = r->dmq1;
+ if (iqmp)
+ *iqmp = r->iqmp;
+} /* compat_RSA_get0_crt_params() */
+#endif
+
+#if !HAVE_RSA_GET0_FACTORS
+#define RSA_get0_factors(...) compat_RSA_get0_factors(__VA_ARGS__)
+
+static void compat_RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) {
+ if (p)
+ *p = r->p;
+ if (q)
+ *q = r->q;
+} /* compat_RSA_get0_factors() */
+#endif
+
+#if !HAVE_RSA_GET0_KEY
+#define RSA_get0_key(...) compat_RSA_get0_key(__VA_ARGS__)
+
+static void compat_RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) {
+ if (n)
+ *n = r->n;
+ if (e)
+ *e = r->e;
+ if (d)
+ *d = r->d;
+} /* compat_RSA_get0_key() */
+#endif
+
+#if !HAVE_RSA_SET0_CRT_PARAMS
+#define RSA_set0_crt_params(...) compat_RSA_set0_crt_params(__VA_ARGS__)
+
+static void compat_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) {
+ if (dmp1)
+ auxS_bn_free_and_set0(&r->dmp1, dmp1);
+ if (dmq1)
+ auxS_bn_free_and_set0(&r->dmq1, dmq1);
+ if (iqmp)
+ auxS_bn_free_and_set0(&r->iqmp, iqmp);
+} /* compat_RSA_set0_crt_params() */
+#endif
+
+#if !HAVE_RSA_SET0_FACTORS
+#define RSA_set0_factors(...) compat_RSA_set0_factors(__VA_ARGS__)
+
+static void compat_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) {
+ if (p)
+ auxS_bn_free_and_set0(&r->p, p);
+ if (q)
+ auxS_bn_free_and_set0(&r->q, q);
+} /* compat_RSA_set0_factors() */
+#endif
+
+#if !HAVE_RSA_SET0_KEY
+#define RSA_set0_key(...) compat_RSA_set0_key(__VA_ARGS__)
+
+static void compat_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
+ if (n)
+ auxS_bn_free_and_set0(&r->n, n);
+ if (e)
+ auxS_bn_free_and_set0(&r->e, e);
+ if (d)
+ auxS_bn_free_and_set0(&r->d, d);
+} /* compat_RSA_set0_key() */
+#endif
+
+#if !HAVE_SSL_CLIENT_VERSION
+#define SSL_client_version(...) compat_SSL_client_version(__VA_ARGS__)
+
+static int compat_SSL_client_version(const SSL *ssl) {
+ return ssl->client_version;
+} /* compat_SSL_client_version() */
+#endif
+
+#if !HAVE_SSL_UP_REF
+#define SSL_up_ref(...) compat_SSL_up_ref(__VA_ARGS__)
+
+static int compat_SSL_up_ref(SSL *ssl) {
+ /* our caller should already have had a proper reference */
+ if (CRYPTO_add(&ssl->references, 1, CRYPTO_LOCK_SSL) < 2)
+ return 0; /* fail */
+
+ return 1;
+} /* compat_SSL_up_ref() */
+#endif
+
#if !HAVE_X509_GET0_EXT
#define X509_get0_ext(crt, i) X509_get_ext((crt), (i))
#endif
@@ -1081,13 +1504,18 @@ static void *compat_EVP_PKEY_get0(EVP_PKEY *key) {
#define X509_EXTENSION_get0_data(ext) X509_EXTENSION_get_data((ext))
#endif
+#if HAVE_X509_STORE_REFERENCES
/*
* X509_STORE_free in OpenSSL versions < 1.0.2 doesn't obey reference count
*/
#define X509_STORE_free(store) \
(compat.X509_STORE_free)((store))
-static void compat_X509_STORE_free(X509_STORE *store) {
+/* to support preprocessor detection below */
+#define compat_X509_STORE_free(store) \
+ compat_X509_STORE_free((store))
+
+static void (compat_X509_STORE_free)(X509_STORE *store) {
int i;
i = CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE);
@@ -1097,12 +1525,21 @@ static void compat_X509_STORE_free(X509_STORE *store) {
(X509_STORE_free)(store);
} /* compat_X509_STORE_free() */
+#endif
-#if !HAVE_SSL_CTX_set1_cert_store
+#if !HAVE_SSL_CTX_SET1_CERT_STORE
+#if !HAVE_SSL_CTX_CERT_STORE || !HAVE_X509_STORE_REFERENCES
#define SSL_CTX_set1_cert_store(ctx, store) \
+ SSL_CTX_set_cert_store((ctx), (store))
+#else
+#define SSL_CTX_set1_cert_store(ctx, store) \
+ compat_SSL_CTX_set1_cert_store((ctx), (store))
+
+/* to support preprocessor detection below */
+#define compat_SSL_CTX_set1_cert_store(ctx, store) \
compat_SSL_CTX_set1_cert_store((ctx), (store))
-static void compat_SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) {
+static void (compat_SSL_CTX_set1_cert_store)(SSL_CTX *ctx, X509_STORE *store) {
int n;
/*
@@ -1122,6 +1559,9 @@ static void compat_SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) {
CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
} /* compat_SSL_CTX_set1_cert_store() */
#endif
+#endif
+
+#if HAVE_SSL_CTX_CERT_STORE
static void compat_init_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
SSL_CTX *ctx = _ctx;
@@ -1132,6 +1572,8 @@ static void compat_init_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX
}
} /* compat_init_SSL_CTX_onfree() */
+#endif
+
/* helper routine to determine if X509_STORE_free obeys reference count */
static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
/* unfortunately there's no way to remove a handler */
@@ -1142,6 +1584,18 @@ static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPT
compat.tmp.store = NULL;
} /* compat_init_X509_STORE_onfree() */
+#if !HAVE_X509_UP_REF
+#define X509_up_ref(...) compat_X509_up_ref(__VA_ARGS__)
+
+static int compat_X509_up_ref(X509 *crt) {
+ /* our caller should already have had a proper reference */
+ if (CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509) < 2)
+ return 0; /* fail */
+
+ return 1;
+} /* compat_X509_up_ref() */
+#endif
+
static int compat_init(void) {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int store_index = -1, ssl_ctx_index = -1, done;
@@ -1161,6 +1615,7 @@ static int compat_init(void) {
if ((error = dl_anchor()))
goto epilog;
+#if defined compat_X509_STORE_free
/*
* Test if X509_STORE_free obeys reference counts by installing an
* onfree callback.
@@ -1210,6 +1665,7 @@ static int compat_init(void) {
compat.flags |= COMPAT_X509_STORE_FREE_BUG;
}
+#endif
done = 1;
epilog:
@@ -1262,7 +1718,13 @@ static struct ex_type {
[EX_SSL_CTX_ALPN_SELECT_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data },
};
-static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, CRYPTO_EX_DATA *from NOTUSED, void *from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
+#if OPENSSL_PREREQ(1,1,0)
+typedef const CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
+#else
+typedef CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
+#endif
+
+static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, const_CRYPTO_EX_DATA *from NOTUSED, void *from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
struct ex_data **data = from_d;
if (*data)
@@ -1861,13 +2323,13 @@ static BIGNUM *(checkbig)(lua_State *L, int index, _Bool *lvalue) {
if (hex) {
luaL_argcheck(L, len > 2+(size_t)neg, index, "invalid hex string");
for (i = 2+neg; i < len; i++) {
- if (!isxdigit(str[i]))
+ if (!isxdigit((unsigned char)str[i]))
luaL_argerror(L, 1, "invalid hex string");
}
} else {
luaL_argcheck(L, len > neg, index, "invalid decimal string");
for (i = neg; i < len; i++) {
- if (!isdigit(str[i]))
+ if (!isdigit((unsigned char)str[i]))
luaL_argerror(L, 1, "invalid decimal string");
}
}
@@ -2644,7 +3106,7 @@ static int pk_interpose(lua_State *L) {
static int pk_type(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
- int nid = key->type;
+ int nid = EVP_PKEY_id(key);
auxL_pushnid(L, nid);
@@ -2718,7 +3180,7 @@ static int pk_setPrivateKey(lua_State *L) {
static int pk_sign(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
- EVP_MD_CTX *md = luaL_checkudata(L, 2, DIGEST_CLASS);
+ EVP_MD_CTX *md = checksimple(L, 2, DIGEST_CLASS);
luaL_Buffer B;
unsigned n;
@@ -2742,7 +3204,7 @@ static int pk_verify(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
size_t len;
const void *sig = luaL_checklstring(L, 2, &len);
- EVP_MD_CTX *md = luaL_checkudata(L, 3, DIGEST_CLASS);
+ EVP_MD_CTX *md = checksimple(L, 3, DIGEST_CLASS);
switch (EVP_VerifyFinal(md, sig, len, key)) {
case 0: /* WRONG */
@@ -2806,7 +3268,7 @@ static int pk_toPEM(lua_State *L) {
#if 0
case 4: case 5: /* params, Parameters */
/* EVP_PKEY_base_id not in OS X */
- switch (EVP_PKEY_type(key->type)) {
+ switch (EVP_PKEY_base_id(key)) {
case EVP_PKEY_RSA:
break;
case EVP_PKEY_DSA: {
@@ -2849,7 +3311,7 @@ static int pk_toPEM(lua_State *L) {
}
#endif
default:
- return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_type(key->type));
+ return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_base_id(key));
}
lua_pushlstring(L, pem, len);
@@ -2869,6 +3331,26 @@ static int pk_toPEM(lua_State *L) {
} /* pk_toPEM() */
+static int pk_getDefaultDigestName(lua_State *L) {
+ EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
+ int nid;
+ char txt[256];
+ size_t len;
+
+ if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
+ return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
+
+ if (!(len = auxS_nid2txt(txt, sizeof txt, nid)))
+ return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
+ if (len > sizeof txt)
+ return auxL_error(L, EOVERFLOW, "pkey:getDefaultDigestName");
+
+ lua_pushlstring(L, txt, len);
+
+ return 1;
+} /* pk_getDefaultDigestName() */
+
+
enum pk_param {
#define PK_RSA_OPTLIST { "n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp", NULL }
#define PK_RSA_OPTOFFSET PK_RSA_N
@@ -2965,82 +3447,100 @@ static void pk_pushparam(lua_State *L, void *base_key, enum pk_param which) {
EC_KEY *ec;
#endif
} key = { base_key };
+ const BIGNUM *i;
switch (which) {
case PK_RSA_N:
/* RSA public modulus n */
- bn_dup_nil(L, key.rsa->n);
+ RSA_get0_key(key.rsa, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_E:
/* RSA public exponent e */
- bn_dup_nil(L, key.rsa->e);
+ RSA_get0_key(key.rsa, NULL, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_D:
/* RSA secret exponent d */
- bn_dup_nil(L, key.rsa->d);
+ RSA_get0_key(key.rsa, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_RSA_P:
/* RSA secret prime p */
- bn_dup_nil(L, key.rsa->p);
+ RSA_get0_factors(key.rsa, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_Q:
/* RSA secret prime q with p < q */
- bn_dup_nil(L, key.rsa->q);
+ RSA_get0_factors(key.rsa, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_RSA_DMP1:
/* exponent1 */
- bn_dup_nil(L, key.rsa->dmp1);
+ RSA_get0_crt_params(key.rsa, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_DMQ1:
/* exponent2 */
- bn_dup_nil(L, key.rsa->dmq1);
+ RSA_get0_crt_params(key.rsa, NULL, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_IQMP:
/* coefficient */
- bn_dup_nil(L, key.rsa->iqmp);
+ RSA_get0_crt_params(key.rsa, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DSA_P:
- bn_dup_nil(L, key.dsa->p);
+ DSA_get0_pqg(key.dsa, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DSA_Q:
- bn_dup_nil(L, key.dsa->q);
+ DSA_get0_pqg(key.dsa, NULL, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DSA_G:
- bn_dup_nil(L, key.dsa->g);
+ DSA_get0_pqg(key.dsa, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DSA_PUB_KEY:
- bn_dup_nil(L, key.dsa->pub_key);
+ DSA_get0_key(key.dsa, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DSA_PRIV_KEY:
- bn_dup_nil(L, key.dsa->priv_key);
+ DSA_get0_key(key.dsa, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DH_P:
- bn_dup_nil(L, key.dh->p);
+ DH_get0_pqg(key.dh, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DH_G:
- bn_dup_nil(L, key.dh->g);
+ DH_get0_pqg(key.dh, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DH_PUB_KEY:
- bn_dup_nil(L, key.dh->pub_key);
+ DH_get0_key(key.dh, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DH_PRIV_KEY:
- bn_dup_nil(L, key.dh->priv_key);
+ DH_get0_key(key.dh, NULL, &i);
+ bn_dup_nil(L, i);
break;
#ifndef OPENSSL_NO_EC
@@ -3073,22 +3573,9 @@ static void pk_pushparam(lua_State *L, void *base_key, enum pk_param which) {
} /* pk_pushparam() */
-static _Bool pk_bn_set_nothrow(BIGNUM **dst, BIGNUM *src) {
- BIGNUM *tmp;
-
- if (!(tmp = BN_dup(src)))
- return 0;
-
- if (*dst)
- BN_clear_free(*dst);
- *dst = tmp;
-
- return 1;
-} /* pk_bn_set_nothrow() */
-
-#define pk_bn_set(L, dst, index) do { \
- BIGNUM *n = checkbig((L), (index)); \
- if (!pk_bn_set_nothrow((dst), n)) \
+#define pk_setparam_bn_dup(L, index, dst) do { \
+ BIGNUM *tmp = checkbig((L), (index)); \
+ if (!(*dst = BN_dup(tmp))) \
goto sslerr; \
} while (0)
@@ -3101,74 +3588,92 @@ static void pk_setparam(lua_State *L, void *base_key, enum pk_param which, int i
EC_KEY *ec;
#endif
} key = { base_key };
+ BIGNUM *i;
switch (which) {
case PK_RSA_N:
- pk_bn_set(L, &key.rsa->n, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_key(key.rsa, i, NULL, NULL);
break;
case PK_RSA_E:
- pk_bn_set(L, &key.rsa->e, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_key(key.rsa, NULL, i, NULL);
break;
case PK_RSA_D:
- pk_bn_set(L, &key.rsa->d, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_key(key.rsa, NULL, NULL, i);
break;
case PK_RSA_P:
- pk_bn_set(L, &key.rsa->p, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_factors(key.rsa, i, NULL);
break;
case PK_RSA_Q:
- pk_bn_set(L, &key.rsa->q, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_factors(key.rsa, NULL, i);
break;
case PK_RSA_DMP1:
- pk_bn_set(L, &key.rsa->dmp1, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_crt_params(key.rsa, i, NULL, NULL);
break;
case PK_RSA_DMQ1:
- pk_bn_set(L, &key.rsa->dmq1, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_crt_params(key.rsa, NULL, i, NULL);
break;
case PK_RSA_IQMP:
- pk_bn_set(L, &key.rsa->iqmp, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_crt_params(key.rsa, NULL, NULL, i);
break;
case PK_DSA_P:
- pk_bn_set(L, &key.dsa->p, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_pqg(key.dsa, i, NULL, NULL);
break;
case PK_DSA_Q:
- pk_bn_set(L, &key.dsa->q, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_pqg(key.dsa, NULL, i, NULL);
break;
case PK_DSA_G:
- pk_bn_set(L, &key.dsa->g, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_pqg(key.dsa, NULL, NULL, i);
break;
case PK_DSA_PUB_KEY:
- pk_bn_set(L, &key.dsa->pub_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_key(key.dsa, i, NULL);
break;
case PK_DSA_PRIV_KEY:
- pk_bn_set(L, &key.dsa->priv_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_key(key.dsa, NULL, i);
break;
case PK_DH_P:
- pk_bn_set(L, &key.dh->p, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_pqg(key.dh, i, NULL, NULL);
break;
case PK_DH_G:
- pk_bn_set(L, &key.dh->g, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_pqg(key.dh, NULL, NULL, i);
break;
case PK_DH_PUB_KEY:
- pk_bn_set(L, &key.dh->pub_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_key(key.dh, i, NULL);
break;
case PK_DH_PRIV_KEY:
- pk_bn_set(L, &key.dh->priv_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_key(key.dh, NULL, i);
break;
#ifndef OPENSSL_NO_EC
@@ -3399,6 +3904,7 @@ static const auxL_Reg pk_methods[] = {
{ "setPrivateKey", &pk_setPrivateKey },
{ "sign", &pk_sign },
{ "verify", &pk_verify },
+ { "getDefaultDigestName", &pk_getDefaultDigestName },
{ "toPEM", &pk_toPEM },
{ "getParameters", &pk_getParameters },
{ "setParameters", &pk_setParameters },
@@ -3474,21 +3980,6 @@ static EC_GROUP *ecg_dup_nil(lua_State *L, const EC_GROUP *src) {
return (src)? ecg_dup(L, src) : (lua_pushnil(L), (EC_GROUP *)0);
} /* ecg_dup_nil() */
-static EC_GROUP *ecg_new_by_nid(int nid) {
- EC_GROUP *group;
-
- if (!(group = EC_GROUP_new_by_curve_name(nid)))
- return NULL;
-
- /* flag as named for benefit of __tostring */
- EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-
- /* compressed points may be patented */
- EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
-
- return group;
-} /* ecg_new_by_nid() */
-
static EC_GROUP *ecg_push_by_nid(lua_State *L, int nid) {
EC_GROUP **group = prepsimple(L, EC_GROUP_CLASS);
@@ -3743,7 +4234,7 @@ static int xn_all(lua_State *L) {
lua_setfield(L, -2, "id");
len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
- lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len);
+ lua_pushlstring(L, (char *)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), len);
lua_setfield(L, -2, "blob");
@@ -3777,7 +4268,7 @@ static int xn__next(lua_State *L) {
lua_pushlstring(L, txt, len);
len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
- lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len);
+ lua_pushlstring(L, (char *)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), len);
break;
}
@@ -3955,7 +4446,7 @@ text:
gen->type = type;
- if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()))
+ if (!(gen->d.ia5 = ASN1_STRING_type_new(V_ASN1_IA5STRING)))
goto error;
if (!ASN1_STRING_set(gen->d.ia5, (unsigned char *)txt, len))
@@ -3976,7 +4467,7 @@ error:
#define GN_PUSHSTRING(L, o) \
- lua_pushlstring((L), (char *)M_ASN1_STRING_data((o)), M_ASN1_STRING_length((o)))
+ lua_pushlstring((L), (char *)ASN1_STRING_get0_data((o)), ASN1_STRING_length((o)))
static int gn__next(lua_State *L) {
GENERAL_NAMES *gens = checksimple(L, lua_upvalueindex(1), X509_GENS_CLASS);
@@ -4013,8 +4504,8 @@ static int gn__next(lua_State *L) {
break;
case GEN_IPADD:
- txt = (char *)M_ASN1_STRING_data(name->d.iPAddress);
- len = M_ASN1_STRING_length(name->d.iPAddress);
+ txt = (char *)ASN1_STRING_get0_data(name->d.iPAddress);
+ len = ASN1_STRING_length(name->d.iPAddress);
switch (len) {
case 16:
@@ -4259,7 +4750,7 @@ static int xe_getLongName(lua_State *L) {
static int xe_getData(lua_State *L) {
ASN1_STRING *data = X509_EXTENSION_get0_data(checksimple(L, 1, X509_EXT_CLASS));
- lua_pushlstring(L, (char *)ASN1_STRING_data(data), ASN1_STRING_length(data));
+ lua_pushlstring(L, (char *)ASN1_STRING_get0_data(data), ASN1_STRING_length(data));
return 1;
} /* xe_getData() */
@@ -4332,6 +4823,7 @@ static const auxL_IntegerReg xe_textopts[] = {
{ "ERROR_UNKNOWN", X509V3_EXT_ERROR_UNKNOWN },
{ "PARSE_UNKNOWN", X509V3_EXT_PARSE_UNKNOWN },
{ "DUMP_UNKNOWN", X509V3_EXT_DUMP_UNKNOWN },
+ { NULL, 0 },
};
int luaopen__openssl_x509_extension(lua_State *L) {
@@ -4588,7 +5080,7 @@ static double timeutc(ASN1_TIME *time) {
if (!ASN1_TIME_check(time))
return 0;
- cp = strncpy(buf, (const char *)ASN1_STRING_data((ASN1_STRING *)time), sizeof buf - 1);
+ cp = strncpy(buf, (const char *)ASN1_STRING_get0_data((ASN1_STRING *)time), sizeof buf - 1);
if (ASN1_STRING_type(time) == V_ASN1_GENERALIZEDTIME) {
if (!scan(&year, &cp, 4, 1))
@@ -4992,7 +5484,7 @@ static int xc_setBasicConstraint(lua_State *L) {
if (pathLen >= 0) {
ASN1_INTEGER_free(bs->pathlen);
- if (!(bs->pathlen = M_ASN1_INTEGER_new()))
+ if (!(bs->pathlen = ASN1_STRING_type_new(V_ASN1_INTEGER)))
goto error;
if (!ASN1_INTEGER_set(bs->pathlen, pathLen))
@@ -5179,20 +5671,21 @@ static int xc_getPublicKeyDigest(lua_State *L) {
static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) {
const char *id;
const EVP_MD *md;
+ int nid;
- if ((id = luaL_optstring(L, index, NULL)))
- return ((md = EVP_get_digestbyname(id)))? md : EVP_md_null();
-
- switch (EVP_PKEY_type(key->type)) {
- case EVP_PKEY_RSA:
- return EVP_sha1();
- case EVP_PKEY_DSA:
- return EVP_dss1();
- case EVP_PKEY_EC:
- return EVP_ecdsa();
- default:
- return EVP_md_null();
+ if ((id = luaL_optstring(L, index, NULL))) {
+ if (!(md = EVP_get_digestbyname(id)))
+ goto unknown;
+ } else {
+ if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
+ goto unknown;
+ if (!(md = EVP_get_digestbynid(nid)))
+ goto unknown;
}
+
+ return md;
+unknown:
+ return EVP_sha1();
} /* xc_signature() */
static int xc_sign(lua_State *L) {
@@ -5491,6 +5984,103 @@ static int xr_setPublicKey(lua_State *L) {
} /* xr_setPublicKey() */
+static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) {
+ STACK_OF(X509_EXTENSION) *sk = NULL;
+ int has_attrs=0;
+
+ /*
+ * Replace existing if it's there. Extensions are stored in a CSR in
+ * an interesting way:
+ *
+ * They are stored as a list under either (most likely) the
+ * "official" NID_ext_req or under NID_ms_ext_req which means
+ * everything is stored under a list in a single "attribute" so we
+ * can't use X509_REQ_add1_attr or similar.
+ *
+ * Instead we have to get the extensions, find and replace the SAN
+ * if it's in there, then *replace* the extensions in the list of
+ * attributes. (If we just try to add it the old ones are found
+ * first and don't take priority.)
+ */
+ has_attrs = X509_REQ_get_attr_count(csr);
+
+ sk = X509_REQ_get_extensions(csr);
+ if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE))
+ goto error;
+ if (X509_REQ_add_extensions(csr, sk) == 0)
+ goto error;
+ sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
+ sk = NULL;
+
+ /*
+ * Delete the old extensions attribute, so that the one we just
+ * added takes priority.
+ */
+ if (has_attrs) {
+ X509_ATTRIBUTE *attr = NULL;
+ int idx, *pnid;
+
+ for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) {
+ idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1);
+ if (idx == -1)
+ continue;
+ if (!(attr = X509_REQ_delete_attr(csr, idx)))
+ goto error;
+ X509_ATTRIBUTE_free(attr);
+ break;
+ }
+ if (!attr)
+ goto error;
+ }
+
+ /*
+ * We have to mark the encoded form as invalid, otherwise when we
+ * write it out again it will use the loaded version.
+ */
+#if HAVE_I2D_RE_X509_REQ_TBS
+ (void)i2d_re_X509_REQ_tbs(csr, NULL); /* sets csr->req_info->enc.modified */
+#else
+ csr->req_info->enc.modified = 1;
+#endif
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+error:
+ if (sk)
+ sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
+
+ return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid");
+} /* xr_setExtensionByNid() */
+
+
+static int xr_setSubjectAlt(lua_State *L) {
+ X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
+ GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
+
+ return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens);
+} /* xr_setSubjectAlt */
+
+
+static int xr_getSubjectAlt(lua_State *L) {
+ X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
+ STACK_OF(X509_EXTENSION) *exts;
+ GENERAL_NAMES *gens;
+
+ exts = X509_REQ_get_extensions(csr);
+ gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ if (!gens) goto error;
+
+ gn_dup(L, gens);
+
+ return 1;
+error:
+ return 0;
+} /* xr_getSubjectAlt() */
+
+
+
static int xr_sign(lua_State *L) {
X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
@@ -5548,6 +6138,8 @@ static const auxL_Reg xr_methods[] = {
{ "setSubject", &xr_setSubject },
{ "getPublicKey", &xr_getPublicKey },
{ "setPublicKey", &xr_setPublicKey },
+ { "getSubjectAlt", &xr_getSubjectAlt },
+ { "setSubjectAlt", &xr_setSubjectAlt },
{ "sign", &xr_sign },
{ "tostring", &xr__tostring },
{ NULL, NULL },
@@ -6010,7 +6602,7 @@ static void xl_dup(lua_State *L, STACK_OF(X509) *src, _Bool copy) {
for (i = 0; i < n; i++) {
if (!(crt = sk_X509_value(*dst, i)))
continue;
- CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(crt);
}
}
@@ -6195,8 +6787,8 @@ static int xs_verify(lua_State *L) {
X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
X509 *crt = checksimple(L, 2, X509_CERT_CLASS);
STACK_OF(X509) *chain = NULL, **proof;
- X509_STORE_CTX ctx;
- int ok, why;
+ X509_STORE_CTX *ctx = NULL;
+ int nr = 0, ok, why;
/* pre-allocate space for a successful return */
lua_settop(L, 3);
@@ -6207,53 +6799,56 @@ static int xs_verify(lua_State *L) {
int i, n;
if (!(chain = sk_X509_dup(checksimple(L, 3, X509_CHAIN_CLASS))))
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ goto eossl;
n = sk_X509_num(chain);
for (i = 0; i < n; i++) {
if (!(elm = sk_X509_value(chain, i)))
continue;
- CRYPTO_add(&elm->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(elm);
}
}
- if (!X509_STORE_CTX_init(&ctx, store, crt, chain)) {
+ if (!(ctx = X509_STORE_CTX_new()) || !X509_STORE_CTX_init(ctx, store, crt, chain)) {
sk_X509_pop_free(chain, X509_free);
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ goto eossl;
}
ERR_clear_error();
- ok = X509_verify_cert(&ctx);
+ ok = X509_verify_cert(ctx);
switch (ok) {
case 1: /* verified */
- *proof = X509_STORE_CTX_get1_chain(&ctx);
-
- X509_STORE_CTX_cleanup(&ctx);
-
- if (!*proof)
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ if (!(*proof = X509_STORE_CTX_get1_chain(ctx)))
+ goto eossl;
lua_pushboolean(L, 1);
lua_pushvalue(L, -2);
+ nr = 2;
- return 2;
+ break;
case 0: /* not verified */
- why = X509_STORE_CTX_get_error(&ctx);
-
- X509_STORE_CTX_cleanup(&ctx);
+ why = X509_STORE_CTX_get_error(ctx);
lua_pushboolean(L, 0);
lua_pushstring(L, X509_verify_cert_error_string(why));
+ nr = 2;
- return 2;
+ break;
default:
- X509_STORE_CTX_cleanup(&ctx);
-
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ goto eossl;
}
+
+ X509_STORE_CTX_free(ctx);
+
+ return nr;
+eossl:
+ if (ctx)
+ X509_STORE_CTX_free(ctx);
+
+ return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
} /* xs_verify() */
@@ -6529,7 +7124,7 @@ static int sx_new(lua_State *L) {
method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
break;
-#ifndef OPENSSL_NO_SSL2
+#if HAVE_SSLV2_CLIENT_METHOD && HAVE_SSLV2_SERVER_METHOD
case 2: /* SSLv2 */
method = (srv)? &SSLv2_server_method : &SSLv2_client_method;
break;
@@ -7001,7 +7596,7 @@ int luaopen__openssl_ssl_context(lua_State *L) {
static SSL *ssl_push(lua_State *L, SSL *ssl) {
SSL **ud = prepsimple(L, SSL_CLASS);
- CRYPTO_add(&(ssl)->references, 1, CRYPTO_LOCK_SSL);
+ SSL_up_ref(ssl);
*ud = ssl;
return *ud;
@@ -7152,7 +7747,7 @@ static int ssl_getVersion(lua_State *L) {
static int ssl_getClientVersion(lua_State *L) {
SSL *ssl = checksimple(L, 1, SSL_CLASS);
int format = luaL_checkoption(L, 2, "d", (const char *[]){ "d", ".", "f", NULL });
- int version = ssl->client_version;
+ int version = SSL_client_version(ssl);
int major, minor;
switch (format) {
@@ -7306,13 +7901,10 @@ static const EVP_MD *md_optdigest(lua_State *L, int index) {
static int md_new(lua_State *L) {
const EVP_MD *type = md_optdigest(L, 1);
- EVP_MD_CTX *ctx;
-
- ctx = prepudata(L, sizeof *ctx, DIGEST_CLASS, NULL);
-
- EVP_MD_CTX_init(ctx);
+ EVP_MD_CTX **ctx;
- if (!EVP_DigestInit_ex(ctx, type, NULL))
+ ctx = prepsimple(L, DIGEST_CLASS, NULL);
+ if (!(*ctx = EVP_MD_CTX_new()) || !EVP_DigestInit_ex(*ctx, type, NULL))
return auxL_error(L, auxL_EOPENSSL, "digest.new");
return 1;
@@ -7340,7 +7932,7 @@ static void md_update_(lua_State *L, EVP_MD_CTX *ctx, int from, int to) {
static int md_update(lua_State *L) {
- EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
+ EVP_MD_CTX *ctx = checksimple(L, 1, DIGEST_CLASS);
md_update_(L, ctx, 2, lua_gettop(L));
@@ -7351,7 +7943,7 @@ static int md_update(lua_State *L) {
static int md_final(lua_State *L) {
- EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
+ EVP_MD_CTX *ctx = checksimple(L, 1, DIGEST_CLASS);
unsigned char md[EVP_MAX_MD_SIZE];
unsigned len;
@@ -7367,9 +7959,10 @@ static int md_final(lua_State *L) {
static int md__gc(lua_State *L) {
- EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
+ EVP_MD_CTX **ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
- EVP_MD_CTX_cleanup(ctx);
+ EVP_MD_CTX_free(*ctx);
+ *ctx = NULL;
return 0;
} /* md__gc() */
@@ -7410,16 +8003,25 @@ static int hmac_new(lua_State *L) {
const void *key;
size_t len;
const EVP_MD *type;
- HMAC_CTX *ctx;
+ HMAC_CTX **ctx;
key = luaL_checklstring(L, 1, &len);
type = md_optdigest(L, 2);
- ctx = prepudata(L, sizeof *ctx, HMAC_CLASS, NULL);
+ ctx = prepsimple(L, HMAC_CLASS, NULL);
+ if (!(*ctx = HMAC_CTX_new()))
+ goto eossl;
- HMAC_Init_ex(ctx, key, len, type, NULL);
+#if HMAC_INIT_EX_INT
+ if (!HMAC_Init_ex(*ctx, key, len, type, NULL))
+ goto eossl;
+#else
+ HMAC_Init_ex(*ctx, key, len, type, NULL);
+#endif
return 1;
+eossl:
+ return auxL_error(L, auxL_EOPENSSL, "hmac.new");
} /* hmac_new() */
@@ -7443,7 +8045,7 @@ static void hmac_update_(lua_State *L, HMAC_CTX *ctx, int from, int to) {
static int hmac_update(lua_State *L) {
- HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS);
+ HMAC_CTX *ctx = checksimple(L, 1, HMAC_CLASS);
hmac_update_(L, ctx, 2, lua_gettop(L));
@@ -7454,7 +8056,7 @@ static int hmac_update(lua_State *L) {
static int hmac_final(lua_State *L) {
- HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS);
+ HMAC_CTX *ctx = checksimple(L, 1, HMAC_CLASS);
unsigned char hmac[EVP_MAX_MD_SIZE];
unsigned len;
@@ -7469,9 +8071,10 @@ static int hmac_final(lua_State *L) {
static int hmac__gc(lua_State *L) {
- HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS);
+ HMAC_CTX **ctx = luaL_checkudata(L, 1, HMAC_CLASS);
- HMAC_CTX_cleanup(ctx);
+ HMAC_CTX_free(*ctx);
+ *ctx = NULL;
return 0;
} /* hmac__gc() */
@@ -7521,23 +8124,26 @@ static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) {
static int cipher_new(lua_State *L) {
const EVP_CIPHER *type;
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX **ctx;
unsigned char key[EVP_MAX_KEY_LENGTH] = { 0 };
type = cipher_checktype(L, 1);
- ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL);
- EVP_CIPHER_CTX_init(ctx);
+ ctx = prepsimple(L, CIPHER_CLASS, NULL);
+ if (!(*ctx = EVP_CIPHER_CTX_new()))
+ goto eossl;
/*
* NOTE: For some ciphers like AES calling :update or :final without
* setting a key causes a SEGV. Set a dummy key here. Same solution
* as used by Ruby OSSL.
*/
- if (!EVP_CipherInit_ex(ctx, type, NULL, key, NULL, -1))
- return auxL_error(L, auxL_EOPENSSL, "cipher.new");
+ if (!EVP_CipherInit_ex(*ctx, type, NULL, key, NULL, -1))
+ goto eossl;
return 1;
+eossl:
+ return auxL_error(L, auxL_EOPENSSL, "cipher.new");
} /* cipher_new() */
@@ -7547,7 +8153,7 @@ static int cipher_interpose(lua_State *L) {
static int cipher_init(lua_State *L, _Bool encrypt) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
const void *key, *iv;
size_t n, m;
@@ -7619,7 +8225,7 @@ static _Bool cipher_update_(lua_State *L, EVP_CIPHER_CTX *ctx, luaL_Buffer *B, i
static int cipher_update(lua_State *L) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
luaL_buffinit(L, &B);
@@ -7639,7 +8245,7 @@ sslerr:
static int cipher_final(lua_State *L) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
size_t block;
int out;
@@ -7670,9 +8276,10 @@ sslerr:
static int cipher__gc(lua_State *L) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX **ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
- EVP_CIPHER_CTX_cleanup(ctx);
+ EVP_CIPHER_CTX_free(*ctx);
+ *ctx = NULL;
return 0;
} /* cipher__gc() */
@@ -7719,49 +8326,61 @@ static struct randL_state *randL_getstate(lua_State *L) {
return lua_touserdata(L, lua_upvalueindex(1));
} /* randL_getstate() */
-#ifndef HAVE_SYS_SYSCTL_H
-#define HAVE_SYS_SYSCTL_H (!defined __sun && !defined _AIX)
+#if HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h> /* SYS_getrandom syscall(2) */
#endif
#if HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h> /* CTL_KERN KERN_RANDOM RANDOM_UUID KERN_URND KERN_ARND sysctl(2) */
-#endif
-
-#ifndef HAVE_RANDOM_UUID
-#define HAVE_RANDOM_UUID (defined __linux) /* RANDOM_UUID is an enum, not macro */
-#endif
-
-#ifndef HAVE_KERN_URND
-#define HAVE_KERN_URND (defined KERN_URND)
-#endif
-
-#ifndef HAVE_KERN_ARND
-#define HAVE_KERN_ARND (defined KERN_ARND)
+#include <sys/sysctl.h> /* CTL_KERN KERN_RANDOM RANDOM_UUID sysctl(2) */
#endif
static int randL_stir(struct randL_state *st, unsigned rqstd) {
unsigned count = 0;
int error;
unsigned char data[256];
-#if HAVE_RANDOM_UUID || HAVE_KERN_URND || HAVE_KERN_ARND
-#if HAVE_RANDOM_UUID
- int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
-#elif HAVE_KERN_URND
- int mib[] = { CTL_KERN, KERN_URND };
-#else
- int mib[] = { CTL_KERN, KERN_ARND };
+
+#if HAVE_ARC4RANDOM_BUF
+ while (count < rqstd) {
+ size_t n = MIN(rqstd - count, sizeof data);
+
+ arc4random_buf(data, n);
+
+ RAND_seed(data, n);
+
+ count += n;
+ }
+#endif
+
+#if HAVE_SYSCALL && HAVE_DECL_SYS_GETRANDOM
+ while (count < rqstd) {
+ size_t lim = MIN(rqstd - count, sizeof data);
+ int n;
+
+ n = syscall(SYS_getrandom, data, lim, 0);
+
+ if (n == -1) {
+ break;
+ }
+
+ RAND_seed(data, n);
+
+ count += n;
+ }
#endif
+#if HAVE_SYS_SYSCTL_H && HAVE_DECL_RANDOM_UUID
while (count < rqstd) {
+ int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
size_t n = MIN(rqstd - count, sizeof data);
if (0 != sysctl(mib, countof(mib), data, &n, (void *)0, 0))
break;
- RAND_add(data, n, n);
+ RAND_seed(data, n);
count += n;
}
+
#endif
if (count < rqstd) {
@@ -7792,7 +8411,7 @@ static int randL_stir(struct randL_state *st, unsigned rqstd) {
goto error;
default:
- RAND_add(data, n, n);
+ RAND_seed(data, n);
count += n;
}
@@ -7830,7 +8449,12 @@ error:;
#elif defined __sun
/*
* NOTE: Linux requires -lrt for clock_gettime, and in any event
- * already has RANDOM_UUID. The BSDs have KERN_URND and KERN_ARND.
+ * should have RANDOM_UUID or getrandom. (Though, some middle-aged
+ * kernels might have neither). The BSDs have arc4random which
+ * should be using KERN_URND, KERN_ARND, and more recently
+ * getentropy. (Though, again, some older BSD kernels used an
+ * arc4random implementation that opened /dev/urandom.)
+ *
* Just do this for Solaris to keep things simple. We've already
* crossed the line of what can be reasonably accomplished on
* unreasonable platforms.
diff --git a/src/openssl.x509.altname.lua b/src/openssl.x509.altname.lua
index 66f16e7..e8222a0 100644
--- a/src/openssl.x509.altname.lua
+++ b/src/openssl.x509.altname.lua
@@ -1,9 +1,10 @@
local altname = require"_openssl.x509.altname"
+local auxlib = require"openssl.auxlib"
altname.interpose("__tostring", function (self)
local t = { }
- for k, v in pairs(self) do
+ for k, v in auxlib.pairs(self) do
t[#t + 1] = k .. ":" .. v
end
diff --git a/src/openssl.x509.name.lua b/src/openssl.x509.name.lua
index a531502..f33339a 100644
--- a/src/openssl.x509.name.lua
+++ b/src/openssl.x509.name.lua
@@ -1,9 +1,10 @@
local name = require"_openssl.x509.name"
+local auxlib = require"openssl.auxlib"
name.interpose("__tostring", function (self)
local t = { }
- for k, v in pairs(self) do
+ for k, v in auxlib.pairs(self) do
t[#t + 1] = k .. "=" .. v
end