diff --git a/Makefile b/Makefile index 128b945..8f2ff21 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,8 @@ # non-FIPS Mode of operation. # make all-combined Compile MatrixSSL FIPS Edition allowing run-time # selection of FIPS or non-FIPS mode. +# make all-openssl-compat A configuration specially tailored for use +# with the OpenSSL compatibility layer. # make all-combined-default-nonfips The same than make all combined, but # non-FIPS mode is the default. # @@ -164,6 +166,10 @@ all-combined-fulltest: make combined-fulltest-config make all +all-openssl-compat: + make openssl-compat-config + make all + ifneq (,$(findstring clean,$(MAKECMDGOALS))) SUBARGS:=clean endif @@ -247,3 +253,6 @@ clean: clobber: clean clean-config +# Always use common.mk for possible additional rules and processing. +COMMON_MK_NO_TARGETS:=1 +include common.mk diff --git a/apps/ssl/client.c b/apps/ssl/client.c index b64061c..886d805 100644 --- a/apps/ssl/client.c +++ b/apps/ssl/client.c @@ -62,9 +62,9 @@ If supporting client authentication, pick ONE identity to auto select a certificate and private key that support desired algorithms. */ -/* #define ID_RSA / * RSA Certificate and Key * / */ -/* #define ID_ECDH_ECDSA / * EC Certificate and Key * / */ -/* #define ID_ECDH_RSA / * EC Key with RSA signed certificate * / */ +/* #define ID_RSA */ /* RSA Certificate and Key */ +/* #define ID_ECDH_ECDSA */ /* EC Certificate and Key */ +/* #define ID_ECDH_RSA */ /* EC Key with RSA signed certificate */ # if !defined(ID_RSA) && !defined(ID_ECDH_ECDSA) && !defined(ID_ECDH_RSA) /* Choose a default identity based on which algorithms are supported. */ @@ -82,12 +82,28 @@ # endif /* !ID_RSA && !ID_ECDH_ECDSA && !ID_ECDH_RSA */ # define USE_HEADER_KEYS -# define ALLOW_ANON_CONNECTIONS 1 +# define ALLOW_ANON_CONNECTIONS 0 # define CRL_MAX_LENGTH 1048576 /* Maximum length for CRL: 1 megabyte. */ /* If the algorithm type is supported, load a CA for it */ # ifdef USE_ECC_CIPHER_SUITE +/* + If ALLOW_CA_BUNDLE_PARTIAL_PARSE is defined, we can simply try to load + all EC CA certs, even if we are not able to parse all of them. +*/ +# ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE +# ifdef USE_HEADER_KEYS +# include "testkeys/EC/ALL_EC_CAS.h" +# else +static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS.pem"; +# endif /* USE_HEADER_KEYS */ +# else /* !(ALLOW_CA_BUNDLE_PARTIAL_PARSE) */ +/* + If ALLOW_CA_BUNDLE_PARTIAL_PARSE is not defined, we need the following, + ugly code to load only those CA bundles, where each cert is supported + by the present configuration. +*/ # if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1) # ifdef USE_HEADER_KEYS # include "testkeys/EC/ALL_EC_CAS.h" @@ -152,6 +168,8 @@ static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521 # endif /* USE_HEADER_KEYS */ # endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */ +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + # ifndef USE_HEADER_KEYS /* Pointer to filename. We shall increment this when we need to @@ -237,6 +255,8 @@ static char *pEcdhRsaPrivkeyFile = ecdhRsaPrivkeyFile; # ifdef REHANDSHAKE_TEST static int g_rehandshakeFlag = 0; # endif + +static char *g_ca_file; # endif /* USE_HEADER_KEYS */ /* @@ -421,6 +441,13 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid, if (g_max_verify_depth != 0) options.validateCertsOpts.max_verify_depth = g_max_verify_depth; + /* + Do not allow the server to pick different version than what + we select here. Break the connection attempt with a protocol_version + alert if ServerHello.server_version < ClientHello.client_version. + */ + options.clientRejectVersionDowngrade = 1; + matrixSslNewHelloExtension(&extension, NULL); matrixSslCreateSNIext(NULL, (unsigned char *) g_ip, (uint32) strlen(g_ip), &ext, &extLen); @@ -1017,7 +1044,7 @@ static int32 process_cmd_options(int32 argc, char **argv) g_keepalive = 0; opterr = 0; - while ((optionChar = getopt(argc, argv, "ab:c:dhk:Km:n:p:r:s:u:V:e:")) != -1) + while ((optionChar = getopt(argc, argv, "ab:C:c:de:hk:Km:n:p:r:s:u:V:")) != -1) { switch (optionChar) { @@ -1039,6 +1066,15 @@ static int32 process_cmd_options(int32 argc, char **argv) snprintf(g_path, sizeof(g_path), "/bytes?%u", g_bytes_requested); break; + case 'C': +#ifdef USE_HEADER_KEYS + printf("USE_HEADER_KEYS not compatible with CA file option\n"); +#else + g_ca_file = optarg; + printf("Using CA file: %s\n", g_ca_file); +#endif + break; + case 'c': /* Convert the cipherListString into an array of cipher numbers. */ cipherListString = optarg; @@ -1135,7 +1171,6 @@ int32 main(int32 argc, char **argv) sslSessionId_t *sid = NULL; struct g_sslstats stats; unsigned char *CAstream; - # if defined(USE_HEADER_KEYS) && !defined(ID_RSA) const unsigned char *key_buf; int32 key_buf_len; @@ -1143,6 +1178,7 @@ int32 main(int32 argc, char **argv) # ifndef USE_HEADER_KEYS unsigned char *tmp_buf; int32 tmp_buf_len; + char *pCA; # endif /* USE_HEADER_KEYS */ # ifdef WIN32 WSADATA wsaData; @@ -1373,9 +1409,13 @@ int32 main(int32 argc, char **argv) { pRsaPrivkeyFile = NULL; } + if (g_ca_file != NULL) + pCA = g_ca_file; + else + pCA = (char*)CAstream; - if ((rc = matrixSslLoadRsaKeys(keys, pRsaCertFile, pRsaPrivkeyFile, NULL, - (char *) CAstream)) < 0) + if ((rc = matrixSslLoadRsaKeys(keys, pRsaCertFile, pRsaPrivkeyFile, + NULL, pCA) < 0)) { _psTrace("No certificate material loaded. Exiting\n"); if (CAstream) @@ -1400,8 +1440,13 @@ int32 main(int32 argc, char **argv) pEcdhRsaPrivkeyFile = NULL; } + if (g_ca_file != NULL) + pCA = g_ca_file; + else + pCA = (char*)CAstream; + if ((rc = matrixSslLoadEcKeys(keys, pEcdhRsaCertFile, pEcdhRsaPrivkeyFile, - NULL, (char *) CAstream)) < 0) + NULL, pCA)) < 0) { _psTrace("No certificate material loaded. Exiting\n"); if (CAstream) diff --git a/apps/ssl/runClient.sh b/apps/ssl/runClient.sh index c4793eb..e2a9f9e 100755 --- a/apps/ssl/runClient.sh +++ b/apps/ssl/runClient.sh @@ -1,23 +1,31 @@ #!/bin/sh -# Some cipher suites +if [ "X$CIPHER_SUITE" = "X" ] +then +# Set cipher suite CIPHER_SUITE="47" #AES128-SHA #CIPHER_SUITE="5" #RC4128-SHA #CIPHER_SUITE="4" #RC4128-MD5 #CIPHER_SUITE="60" #AES128-SHA256 -#CIPHER_SUITE="10" #DES-CBC3-SHA -#CIPHER_SUITE="141" #PSK_AES256-SHA +#CIPHER_SUITE="10" #DES-CBC3-SHA +#CIPHER_SUITE="141" #PSK_AES256-SHA #CIPHER_SUITE="49156" #ECDH_ECDSA-AES128-SHA #CIPHER_SUITE="49162" #ECDHE_ECDSA-AES256-SHA #CIPHER_SUITE="156" #RSA AES128-GCM-SHA256 #CIPHER_SUITE="157" #RSA AES256-GCM-SHA384 #CIPHER_SUITE="57" #DHE_RSA AES256-SHA #CIPHER_SUITE="49195" #ECDHE_ECDSA-AES128-GCM-SHA256 -#CIPHER_SUITE="49196" #ECDHE_ECDSA-AES256-GCM-SHA384 - +#CIPHER_SUITE="49196" #ECDHE_ECDSA-AES256-GCM-SHA384 +#CIPHER_SUITE="52243" #TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 +#CIPHER_SUITE="52244" #TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 +fi + +if [ "X$PROTOCOL_VERSION" = "X" ] +then #PROTOCOL_VERSION="1" #TLS1.0 #PROTOCOL_VERSION="2" #TLS1.1 PROTOCOL_VERSION="3" #TLS1.2 +fi IPADDR="127.0.0.1" PORT="4433" diff --git a/common.mk b/common.mk index 095d9c5..8778b60 100644 --- a/common.mk +++ b/common.mk @@ -1,15 +1,17 @@ ## # Common Makefile definitions. # @version $Format:%h%d$ -# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved. +# Copyright (c) 2013-2017 INSIDE Secure Corporation. All Rights Reserved. # #------------------------------------------------------------------------------- +# Allow building inclusion paths relative to location of common.mk file. +COMMON_MK_PATH:=$(dir $(lastword $(MAKEFILE_LIST))) # Allow extra CFLAGS, CPPFLAGS and LDFLAGS to be used. -LDFLAGS += $(EXTRA_LDFLAGS) -CFLAGS += $(CFLAGS_STANDARD) $(CFLAGS_PLATFORM) $(CFLAGS_ADDITIONAL) $(CFLAGS_WARNINGS) $(CFLAGS_CPU) $(CFLAGS_ASM) $(CFLAGS_PROFILE) $(DEBUGGABLE) $(EXTRA_CFLAGS) -CPPFLAGS += $(CPPFLAGS_STANDARD) $(CPPFLAGS_PLATFORM) $(CPPFLAGS_ADDITIONAL) $(CPPFLAGS_WARNINGS) $(CPPFLAGS_CPPPU) $(CPPFLAGS_ASM) $(CPPFLAGS_PROFILE) $(DEBUGGABLE) $(EXTRA_CPPFLAGS) +LDFLAGS += $(EXTRA_LDFLAGS) $(LDFLAGS_MAKEFILES) +CFLAGS += $(CFLAGS_STANDARD) $(CFLAGS_PLATFORM) $(CFLAGS_ADDITIONAL) $(CFLAGS_WARNINGS) $(CFLAGS_CPU) $(CFLAGS_ASM) $(CFLAGS_PROFILE) $(CFLAGS_MAKEFILES) $(DEBUGGABLE) $(EXTRA_CFLAGS) +CPPFLAGS += $(CPPFLAGS_STANDARD) $(CPPFLAGS_PLATFORM) $(CPPFLAGS_ADDITIONAL) $(CPPFLAGS_WARNINGS) $(CPPFLAGS_CPPPU) $(CPPFLAGS_ASM) $(CPPFLAGS_PROFILE) $(CPPFLAGS_MAKEFILES) $(DEBUGGABLE) $(EXTRA_CPPFLAGS) #------------------------------------------------------------------------------- ## Makefile variables that must be defined in this file @@ -131,6 +133,7 @@ ifndef MATRIX_DEBUG endif CFLAGS+=$(OPT) $(C_STD) +ifeq "$(COMMON_MK_NO_TARGETS)" "" default: $(BUILD) debug: @@ -138,6 +141,7 @@ debug: release: @$(MAKE) $(JOBS) compile +endif ifeq ($(SSH_PACKAGE),1) CFLAGS+=-DSSH_PACKAGE @@ -290,22 +294,8 @@ ifdef USE_OPENSSL_CRYPTO endif #endif -#ifdef USE_LIBSODIUM_CRYPTO -#USE_LIBSODIUM_CRYPTO:=1 -ifdef USE_LIBSODIUM_CRYPTO - LIBSODIUM_ROOT:=/opt/libsodium-1.0.8/src/libsodium - ifdef LIBSODIUM_ROOT - # Statically link against a given libsodium - CFLAGS+=-I$(LIBSODIUM_ROOT)/include - LDFLAGS+=$(LIBSODIUM_ROOT)/.libs/libsodium.a - endif - ifndef LIBSODIUM_ROOT - $(error Please define LIBSODIUM_ROOT) - endif - CFLAGS+=-DUSE_LIBSODIUM_CRYPTO - STROPTS+=", USE_LIBSODIUM_CRYPTO" -endif -#endif +# Include optional support for libsodium +-include $(COMMON_MK_PATH)/makefiles/libsodium_support.mk # Linux Target ifneq (,$(findstring -linux,$(CCARCH))) @@ -346,7 +336,30 @@ OBJS=$(SRC:.c=.o) $(SRC:.S:*.o) # Remove extra spaces in CFLAGS #CFLAGS=$(strip $(CFLAGS)) +ifneq (,$(filter defines,$(MAKECMDGOALS))) # Display the precompiler defines for the current build settings +# The rule is only available if explicitly requested on command line. + defines: :| $(CC) $(CFLAGS) -dM -E -x c - +endif +# Introduce here paths to additional build files (services) available. +use_prepkg_mk=$(MATRIXSSL_ROOT)/makefiles/prepkg.mk +use_testsupp_mk=$(MATRIXSSL_ROOT)/makefiles/testsupp.mk +use_rules_mk=$(MATRIXSSL_ROOT)/makefiles/rules.mk + +# Provide names of built packages for interpackage references +# Note: Some of these may not be built in some cases. +LIBCORE_S_A=$(MATRIXSSL_ROOT)/core/libcore_s$(A) +LIBCRYPT_S_A=$(MATRIXSSL_ROOT)/crypto/libcrypt_s$(A) +LIBCMS_S_A=$(MATRIXSSL_ROOT)/crypto/cms/libcms_s$(A) +LIBSSL_S_A=$(MATRIXSSL_ROOT)/matrixssl/libssl_s$(A) + +# Optional external libraries +LIBZ=-lz +LIBDL=-ldl +LIBTHREAD=-lpthread + +# When linking use default compiler front-end +CC_LD=$(CC) diff --git a/configs/default/cryptoConfig.h b/configs/default/cryptoConfig.h index e3e8a1c..7ec451c 100644 --- a/configs/default/cryptoConfig.h +++ b/configs/default/cryptoConfig.h @@ -120,9 +120,12 @@ # define USE_AES_CBC # define USE_AES_GCM -# ifdef USE_LIBSODIUM +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ /* #define USE_CHACHA20_POLY1305 */ -# endif /** @security 3DES is still relatively secure, however is deprecated for TLS */ # define USE_3DES diff --git a/configs/default/matrixsslConfig.h b/configs/default/matrixsslConfig.h index 3d1af9d..8ef6140 100644 --- a/configs/default/matrixsslConfig.h +++ b/configs/default/matrixsslConfig.h @@ -83,6 +83,8 @@ extern "C" { # define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ # define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ # define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral ECC DH keys, RSA certificates */ @@ -93,6 +95,8 @@ extern "C" { # define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ # define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ # define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ @@ -242,6 +246,18 @@ extern "C" { */ /* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + /******************************************************************************/ /** Enable the Application Layer Protocol Negotiation extension. diff --git a/configs/noecc/cryptoConfig.h b/configs/noecc/cryptoConfig.h index 6787340..130c3ff 100644 --- a/configs/noecc/cryptoConfig.h +++ b/configs/noecc/cryptoConfig.h @@ -120,9 +120,12 @@ # define USE_AES_CBC # define USE_AES_GCM -# ifdef USE_LIBSODIUM +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ /* #define USE_CHACHA20_POLY1305 */ -# endif /** @security 3DES is still relatively secure, however is deprecated for TLS */ # define USE_3DES diff --git a/configs/noecc/matrixsslConfig.h b/configs/noecc/matrixsslConfig.h index 4d80c58..bb9f2c7 100644 --- a/configs/noecc/matrixsslConfig.h +++ b/configs/noecc/matrixsslConfig.h @@ -83,6 +83,8 @@ extern "C" { /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral ECC DH keys, RSA certificates */ @@ -93,6 +95,8 @@ extern "C" { /* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ /* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ /* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ @@ -242,6 +246,18 @@ extern "C" { */ /* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + /******************************************************************************/ /** Enable the Application Layer Protocol Negotiation extension. diff --git a/configs/psk/cryptoConfig.h b/configs/psk/cryptoConfig.h index 5a3c7d0..ec332b3 100644 --- a/configs/psk/cryptoConfig.h +++ b/configs/psk/cryptoConfig.h @@ -120,9 +120,12 @@ # define USE_AES_CBC /* #define USE_AES_GCM */ -# ifdef USE_LIBSODIUM +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ /* #define USE_CHACHA20_POLY1305 */ -# endif /** @security 3DES is still relatively secure, however is deprecated for TLS */ /* #define USE_3DES */ diff --git a/configs/psk/matrixsslConfig.h b/configs/psk/matrixsslConfig.h index 682785a..8bc1755 100644 --- a/configs/psk/matrixsslConfig.h +++ b/configs/psk/matrixsslConfig.h @@ -83,6 +83,8 @@ extern "C" { /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral ECC DH keys, RSA certificates */ @@ -93,6 +95,8 @@ extern "C" { /* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ /* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ /* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ @@ -242,6 +246,18 @@ extern "C" { */ /* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + /******************************************************************************/ /** Enable the Application Layer Protocol Negotiation extension. diff --git a/configs/rsaonly/cryptoConfig.h b/configs/rsaonly/cryptoConfig.h index b506cd4..7943a94 100644 --- a/configs/rsaonly/cryptoConfig.h +++ b/configs/rsaonly/cryptoConfig.h @@ -120,9 +120,12 @@ # define USE_AES_CBC # define USE_AES_GCM -# ifdef USE_LIBSODIUM +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ /* #define USE_CHACHA20_POLY1305 */ -# endif /** @security 3DES is still relatively secure, however is deprecated for TLS */ # define USE_3DES diff --git a/configs/rsaonly/matrixsslConfig.h b/configs/rsaonly/matrixsslConfig.h index b724133..fd0ff94 100644 --- a/configs/rsaonly/matrixsslConfig.h +++ b/configs/rsaonly/matrixsslConfig.h @@ -83,6 +83,8 @@ extern "C" { /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ /* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral ECC DH keys, RSA certificates */ @@ -93,6 +95,8 @@ extern "C" { /* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ /* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ /* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ @@ -242,6 +246,18 @@ extern "C" { */ /* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + /******************************************************************************/ /** Enable the Application Layer Protocol Negotiation extension. diff --git a/configs/tls/cryptoConfig.h b/configs/tls/cryptoConfig.h index d5a856e..1e9e064 100644 --- a/configs/tls/cryptoConfig.h +++ b/configs/tls/cryptoConfig.h @@ -120,9 +120,12 @@ # define USE_AES_CBC # define USE_AES_GCM -# ifdef USE_LIBSODIUM +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ /* #define USE_CHACHA20_POLY1305 */ -# endif /** @security 3DES is still relatively secure, however is deprecated for TLS */ # define USE_3DES diff --git a/configs/tls/matrixsslConfig.h b/configs/tls/matrixsslConfig.h index 3d1af9d..8ef6140 100644 --- a/configs/tls/matrixsslConfig.h +++ b/configs/tls/matrixsslConfig.h @@ -83,6 +83,8 @@ extern "C" { # define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ # define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ # define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral ECC DH keys, RSA certificates */ @@ -93,6 +95,8 @@ extern "C" { # define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ # define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ # define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to old draft. + Do not enable except for compatibility with obsolete software. */ /* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ /** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ @@ -242,6 +246,18 @@ extern "C" { */ /* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + /******************************************************************************/ /** Enable the Application Layer Protocol Negotiation extension. diff --git a/core/POSIX/osdep.c b/core/POSIX/osdep.c index 1b47d6d..a09056a 100644 --- a/core/POSIX/osdep.c +++ b/core/POSIX/osdep.c @@ -469,34 +469,127 @@ void osdepTraceClose(void) { } +FILE *_psGetTraceFile(void) +{ + static FILE *tracefile = NULL; +#ifdef USE_MULTITHREADING + static pthread_mutex_t tracefile_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* USE_MULTITHREADING */ + + if (tracefile == NULL) + { + const char *str; + +#ifdef USE_MULTITHREADING + pthread_mutex_lock(&tracefile_mutex); +#endif /* USE_MULTITHREADING */ + + if (tracefile == NULL) + { + str = getenv("PSCORE_DEBUG_FILE"); + if (str != NULL) + { + tracefile = fopen(str, "w"); + if (!tracefile) + { + fprintf( + stderr, + "%s: Unable to open file %s, %s.\n", + __func__, + str, + "producing log to standard output"); + tracefile = stdout; + } + } + else + { + str = getenv("PSCORE_DEBUG_FILE_APPEND"); + } + + if (tracefile == NULL && str != NULL) + { + tracefile = fopen(str, "a"); + if (!tracefile) + { + fprintf( + stderr, + "%s: Unable to open file %s, %s.\n", + __func__, + str, + "producing log to standard output"); + tracefile = stdout; + } + } + + if (tracefile == NULL) + { + /* Default: output to standard output. */ + tracefile = stdout; + } + } + + if (tracefile) + { + setvbuf(tracefile, NULL, _IONBF, 0); + } + +#ifdef USE_MULTITHREADING + pthread_mutex_unlock(&tracefile_mutex); +#endif /* USE_MULTITHREADING */ + } + return tracefile; +} + void _psTrace(const char *msg) { - printf("%s", msg); + FILE *tracefile = _psGetTraceFile(); + + if (tracefile) + { + fprintf(tracefile, "%s", msg); + } } /* message should contain one %s, unless value is NULL */ void _psTraceStr(const char *message, const char *value) { + FILE *tracefile = _psGetTraceFile(); if (value) { - printf(message, value); + if (tracefile) + { + fprintf(tracefile, message, value); + } } else { - printf("%s", message); + if (tracefile) + { + fprintf(tracefile, "%s", message); + } } } /* message should contain one %d */ void _psTraceInt(const char *message, int32 value) { - printf(message, value); + FILE *tracefile = _psGetTraceFile(); + + if (tracefile) + { + fprintf(tracefile, message, value); + } } /* message should contain one %p */ void _psTracePtr(const char *message, const void *value) { - printf(message, value); + FILE *tracefile = _psGetTraceFile(); + + if (tracefile) + { + fprintf(tracefile, message, value); + } } /******************************************************************************/ diff --git a/core/psbuf.c b/core/psbuf.c index 88e85dc..36bb2f2 100644 --- a/core/psbuf.c +++ b/core/psbuf.c @@ -301,9 +301,11 @@ void assert_subbuf(psDynBuf_t *sub) assert(sub->buf.buf + sub->buf.size >= db->buf.start && sub->buf.buf + sub->buf.size <= db->buf.end); +#ifdef PSBUF_DEBUG_WITH_MEMSET /* For debugging: Mark head and tail visually. */ memset(sub->buf.buf, '(', sub->buf.start - sub->buf.buf); memset(sub->buf.end, ')', sub->buf.buf + sub->buf.size - sub->buf.end); +#endif /* PSBUF_DEBUG_WITH_MEMSET */ } static void *psDynBufGrow(psDynBuf_t *db, size_t head_sz, size_t tail_sz) @@ -339,9 +341,11 @@ static void *psDynBufGrow(psDynBuf_t *db, size_t head_sz, size_t tail_sz) headroom, filled, tailroom, headroom + head_sz, filled, tailroom + tail_sz, offset, offset_tail); assert_subbuf(db); +#ifdef PSBUF_DEBUG_WITH_MEMSET /* For debugging: */ memset(db->buf.buf, '{', headroom); memset(db->buf.end, '}', tailroom); +#endif /* PSBUF_DEBUG_WITH_MEMSET */ loc = psDynBufGrow(db->master, 0, head_sz + tail_sz); if (loc) @@ -371,9 +375,11 @@ static void *psDynBufGrow(psDynBuf_t *db, size_t head_sz, size_t tail_sz) db->buf.size, db->buf.start - db->buf.buf, db->buf.end - db->buf.start, db->buf.buf + db->buf.size - db->buf.end); +#ifdef PSBUF_DEBUG_WITH_MEMSET /* For debugging: */ memset(db->buf.buf, '<', head_sz + headroom); memset(db->buf.end, '>', tail_sz + tailroom); +#endif /* PSBUF_DEBUG_WITH_MEMSET */ } else { @@ -523,7 +529,9 @@ void *psDynBufSubInit(psDynBuf_t *db, psDynBuf_t *sub, size_t capacity) sub->pool = NULL; sub->master = db; sub->err = 0; +#ifdef PSBUF_DEBUG_WITH_MEMSET memset(sub->buf.buf, '#', capacity); +#endif /* PSBUF_DEBUG_WITH_MEMSET */ assert_subbuf(sub); } else @@ -553,7 +561,9 @@ void *psDynBufSubInitAt(psDynBuf_t *db, psDynBuf_t *sub, size_t at, sub->pool = NULL; sub->master = db; sub->err = 0; +#ifdef PSBUF_DEBUG_WITH_MEMSET memset(sub->buf.buf, '#', length); +#endif /* PSBUF_DEBUG_WITH_MEMSET */ assert_subbuf(sub); } else diff --git a/core/psbuf.h b/core/psbuf.h index e502073..f3ce92d 100644 --- a/core/psbuf.h +++ b/core/psbuf.h @@ -163,6 +163,17 @@ static __inline void *psDynBufAppendBuf(psDynBuf_t *db, const psBuf_t *b) return psDynBufAppendOctets(db, b->start, b->end - b->start); } +static __inline void *psDynBufAppendParseBuf(psDynBuf_t *db, + const psParseBuf_t *pb) +{ + if (!pb || pb->err) + { + db->err++; + return NULL; + } + return psDynBufAppendBuf(db, &(pb->buf)); +} + static __inline void *psDynBufIncorporateDynBuf(psDynBuf_t *db, psDynBuf_t *db2) { size_t len; @@ -202,6 +213,30 @@ void *psDynBufSubFinish(psDynBuf_t *sub); char *psDynBufAppendAsn1TagGen(psDynBuf_t *db, unsigned char tag, const unsigned char *bytes, size_t len); +static inline +char *psDynBufAppendAsn1IntegerSmall(psDynBuf_t *db, signed char byte) +{ + unsigned char bytes[1]; + + bytes[0] = (unsigned char) byte; + return psDynBufAppendAsn1TagGen(db, 0x02, bytes, 1); +} + +static inline +char *psDynBufAppendAsn1OctetString(psDynBuf_t *db, + const unsigned char *bytes, size_t len) +{ + return psDynBufAppendAsn1TagGen(db, 0x04, bytes, len); +} + +static inline +char *psDynBufAppendAsn1Oid(psDynBuf_t *db, + const unsigned char *oidbytes, size_t len) +{ + /* Note: oidbytes shall not include OID identifier (6) or length. */ + return psDynBufAppendAsn1TagGen(db, 0x06, oidbytes, len); +} + char *psDynBufBeginConstructedTag(psDynBuf_t *db, psDynBuf_t *sub); char *psDynBufEndConstructedTag(psDynBuf_t *sub, unsigned char tag); diff --git a/crypto/cryptoApi.h b/crypto/cryptoApi.h index e1ab7c2..607c719 100644 --- a/crypto/cryptoApi.h +++ b/crypto/cryptoApi.h @@ -81,6 +81,11 @@ extern "C" { # define PS_MESSAGE_UNSUPPORTED -42 /* Request/Response format/type is unsupported. */ # define PS_VERSION_UNSUPPORTED -43 /* Request/Response version is unsupported. */ +# define PS_SELFTEST_FAILED -44 /* Selftest, such as FIPS 140-2 + Powerup selftest has failed. + Software initialization has + failed. */ + /** Public return value codes for OCSP. These are additional possible return values from OCSP parsing. @@ -359,6 +364,28 @@ static __inline void psMd5Sha1Cpy(psMd5Sha1_t *d, const psMd5Sha1_t *s) } # endif /* USE_MD5SHA1 */ +# ifdef USE_SHA224 +/******************************************************************************/ +/* Pre-init should be called for uninitialized, e.g. function local + digest contexts, before calling the initialization function. */ +static __inline void psSha224PreInit(psSha256_t *sha224) +{ + /* Nothing to pre-initialize for native crypto. */ +} +PSPUBLIC void psSha224Init(psSha256_t *sha224); +PSPUBLIC void psSha224Update(psSha256_t *sha224, + const unsigned char *buf, uint32_t len); +PSPUBLIC void psSha224Final(psSha256_t * sha224, + unsigned char hash[SHA224_HASHLEN]); +static __inline void psSha224Sync(psSha256_t *md, int sync_all) +{ +} +static __inline void psSha224Cpy(psSha256_t *d, const psSha256_t *s) +{ + memcpy(d, s, sizeof(psSha256_t)); +} +# endif /* USE_SHA224 */ + # ifdef USE_SHA256 /******************************************************************************/ /* Pre-init should be called for uninitialized, e.g. function local @@ -558,9 +585,13 @@ PSPUBLIC void psClearPubKey(psPubKey_t *key); PSPUBLIC int32_t psNewPubKey(psPool_t *pool, uint8_t type, psPubKey_t **key); PSPUBLIC void psDeletePubKey(psPubKey_t **key); PSPUBLIC int32_t psParseUnknownPrivKey(psPool_t *pool, int pemOrDer, - char *keyfile, char *password, psPubKey_t *privkey); + const char *keyfile, const char *password, + psPubKey_t *privkey); +PSPUBLIC int32_t psParseUnknownPrivKeyMem(psPool_t *pool, + unsigned char *keyBuf, int32 keyBufLen, + const char *password, psPubKey_t *privkey); PSPUBLIC int32_t psParseUnknownPubKey(psPool_t *pool, int pemOrDer, - char *keyfile, const char *password, psPubKey_t *pubkey); + char *keyfile, const char *password, psPubKey_t *pubkey); # endif # ifdef USE_RSA diff --git a/crypto/cryptolib.h b/crypto/cryptolib.h index 7d0eac0..e47fb94 100644 --- a/crypto/cryptolib.h +++ b/crypto/cryptolib.h @@ -135,6 +135,9 @@ extern int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size, # define OID_SHA1_ALG_STR "1.3.14.3.2.26" # define OID_SHA1_ALG 88 # define OID_SHA1_ALG_HEX "\x06\x05\x2B\x0E\x03\x02\x1A" +# define OID_SHA224_ALG_STR "2.16.840.1.101.3.4.2.4" +# define OID_SHA224_ALG (417 + OID_COLLISION) +# define OID_SHA224_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04" # define OID_SHA256_ALG_STR "2.16.840.1.101.3.4.2.1" # define OID_SHA256_ALG 414 # define OID_SHA256_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01" @@ -170,6 +173,9 @@ extern int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size, # define OID_RSASSA_PSS_STR "1.2.840.113549.1.1.10" # define OID_RSASSA_PSS (654 + OID_COLLISION) # define OID_RSASSA_PSS_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A" +# define OID_SHA224_RSA_SIG_STR "1.2.840.113549.1.1.14" +# define OID_SHA224_RSA_SIG (658 + OID_COLLISION) +# define OID_SHA224_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0E" # define OID_SHA256_RSA_SIG_STR "1.2.840.113549.1.1.11" # define OID_SHA256_RSA_SIG (655 + OID_COLLISION) # define OID_SHA256_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B" @@ -338,6 +344,34 @@ extern int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size, # define OID_BASIC_OCSP_RESPONSE 117 # define OID_BASIC_OCSP_RESPONSE_HEX "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x01" +/* These definitions are for MatrixCMS (optional component). */ +# define OID_ECKA_EG_X963KDF_SHA256_STR "0.4.0.127.0.7.1.1.5.1.1.3" +# define OID_ECKA_EG_X963KDF_SHA256 150 +# define OID_ECKA_EG_X963KDF_SHA256_HEX "\x06\x0B\x04\x00\x7F\x00\x07\x01\x01\x05\x01\x01\x03" +# define OID_ECKA_EG_X963KDF_SHA384_STR "0.4.0.127.0.7.1.1.5.1.1.4" +# define OID_ECKA_EG_X963KDF_SHA384 151 +# define OID_ECKA_EG_X963KDF_SHA384_HEX "\x06\x0B\x04\x00\x7F\x00\x07\x01\x01\x05\x01\x01\x04" +# define OID_ECKA_EG_X963KDF_SHA512_STR "0.4.0.127.0.7.1.1.5.1.1.5" +# define OID_ECKA_EG_X963KDF_SHA512 152 +# define OID_ECKA_EG_X963KDF_SHA512_HEX "\x06\x0B\x04\x00\x7F\x00\x07\x01\x01\x05\x01\x01\x05" +# define OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME_STR "1.3.133.16.840.63.0.2" +# define OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME 464 +# define OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME_HEX "\x06\x09\x2B\x81\x05\x10\x86\x48\x3F\x00\x02" +# define OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME_STR "1.3.133.16.840.63.0.3" +# define OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME 465 +# define OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME_HEX "\x06\x09\x2B\x81\x05\x10\x86\x48\x3F\x00\x03" +# define OID_MQVSINGLEPASS_SHA1KDF_SCHEME_STR "1.3.133.16.840.63.0.16" +# define OID_MQVSINGLEPASS_SHA1KDF_SCHEME 478 +# define OID_MQVSINGLEPASS_SHA1KDF_SCHEME_HEX "\x06\x09\x2B\x81\x05\x10\x86\x48\x3F\x00\x10" +# define OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME_STR "1.3.132.1.11.1" +# define OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME 189 +# define OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME_HEX "\x06\x06\x2B\x81\x04\x01\x0B\x01" +# define OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME_STR "1.3.132.1.11.2" +# define OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME 190 +# define OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME_HEX "\x06\x06\x2B\x81\x04\x01\x0B\x02" +# define OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME_STR "1.3.132.1.11.3" +# define OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME 191 +# define OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME_HEX "\x06\x06\x2B\x81\x04\x01\x0B\x03" # define PBE12 1 # define PBES2 2 @@ -354,6 +388,7 @@ extern int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size, # define PKCS1_SHA256_ID 2 # define PKCS1_SHA384_ID 3 # define PKCS1_SHA512_ID 4 +# define PKCS1_SHA224_ID 5 # endif /******************************************************************************/ diff --git a/crypto/keyformat/asn1.c b/crypto/keyformat/asn1.c index af54118..ce19d9a 100644 --- a/crypto/keyformat/asn1.c +++ b/crypto/keyformat/asn1.c @@ -34,6 +34,44 @@ #include "../cryptoImpl.h" +/* Compute tag length when it is known that p points to valid ASN.1 DER + encoding, no larger than 16 megabytes. */ +uint32_t getAsnTagLenUnsafe(const unsigned char *p) +{ + uint32_t len; + + /* Return 0 for uninitialized data or NULL. */ + if (p == NULL || *p == 0) + { + return 0; + } + len = p[1]; + if (len >= 0x80) + { + unsigned char lenbytes[3] = { 0, 0, 0 }; /* Size up-to 16 Mbytes. */ + len -= 0x80; /* Compute number of bytes in encoding. */ + if (len == 0 || len >= 4) + { + /* Although the function is "Unsafe", check for too long + length encoding, because in future some parser may accept + input > 4 gigabytes. */ + return 0; /* Too large length. */ + } + /* Note: */ + memcpy(lenbytes + 3 - len, p + 2, len); + len = + len + 2 + + ((lenbytes[0] << 16) | + (lenbytes[1] << 8) | + (lenbytes[2] << 0)); + } + else + { + len += 2; /* Tag and length byte. */ + } + return len; +} + /******************************************************************************/ /* On success, p will be updated to point to first character of value and @@ -470,6 +508,7 @@ static void checkAsnOidDatabase(int32_t *oi, switch (*oi) { case OID_SHA1_ALG: oid_hex = OID_SHA1_ALG_HEX; break; + case OID_SHA224_ALG: oid_hex = OID_SHA224_ALG_HEX; break; case OID_SHA256_ALG: oid_hex = OID_SHA256_ALG_HEX; break; case OID_SHA384_ALG: oid_hex = OID_SHA384_ALG_HEX; break; case OID_SHA512_ALG: oid_hex = OID_SHA512_ALG_HEX; break; @@ -481,6 +520,7 @@ static void checkAsnOidDatabase(int32_t *oi, case OID_SHA1_RSA_SIG2: oid_hex = OID_SHA1_RSA_SIG2_HEX; break; case OID_ID_MGF1: oid_hex = OID_ID_MGF1_HEX; break; case OID_RSASSA_PSS: oid_hex = OID_RSASSA_PSS_HEX; break; + case OID_SHA224_RSA_SIG: oid_hex = OID_SHA224_RSA_SIG_HEX; break; case OID_SHA256_RSA_SIG: oid_hex = OID_SHA256_RSA_SIG_HEX; break; case OID_SHA384_RSA_SIG: oid_hex = OID_SHA384_RSA_SIG_HEX; break; case OID_SHA512_RSA_SIG: oid_hex = OID_SHA512_RSA_SIG_HEX; break; @@ -532,6 +572,15 @@ static void checkAsnOidDatabase(int32_t *oi, case OID_PKCS7_ENCRYPTED_DATA: oid_hex = OID_PKCS7_ENCRYPTED_DATA_HEX; break; case OID_OCSP: oid_hex = OID_OCSP_HEX; break; case OID_BASIC_OCSP_RESPONSE: oid_hex = OID_BASIC_OCSP_RESPONSE_HEX; break; + case OID_ECKA_EG_X963KDF_SHA256: oid_hex = OID_ECKA_EG_X963KDF_SHA256_HEX; break; + case OID_ECKA_EG_X963KDF_SHA384: oid_hex = OID_ECKA_EG_X963KDF_SHA384_HEX; break; + case OID_ECKA_EG_X963KDF_SHA512: oid_hex = OID_ECKA_EG_X963KDF_SHA512_HEX; break; + case OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME_HEX; break; + case OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME_HEX; break; + case OID_MQVSINGLEPASS_SHA1KDF_SCHEME: oid_hex = OID_MQVSINGLEPASS_SHA1KDF_SCHEME_HEX; break; + case OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME_HEX; break; + case OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME_HEX; break; + case OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME_HEX; break; default: /* No possible matches: bitwise-add not found constant to OID. */ *oi |= OID_NOT_FOUND; diff --git a/crypto/keyformat/asn1.h b/crypto/keyformat/asn1.h index f9c8b13..645430a 100644 --- a/crypto/keyformat/asn1.h +++ b/crypto/keyformat/asn1.h @@ -80,6 +80,8 @@ enum # define ASN_UNKNOWN_LEN 65533 +extern uint32_t getAsnTagLenUnsafe(const unsigned char *p); + extern int32_t getAsnLength(const unsigned char **p, psSize_t size, psSize_t *valLen); extern int32_t getAsnLength32(const unsigned char **p, uint32_t size, diff --git a/crypto/keyformat/pkcs.c b/crypto/keyformat/pkcs.c index 3a5949a..f1a725e 100644 --- a/crypto/keyformat/pkcs.c +++ b/crypto/keyformat/pkcs.c @@ -170,6 +170,22 @@ int32_t pkcs1Unpad(const unsigned char *in, psSize_t inlen, #ifdef USE_PRIVATE_KEY_PARSING # ifdef USE_PKCS8 + +static int32 pkcs8parse_unknown( + psPool_t *pool, + unsigned char *buf, + int32 size, + psPubKey_t *key) +{ + /* When PKCS #8 header appears correct, but format is not + RSA or ECDSA this function is called. + The function may be extended to parse public key formats usually + not processed by MatrixSSL. */ + + psTraceCrypto("Unsupported public key type in PKCS#8 parse\n"); + return PS_UNSUPPORTED_FAIL; +} + /******************************************************************************/ /** Parse PKCS#8 format keys (from DER formatted binary) @@ -190,7 +206,6 @@ int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size, const unsigned char *end, *p; int32 version, oi; psSize_t seqlen, len, plen; - # ifdef USE_ECC int32 coi; const psEccCurve_t *eccSet; @@ -213,6 +228,8 @@ int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size, if (pass) { + psSize_t i; + # ifdef USE_PKCS5 /* An encrypted PKCS#8 key has quite a bit more information we must parse We actually parse a good bit of PKCS#5 structures here @@ -324,6 +341,50 @@ int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size, /* @security SECURITY - we zero out des3 key when done with it */ memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t)); memset_s(desKeyBin, DES3_KEYLEN, 0x0, DES3_KEYLEN); + + /* Remove padding. + This implementation allows up-to 16 bytes padding, for + compatibility with 3DES and AES algorithms. */ + /* Start by checking length. */ + /* coverity[dead_error_condition] */ + /* With the current value for MIN_ECC_BITS and MIN_RSA_BITS + this path can never be taken. This code path is ready in + case the values change in the future. */ + if (len < 1) + { + /* coverity[dead_error_begin] */ + psTraceCrypto("PKCS#8 padding error\n"); + return PS_FAILURE; + } + plen = (unsigned char) p[len - 1]; + if (plen < 1 || plen > 16) + { + psTraceCrypto("PKCS#8 padding error\n"); + return PS_FAILURE; + } + /* coverity[dead_error_condition] */ + /* With the current value for MIN_ECC_BITS and MIN_RSA_BITS + this path can never be taken. This code path is ready in + case the values change in the future. */ + if (len < plen) + { + /* coverity[dead_error_begin] */ + psTraceCrypto("PKCS#8 padding error\n"); + return PS_FAILURE; + } + for(i = 0; i < plen; i++) + { + if (p[len - i - 1] != (unsigned char) plen) + { + psTraceCrypto("PKCS#8 padding error\n"); + return PS_FAILURE; + } + } + + /* The padding has been processed. */ + size = len - plen; + end = p + size; + buf = (unsigned char *)p; # else /* !USE_PKCS5 */ /* The private key is encrypted, but PKCS5 support has been turned off @@ -360,8 +421,7 @@ int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size, # ifdef USE_ECC if (oi != OID_ECDSA_KEY_ALG && oi != OID_RSA_KEY_ALG) { - psTraceCrypto("Unsupported public key type in PKCS#8 parse\n"); - return PS_UNSUPPORTED_FAIL; + return pkcs8parse_unknown(pool, buf, size, key); } if (oi == OID_ECDSA_KEY_ALG) { @@ -392,8 +452,7 @@ int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size, # else if (oi != OID_RSA_KEY_ALG || plen != 0) { - psTraceCrypto("Unsupported public key type in PKCS#8 parse\n"); - return PS_UNSUPPORTED_FAIL; + return pkcs8parse_unknown(pool, buf, size, key); } # endif /* PrivateKey Octet Stream */ @@ -456,14 +515,11 @@ int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size, p += len; plen = (int32) (end - p); } - /* Any remaining bytes should be non ASN.1 bytes that correspond - to the 3DES block padding */ - while (p < end) + + if (plen > 0) { - if (*p++ != (char) plen) - { - goto PKCS8_FAIL; - } + /* Unexpected extra data remains. Treat it as an error. */ + goto PKCS8_FAIL; } } diff --git a/crypto/keyformat/x509.c b/crypto/keyformat/x509.c index 17f9ff0..8083f55 100644 --- a/crypto/keyformat/x509.c +++ b/crypto/keyformat/x509.c @@ -191,6 +191,7 @@ int32 psX509ParseCertFile(psPool_t *pool, char *fileName, unsigned char *fileBuf; psList_t *fileList, *currentFile, *x509list, *frontX509; psX509Cert_t *currentCert, *firstCert, *prevCert; + int32 numParsed = 0; *outcert = NULL; /* @@ -234,20 +235,33 @@ int32 psX509ParseCertFile(psPool_t *pool, char *fileName, frontX509 = x509list; /* Recurse each individual cert buffer from within the file - */ + + If partial parse of cert bundles is not allowed, the failure + to load any of the certificates causes the whole function + call to fail. If partial parse of cert bundles is allowed, + parse as many as we can and return the number of parsed certs. +*/ while (x509list != NULL) { - if ((err = psX509ParseCert(pool, x509list->item, x509list->len, - ¤tCert, flags)) < PS_SUCCESS) + err = psX509ParseCert(pool, x509list->item, x509list->len, + ¤tCert, flags); + if (err < 0) { - psX509FreeCert(currentCert); - psFreeList(fileList, pool); - psFreeList(frontX509, pool); - if (firstCert) + if (!(flags & CERT_ALLOW_BUNDLE_PARTIAL_PARSE)) { - psX509FreeCert(firstCert); + psX509FreeCert(currentCert); + psFreeList(fileList, pool); + psFreeList(frontX509, pool); + if (firstCert) + { + psX509FreeCert(firstCert); + } + return err; } - return err; + } + else + { + numParsed++; } x509list = x509list->next; @@ -269,7 +283,7 @@ int32 psX509ParseCertFile(psPool_t *pool, char *fileName, *outcert = firstCert; - return PS_SUCCESS; + return numParsed; } /******************************************************************************/ @@ -616,6 +630,704 @@ PSPUBLIC int32 psX509GetCertPublicKeyDer(psX509Cert_t *cert, return PS_SUCCESS; } +/* + Parse a single, DER-encoded ASN.1 Certificate. + + Preconditions: + - *pp points to the first octet of a DER-encoded Certificate. + - the length of the DER-encoded Certificate is size octets. + - cert points to an allocated and zeroized psX509Cert_t struct. + + Postconditions: + - *pp == (pp_orig + size), where pp_orig is the original (input) + value of *pp. + - If return value is PS_SUCCESS, cert will contain a parsed + and usable certificate. + - If return value is < 0, cert->parseStatus will contain information + about the reason of the parse failure. + + @param[in] Pointer to a memory pool + @param[in,out] pp Pointer to a pointer pointing to the first octet + of a DER-encoded Certificate. After parsing has completed, the underlying + pointer will be updated to point to the octet after the final octet + of the Certificate. + @param[in] size Size of the DER buffer in bytes. + @param[in] cert An allocated psX509Cert_t struct to be filled. + with the parsed Certificate data. + @param[in] flags +*/ +static int parse_single_cert(psPool_t *pool, const unsigned char **pp, + uint32 size, const unsigned char *far_end, + psX509Cert_t *cert, int32 flags) +{ +# ifdef USE_CERT_PARSE + const unsigned char *tbsCertStart; + unsigned char sha1KeyHash[SHA1_HASH_SIZE]; + psDigestContext_t hashCtx; + psSize_t certLen; + const unsigned char *p_subject_pubkey_info; + size_t subject_pubkey_info_header_len; +# endif /* USE_CERT_PARSE */ + const unsigned char *certStart, *certEnd, *end, *p; + int32_t rc, func_rc; + uint32_t oneCertLen; + psSize_t len, plen; + + /* + Initialize the cert structure.*/ + cert->pool = pool; + cert->parseStatus = PS_X509_PARSE_FAIL; /* Default to fail status */ +# ifdef USE_CERT_PARSE + cert->extensions.bc.cA = CA_UNDEFINED; +# endif /* USE_CERT_PARSE */ + + p = *pp; + certStart = p; + end = p + size; + + func_rc = PS_SUCCESS; + + if ((rc = getAsnSequence32(&p, (uint32_t) (far_end - p), &oneCertLen, 0)) + < 0) + { + psTraceCrypto("Initial cert parse error\n"); + func_rc = rc; + goto out; + } + /* The whole list of certs could be > 64K bytes, but we still + restrict individual certs to 64KB */ + if (oneCertLen > 0xFFFF) + { + psAssert(oneCertLen <= 0xFFFF); + func_rc = PS_FAILURE; + goto out; + } + end = p + oneCertLen; + + /* + If the user has specified to keep the ASN.1 buffer in the X.509 + structure, now is the time to account for it + */ + if (flags & CERT_STORE_UNPARSED_BUFFER) + { + cert->binLen = oneCertLen + (int32) (p - certStart); + cert->unparsedBin = psMalloc(pool, cert->binLen); + if (cert->unparsedBin == NULL) + { + psError("Memory allocation error in psX509ParseCert\n"); + func_rc = PS_MEM_FAIL; + goto out; + } + memcpy(cert->unparsedBin, certStart, cert->binLen); + } + +# ifdef ENABLE_CA_CERT_HASH + /* We use the cert_sha1_hash type for the Trusted CA Indication so + run a SHA1 has over the entire Certificate DER encoding. */ + psSha1PreInit(&hashCtx.sha1); + psSha1Init(&hashCtx.sha1); + psSha1Update(&hashCtx.sha1, certStart, + oneCertLen + (int32) (p - certStart)); + psSha1Final(&hashCtx.sha1, cert->sha1CertHash); +# endif + +# ifdef USE_CERT_PARSE + tbsCertStart = p; +# endif /* USE_CERT_PARSE */ + /* + TBSCertificate ::= SEQUENCE { + version [0] EXPLICIT Version DEFAULT v1, + serialNumber CertificateSerialNumber, + signature AlgorithmIdentifier, + issuer Name, + validity Validity, + subject Name, + subjectPublicKeyInfo SubjectPublicKeyInfo, + issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + extensions [3] EXPLICIT Extensions OPTIONAL + -- If present, version shall be v3 } + */ + if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) + { + psTraceCrypto("ASN sequence parse error\n"); + func_rc = rc; + goto out; + } + certEnd = p + len; +# ifdef USE_CERT_PARSE + /* + Start parsing TBSCertificate contents. + */ + certLen = certEnd - tbsCertStart; + /* + Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + if ((rc = getExplicitVersion(&p, (uint32) (end - p), 0, &cert->version)) + < 0) + { + psTraceCrypto("ASN version parse error\n"); + func_rc = rc; + goto out; + } + switch (cert->version) + { + case 0: + case 1: +# ifndef ALLOW_VERSION_1_ROOT_CERT_PARSE + psTraceCrypto("ERROR: v1 and v2 certificate versions insecure\n"); + cert->parseStatus = PS_X509_UNSUPPORTED_VERSION; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; +# else + /* Allow locally stored, trusted version 1 and version 2 certificates + to be parsed. The SSL layer code will still reject non v3 + certificates that arrive over-the-wire. */ + /* Version 1 certificates do not have basic constraints to + specify a CA flag or path length. Here, the CA flag is implied + since v1 certs can only be loaded as root. We explicitly set + the pathLengthConstraint to allow up to 2 intermediate certs. + This can be adjusted to allow more or less intermediate certs. */ + cert->extensions.bc.pathLenConstraint = 2; + break; +# endif /* ALLOW_VERSION_1_ROOT_CERT_PARSE */ + case 2: + /* Typical case of v3 cert */ + break; + default: + psTraceIntCrypto("ERROR: unknown certificate version: %d\n", + cert->version); + cert->parseStatus = PS_X509_UNSUPPORTED_VERSION; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } + /* + CertificateSerialNumber ::= INTEGER + There is a special return code for a missing serial number that + will get written to the parse warning flag + */ + if ((rc = getSerialNum(pool, &p, (uint32) (end - p), &cert->serialNumber, + &cert->serialNumberLen)) < 0) + { + psTraceCrypto("ASN serial number parse error\n"); + func_rc = rc; + goto out; + } + /* + AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY algorithm OPTIONAL } + */ + if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p), + &cert->certAlgorithm, &plen)) < 0) + { + psTraceCrypto("Couldn't parse algorithm identifier for certAlgorithm\n"); + cert->parseStatus = PS_X509_ALG_ID; + func_rc = rc; + goto out; + } + if (plen != 0) + { +# ifdef USE_PKCS1_PSS + if (cert->certAlgorithm == OID_RSASSA_PSS) + { + /* RSASSA-PSS-params ::= SEQUENCE { + hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + saltLength [2] INTEGER DEFAULT 20, + trailerField [3] TrailerField DEFAULT trailerFieldBC + } + */ + if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) + { + psTraceCrypto("ASN sequence parse error\n"); + func_rc = rc; + goto out; + } + /* Always set the defaults before parsing */ + cert->pssHash = PKCS1_SHA1_ID; + cert->maskGen = OID_ID_MGF1; + cert->saltLen = SHA1_HASH_SIZE; + /* Something other than defaults to parse here? */ + if (len > 0) + { + if ((rc = getRsaPssParams(&p, len, cert, 0)) < 0) + { + func_rc = rc; + goto out; + } + } + } + else + { + psTraceCrypto("Unsupported X.509 certAlgorithm\n"); + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } +# else + psTraceCrypto("Unsupported X.509 certAlgorithm\n"); + func_rc = PS_UNSUPPORTED_FAIL; + goto out; +# endif + } + /* + Name ::= CHOICE { + RDNSequence } + + RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + + RelativeDistinguishedName ::= SET OF AttributeTypeAndValue + + AttributeTypeAndValue ::= SEQUENCE { + type AttributeType, + value AttributeValue } + + AttributeType ::= OBJECT IDENTIFIER + + AttributeValue ::= ANY DEFINED BY AttributeType + */ + if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p), + &cert->issuer, flags)) < 0) + { + psTraceCrypto("Couldn't parse issuer DN attributes\n"); + cert->parseStatus = PS_X509_ISSUER_DN; + func_rc = rc; + goto out; + } + /* + Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } + */ + if ((rc = getTimeValidity(pool, &p, (uint32) (end - p), + &cert->notBeforeTimeType, &cert->notAfterTimeType, + &cert->notBefore, &cert->notAfter)) < 0) + { + psTraceCrypto("Couldn't parse validity\n"); + func_rc = rc; + goto out; + } + + /* SECURITY - platforms without a date function will always succeed */ + if ((rc = validateDateRange(cert)) < 0) + { + psTraceCrypto("Validity date check failed\n"); + cert->parseStatus = PS_X509_DATE; + func_rc = rc; + goto out; + } + /* + Subject DN + */ + cert->subjectKeyDerOffsetIntoUnparsedBin = (uint16_t) (p - certStart); + if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p), + &cert->subject, flags)) < 0) + { + psTraceCrypto("Couldn't parse subject DN attributes\n"); + cert->parseStatus = PS_X509_SUBJECT_DN; + func_rc = rc; + goto out; + } + /* + SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING } + */ + p_subject_pubkey_info = p; + + cert->publicKeyDerOffsetIntoUnparsedBin = (uint16_t) (p - certStart); + + if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) + { + psTraceCrypto("Couldn't get ASN sequence for pubKeyAlgorithm\n"); + func_rc = rc; + goto out; + } + subject_pubkey_info_header_len = (p - p_subject_pubkey_info); + cert->publicKeyDerLen = len + subject_pubkey_info_header_len; + + if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p), + &cert->pubKeyAlgorithm, &plen)) < 0) + { + psTraceCrypto("Couldn't parse algorithm id for pubKeyAlgorithm\n"); + func_rc = rc; + goto out; + } + + /* Populate with correct type based on pubKeyAlgorithm OID */ + switch (cert->pubKeyAlgorithm) + { +# ifdef USE_ECC + case OID_ECDSA_KEY_ALG: + if (plen == 0 || plen > (int32) (end - p)) + { + psTraceCrypto("Bad params on EC OID\n"); + func_rc = PS_PARSE_FAIL; + goto out; + } + psInitPubKey(pool, &cert->publicKey, PS_ECC); + if ((rc = getEcPubKey(pool, &p, (uint16_t) (end - p), + &cert->publicKey.key.ecc, sha1KeyHash)) < 0) + { + if (rc == PS_UNSUPPORTED_FAIL) + { + cert->parseStatus = PS_X509_UNSUPPORTED_ECC_CURVE; + } + func_rc = PS_PARSE_FAIL; + goto out; + } + /* keysize will be the size of the public ecc key (2 * privateLen) */ + cert->publicKey.keysize = psEccSize(&cert->publicKey.key.ecc); + if (cert->publicKey.keysize < (MIN_ECC_BITS / 8)) + { + psTraceIntCrypto("ECC key size < %d\n", MIN_ECC_BITS); + psClearPubKey(&cert->publicKey); + cert->parseStatus = PS_X509_WEAK_KEY; + func_rc = PS_PARSE_FAIL; + goto out; + } + break; +# endif +# ifdef USE_RSA + case OID_RSA_KEY_ALG: + psAssert(plen == 0); /* No parameters on RSA pub key OID */ + psInitPubKey(pool, &cert->publicKey, PS_RSA); + if ((rc = psRsaParseAsnPubKey(pool, &p, (uint16_t) (end - p), + &cert->publicKey.key.rsa, sha1KeyHash)) < 0) + { + psTraceCrypto("Couldn't get RSA pub key from cert\n"); + cert->parseStatus = PS_X509_MISSING_RSA; + func_rc = rc; + goto out; + } + cert->publicKey.keysize = psRsaSize(&cert->publicKey.key.rsa); + + if (cert->publicKey.keysize < (MIN_RSA_BITS / 8)) + { + psTraceIntCrypto("RSA key size < %d\n", MIN_RSA_BITS); + psClearPubKey(&cert->publicKey); + cert->parseStatus = PS_X509_WEAK_KEY; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } + + break; +# endif + default: + /* Note 645:RSA, 515:DSA, 518:ECDSA, 32969:GOST */ + psTraceIntCrypto( + "Unsupported public key algorithm in cert parse: %d\n", + cert->pubKeyAlgorithm); + cert->parseStatus = PS_X509_UNSUPPORTED_KEY_ALG; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } + +# ifdef USE_OCSP + /* A sha1 hash of the public key is useful for OCSP */ + memcpy(cert->sha1KeyHash, sha1KeyHash, SHA1_HASH_SIZE); +# endif + + /* As the next three values are optional, we can do a specific test here */ + if (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED)) + { + if (getImplicitBitString(pool, &p, (uint32) (end - p), + IMPLICIT_ISSUER_ID, &cert->uniqueIssuerId, + &cert->uniqueIssuerIdLen) < 0 || + getImplicitBitString(pool, &p, (uint32) (end - p), + IMPLICIT_SUBJECT_ID, &cert->uniqueSubjectId, + &cert->uniqueSubjectIdLen) < 0 || + getExplicitExtensions(pool, &p, (uint32) (end - p), + EXPLICIT_EXTENSION, &cert->extensions, 0) < 0) + { + psTraceCrypto("There was an error parsing a certificate\n" + "extension. This is likely caused by an\n" + "extension format that is not currently\n" + "recognized. Please email support\n" + "to add support for the extension.\n"); + cert->parseStatus = PS_X509_UNSUPPORTED_EXT; + func_rc = PS_PARSE_FAIL; + goto out; + } + } + + /* This is the end of the cert. Do a check here to be certain */ + if (certEnd != p) + { + psTraceCrypto("Error. Expecting end of cert\n"); + cert->parseStatus = PS_X509_EOF; + func_rc = PS_LIMIT_FAIL; + goto out; + } + + /* Reject any cert without a distinguishedName or subjectAltName */ + if (cert->subject.commonName == NULL && + cert->subject.country == NULL && + cert->subject.state == NULL && + cert->subject.organization == NULL && + cert->subject.orgUnit == NULL && + cert->subject.domainComponent == NULL && + cert->extensions.san == NULL) + { + psTraceCrypto("Error. Cert has no name information\n"); + cert->parseStatus = PS_X509_MISSING_NAME; + func_rc = PS_PARSE_FAIL; + goto out; + } +# else /* No TBSCertificate parsing. */ + p = certEnd; +# endif /* USE_CERT_PARSE (end of TBSCertificate parsing) */ + + /* Certificate signature info */ + if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p), + &cert->sigAlgorithm, &plen)) < 0) + { + psTraceCrypto("Couldn't get algorithm identifier for sigAlgorithm\n"); + func_rc = rc; + goto out; + } + + if (plen != 0) + { +# ifdef USE_PKCS1_PSS + if (cert->sigAlgorithm == OID_RSASSA_PSS) + { + /* RSASSA-PSS-params ::= SEQUENCE { + hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + saltLength [2] INTEGER DEFAULT 20, + trailerField [3] TrailerField DEFAULT trailerFieldBC + } + */ + if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) + { + psTraceCrypto("ASN sequence parse error\n"); + func_rc = rc; + goto out; + } + /* Something other than defaults to parse here? */ + if (len > 0) + { + if ((rc = getRsaPssParams(&p, len, cert, 1)) < 0) + { + func_rc = rc; + goto out; + } + } + } + else + { + psTraceCrypto("Unsupported X.509 sigAlgorithm\n"); + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } +# else + psTraceCrypto("Unsupported X.509 sigAlgorithm\n"); + func_rc = PS_UNSUPPORTED_FAIL; + goto out; +# endif /* USE_PKCS1_PSS */ + } +# ifdef USE_CERT_PARSE + /* + https://tools.ietf.org/html/rfc5280#section-4.1.1.2 + This field MUST contain the same algorithm identifier as the + signature field in the sequence tbsCertificate (Section 4.1.2.3). + */ + if (cert->certAlgorithm != cert->sigAlgorithm) + { + psTraceIntCrypto("Parse error: mismatched sig alg (tbs = %d ", + cert->certAlgorithm); + psTraceIntCrypto("sig = %d)\n", cert->sigAlgorithm); + cert->parseStatus = PS_X509_SIG_MISMATCH; + func_rc = PS_PARSE_FAIL; + goto out; + } + /* + Compute the hash of the cert here for CA validation + */ + switch (cert->certAlgorithm) + { +# ifdef ENABLE_MD5_SIGNED_CERTS +# ifdef USE_MD2 + case OID_MD2_RSA_SIG: + psMd2Init(&hashCtx.md2); + psMd2Update(&hashCtx.md2, tbsCertStart, certLen); + psMd2Final(&hashCtx.md2, cert->sigHash); + break; +# endif /* USE_MD2 */ + case OID_MD5_RSA_SIG: + psMd5Init(&hashCtx.md5); + psMd5Update(&hashCtx.md5, tbsCertStart, certLen); + psMd5Final(&hashCtx.md5, cert->sigHash); + break; +# endif +# ifdef ENABLE_SHA1_SIGNED_CERTS + case OID_SHA1_RSA_SIG: + case OID_SHA1_RSA_SIG2: +# ifdef USE_ECC + case OID_SHA1_ECDSA_SIG: +# endif + psSha1PreInit(&hashCtx.sha1); + psSha1Init(&hashCtx.sha1); + psSha1Update(&hashCtx.sha1, tbsCertStart, certLen); + psSha1Final(&hashCtx.sha1, cert->sigHash); + break; +# endif +# ifdef USE_SHA224 + case OID_SHA224_RSA_SIG: +# ifdef USE_ECC + case OID_SHA224_ECDSA_SIG: +# endif + psSha224PreInit(&hashCtx.sha256); + psSha224Init(&hashCtx.sha256); + psSha224Update(&hashCtx.sha256, tbsCertStart, certLen); + psSha224Final(&hashCtx.sha256, cert->sigHash); + break; +# endif +# ifdef USE_SHA256 + case OID_SHA256_RSA_SIG: +# ifdef USE_ECC + case OID_SHA256_ECDSA_SIG: +# endif + psSha256PreInit(&hashCtx.sha256); + psSha256Init(&hashCtx.sha256); + psSha256Update(&hashCtx.sha256, tbsCertStart, certLen); + psSha256Final(&hashCtx.sha256, cert->sigHash); + break; +# endif +# ifdef USE_SHA384 + case OID_SHA384_RSA_SIG: +# ifdef USE_ECC + case OID_SHA384_ECDSA_SIG: +# endif + psSha384PreInit(&hashCtx.sha384); + psSha384Init(&hashCtx.sha384); + psSha384Update(&hashCtx.sha384, tbsCertStart, certLen); + psSha384Final(&hashCtx.sha384, cert->sigHash); + break; +# endif +# ifdef USE_SHA512 + case OID_SHA512_RSA_SIG: +# ifdef USE_ECC + case OID_SHA512_ECDSA_SIG: +# endif + psSha512PreInit(&hashCtx.sha512); + psSha512Init(&hashCtx.sha512); + psSha512Update(&hashCtx.sha512, tbsCertStart, certLen); + psSha512Final(&hashCtx.sha512, cert->sigHash); + break; +# endif +# ifdef USE_PKCS1_PSS + case OID_RSASSA_PSS: + switch (cert->pssHash) + { +# ifdef ENABLE_MD5_SIGNED_CERTS + case PKCS1_MD5_ID: + psMd5Init(&hashCtx.md5); + psMd5Update(&hashCtx.md5, tbsCertStart, certLen); + psMd5Final(&hashCtx.md5, cert->sigHash); + break; +# endif +# ifdef ENABLE_SHA1_SIGNED_CERTS + case PKCS1_SHA1_ID: + psSha1PreInit(&hashCtx.sha1); + psSha1Init(&hashCtx.sha1); + psSha1Update(&hashCtx.sha1, tbsCertStart, certLen); + psSha1Final(&hashCtx.sha1, cert->sigHash); + break; +# endif +# ifdef USE_SHA224 + case PKCS1_SHA224_ID: + psSha224PreInit(&hashCtx.sha256); + psSha224Init(&hashCtx.sha256); + psSha224Update(&hashCtx.sha256, tbsCertStart, certLen); + psSha224Final(&hashCtx.sha256, cert->sigHash); + break; +# endif +# ifdef USE_SHA256 + case PKCS1_SHA256_ID: + psSha256PreInit(&hashCtx.sha256); + psSha256Init(&hashCtx.sha256); + psSha256Update(&hashCtx.sha256, tbsCertStart, certLen); + psSha256Final(&hashCtx.sha256, cert->sigHash); + break; +# endif +# ifdef USE_SHA384 + case PKCS1_SHA384_ID: + psSha384PreInit(&hashCtx.sha384); + psSha384Init(&hashCtx.sha384); + psSha384Update(&hashCtx.sha384, tbsCertStart, certLen); + psSha384Final(&hashCtx.sha384, cert->sigHash); + break; +# endif +# ifdef USE_SHA512 + case PKCS1_SHA512_ID: + psSha512PreInit(&hashCtx.sha512); + psSha512Init(&hashCtx.sha512); + psSha512Update(&hashCtx.sha512, tbsCertStart, certLen); + psSha512Final(&hashCtx.sha512, cert->sigHash); + break; +# endif + default: + psTraceIntCrypto("Unsupported pssHash algorithm: %d\n", + cert->pssHash); + cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } /* switch pssHash */ + break; +# endif /* USE_PKCS1_PSS */ + + default: + /* Note 1670:MD2 */ + psTraceIntCrypto("Unsupported cert algorithm: %d\n", + cert->certAlgorithm); + cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + + } /* switch certAlgorithm */ + + /* 6 empty bytes is plenty enough to know if sigHash didn't calculate */ + if (memcmp(cert->sigHash, "\0\0\0\0\0\0", 6) == 0) + { + psTraceIntCrypto("No library signature alg support for cert: %d\n", + cert->certAlgorithm); + cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG; + func_rc = PS_UNSUPPORTED_FAIL; + goto out; + } +# endif /* USE_CERT_PARSE */ + + if ((rc = psX509GetSignature(pool, &p, (uint32) (end - p), + &cert->signature, &cert->signatureLen)) < 0) + { + psTraceCrypto("Couldn't parse signature\n"); + cert->parseStatus = PS_X509_SIGNATURE; + func_rc = rc; + goto out; + } + +# ifndef USE_CERT_PARSE + /* Some APIs need certAlgorithm.*/ + cert->certAlgorithm = cert->sigAlgorithm; +# endif /* !USE_CERT_PARSE */ + +out: + if (func_rc == PS_SUCCESS) + { + cert->parseStatus = PS_X509_PARSE_SUCCESS; + psAssert(p == end); /* Must have parsed everything. */ + } + psAssert(p <= end); /* Must not have parsed too much. */ + + *pp = end; + + return func_rc; +} + /******************************************************************************/ /* Parse an X509 v3 ASN.1 certificate stream @@ -632,26 +1344,19 @@ int32 psX509ParseCert(psPool_t *pool, const unsigned char *pp, uint32 size, psX509Cert_t **outcert, int32 flags) { psX509Cert_t *cert; - const unsigned char *p, *end, *far_end, *certStart; - psSize_t len; - uint32_t oneCertLen; + const unsigned char *p, *far_end; int32_t parsing, rc; - const unsigned char *certEnd; - psSize_t plen; + int32_t numCerts = 0; + int32_t numParsedCerts = 0; -# ifdef USE_CERT_PARSE - const unsigned char *tbsCertStart; - unsigned char sha1KeyHash[SHA1_HASH_SIZE]; - psDigestContext_t hashCtx; - psSize_t certLen; - const unsigned char *p_subject_pubkey_info; - size_t subject_pubkey_info_header_len; -# endif /* USE_CERT_PARSE */ /* Allocate the cert structure right away. User MUST always call psX509FreeCert regardless of whether this function succeeds. memset is important because the test for NULL is what is used - to determine what to free + to determine what to free. + + If the input stream consists of multiple certs, the rest of + the psX509Cert_t structs will be allocated in parse_single_cert(). */ *outcert = cert = psMalloc(pool, sizeof(psX509Cert_t)); if (cert == NULL) @@ -660,11 +1365,6 @@ int32 psX509ParseCert(psPool_t *pool, const unsigned char *pp, uint32 size, return PS_MEM_FAIL; } memset(cert, 0x0, sizeof(psX509Cert_t)); - cert->pool = pool; - cert->parseStatus = PS_X509_PARSE_FAIL; /* Default to fail status */ -# ifdef USE_CERT_PARSE - cert->extensions.bc.cA = CA_UNDEFINED; -# endif /* USE_CERT_PARSE */ # ifdef ALWAYS_KEEP_CERT_DER flags |= CERT_STORE_UNPARSED_BUFFER; @@ -672,591 +1372,44 @@ int32 psX509ParseCert(psPool_t *pool, const unsigned char *pp, uint32 size, p = pp; far_end = p + size; -/* - Certificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm AlgorithmIdentifier, - signatureValue BIT STRING } - */ + parsing = 1; while (parsing) { - certStart = p; - if ((rc = getAsnSequence32(&p, (uint32_t) (far_end - p), &oneCertLen, 0)) - < 0) + /* + Certificate ::= SEQUENCE { + tbsCertificate TBSCertificate, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } + */ + rc = parse_single_cert(pool, &p, size, far_end, cert, flags); + if (rc == PS_SUCCESS) { - psTraceCrypto("Initial cert parse error\n"); - return rc; + numParsedCerts++; } - /* The whole list of certs could be > 64K bytes, but we still - restrict individual certs to 64KB */ - if (oneCertLen > 0xFFFF) + else { - psAssert(oneCertLen <= 0xFFFF); - return PS_FAILURE; - } - end = p + oneCertLen; -/* - If the user has specified to keep the ASN.1 buffer in the X.509 - structure, now is the time to account for it - */ - if (flags & CERT_STORE_UNPARSED_BUFFER) - { - cert->binLen = oneCertLen + (int32) (p - certStart); - cert->unparsedBin = psMalloc(pool, cert->binLen); - if (cert->unparsedBin == NULL) + psAssert(cert->parseStatus != PS_X509_PARSE_SUCCESS); + + if (!(flags & CERT_ALLOW_BUNDLE_PARTIAL_PARSE)) { - psError("Memory allocation error in psX509ParseCert\n"); - return PS_MEM_FAIL; - } - memcpy(cert->unparsedBin, certStart, cert->binLen); - } - -# ifdef ENABLE_CA_CERT_HASH - /* We use the cert_sha1_hash type for the Trusted CA Indication so - run a SHA1 has over the entire Certificate DER encoding. */ - psSha1PreInit(&hashCtx.sha1); - psSha1Init(&hashCtx.sha1); - psSha1Update(&hashCtx.sha1, certStart, - oneCertLen + (int32) (p - certStart)); - psSha1Final(&hashCtx.sha1, cert->sha1CertHash); -# endif - -# ifdef USE_CERT_PARSE - tbsCertStart = p; -# endif /* USE_CERT_PARSE */ -/* - TBSCertificate ::= SEQUENCE { - version [0] EXPLICIT Version DEFAULT v1, - serialNumber CertificateSerialNumber, - signature AlgorithmIdentifier, - issuer Name, - validity Validity, - subject Name, - subjectPublicKeyInfo SubjectPublicKeyInfo, - issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version shall be v2 or v3 - subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version shall be v2 or v3 - extensions [3] EXPLICIT Extensions OPTIONAL - -- If present, version shall be v3 } - */ - if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) - { - psTraceCrypto("ASN sequence parse error\n"); - return rc; - } - certEnd = p + len; -# ifdef USE_CERT_PARSE -/* - Start parsing TBSCertificate contents. - */ - certLen = certEnd - tbsCertStart; -/* - Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - if ((rc = getExplicitVersion(&p, (uint32) (end - p), 0, &cert->version)) - < 0) - { - psTraceCrypto("ASN version parse error\n"); - return rc; - } - switch (cert->version) - { - case 0: - case 1: -# ifndef ALLOW_VERSION_1_ROOT_CERT_PARSE - psTraceCrypto("ERROR: v1 and v2 certificate versions insecure\n"); - cert->parseStatus = PS_X509_UNSUPPORTED_VERSION; - return PS_PARSE_FAIL; -# else - /* Allow locally stored, trusted version 1 and version 2 certificates - to be parsed. The SSL layer code will still reject non v3 - certificates that arrive over-the-wire. */ - /* Version 1 certificates do not have basic constraints to - specify a CA flag or path length. Here, the CA flag is implied - since v1 certs can only be loaded as root. We explicitly set - the pathLengthConstraint to allow up to 2 intermediate certs. - This can be adjusted to allow more or less intermediate certs. */ - cert->extensions.bc.pathLenConstraint = 2; - break; -# endif /* ALLOW_VERSION_1_ROOT_CERT_PARSE */ - case 2: - /* Typical case of v3 cert */ - break; - default: - psTraceIntCrypto("ERROR: unknown certificate version: %d\n", - cert->version); - cert->parseStatus = PS_X509_UNSUPPORTED_VERSION; - return PS_PARSE_FAIL; - } -/* - CertificateSerialNumber ::= INTEGER - There is a special return code for a missing serial number that - will get written to the parse warning flag - */ - if ((rc = getSerialNum(pool, &p, (uint32) (end - p), &cert->serialNumber, - &cert->serialNumberLen)) < 0) - { - psTraceCrypto("ASN serial number parse error\n"); - return rc; - } -/* - AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL } - */ - if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p), - &cert->certAlgorithm, &plen)) < 0) - { - psTraceCrypto("Couldn't parse algorithm identifier for certAlgorithm\n"); - cert->parseStatus = PS_X509_ALG_ID; - return rc; - } - if (plen != 0) - { -# ifdef USE_PKCS1_PSS - if (cert->certAlgorithm == OID_RSASSA_PSS) - { - /* RSASSA-PSS-params ::= SEQUENCE { - hashAlgorithm [0] HashAlgorithm DEFAULT sha1, - maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, - saltLength [2] INTEGER DEFAULT 20, - trailerField [3] TrailerField DEFAULT trailerFieldBC - } - */ - if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) - { - psTraceCrypto("ASN sequence parse error\n"); - return rc; - } - /* Always set the defaults before parsing */ - cert->pssHash = PKCS1_SHA1_ID; - cert->maskGen = OID_ID_MGF1; - cert->saltLen = SHA1_HASH_SIZE; - /* Something other than defaults to parse here? */ - if (len > 0) - { - if ((rc = getRsaPssParams(&p, len, cert, 0)) < 0) - { - return rc; - } - } - } - else - { - psTraceCrypto("Unsupported X.509 certAlgorithm\n"); - return PS_UNSUPPORTED_FAIL; - } -# else - psTraceCrypto("Unsupported X.509 certAlgorithm\n"); - return PS_UNSUPPORTED_FAIL; -# endif - } -/* - Name ::= CHOICE { - RDNSequence } - - RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - - RelativeDistinguishedName ::= SET OF AttributeTypeAndValue - - AttributeTypeAndValue ::= SEQUENCE { - type AttributeType, - value AttributeValue } - - AttributeType ::= OBJECT IDENTIFIER - - AttributeValue ::= ANY DEFINED BY AttributeType - */ - if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p), - &cert->issuer, flags)) < 0) - { - psTraceCrypto("Couldn't parse issuer DN attributes\n"); - cert->parseStatus = PS_X509_ISSUER_DN; - return rc; - } -/* - Validity ::= SEQUENCE { - notBefore Time, - notAfter Time } - */ - if ((rc = getTimeValidity(pool, &p, (uint32) (end - p), - &cert->notBeforeTimeType, &cert->notAfterTimeType, - &cert->notBefore, &cert->notAfter)) < 0) - { - psTraceCrypto("Couldn't parse validity\n"); - return rc; - } - - /* SECURITY - platforms without a date function will always succeed */ - if ((rc = validateDateRange(cert)) < 0) - { - psTraceCrypto("Validity date check failed\n"); - cert->parseStatus = PS_X509_DATE; - return rc; - } -/* - Subject DN - */ - cert->subjectKeyDerOffsetIntoUnparsedBin = (uint16_t) (p - certStart); - if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p), - &cert->subject, flags)) < 0) - { - psTraceCrypto("Couldn't parse subject DN attributes\n"); - cert->parseStatus = PS_X509_SUBJECT_DN; - return rc; - } -/* - SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING } - */ - p_subject_pubkey_info = p; - - cert->publicKeyDerOffsetIntoUnparsedBin = (uint16_t) (p - certStart); - - if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) - { - psTraceCrypto("Couldn't get ASN sequence for pubKeyAlgorithm\n"); - return rc; - } - subject_pubkey_info_header_len = (p - p_subject_pubkey_info); - cert->publicKeyDerLen = len + subject_pubkey_info_header_len; - - if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p), - &cert->pubKeyAlgorithm, &plen)) < 0) - { - psTraceCrypto("Couldn't parse algorithm id for pubKeyAlgorithm\n"); - return rc; - } - - /* Populate with correct type based on pubKeyAlgorithm OID */ - switch (cert->pubKeyAlgorithm) - { -# ifdef USE_ECC - case OID_ECDSA_KEY_ALG: - if (plen == 0 || plen > (int32) (end - p)) - { - psTraceCrypto("Bad params on EC OID\n"); - return PS_PARSE_FAIL; - } - psInitPubKey(pool, &cert->publicKey, PS_ECC); - if ((rc = getEcPubKey(pool, &p, (uint16_t) (end - p), - &cert->publicKey.key.ecc, sha1KeyHash)) < 0) - { - if (rc == PS_UNSUPPORTED_FAIL) - { - cert->parseStatus = PS_X509_UNSUPPORTED_ECC_CURVE; - } - return PS_PARSE_FAIL; - } - /* keysize will be the size of the public ecc key (2 * privateLen) */ - cert->publicKey.keysize = psEccSize(&cert->publicKey.key.ecc); - if (cert->publicKey.keysize < (MIN_ECC_BITS / 8)) - { - psTraceIntCrypto("ECC key size < %d\n", MIN_ECC_BITS); - psClearPubKey(&cert->publicKey); - cert->parseStatus = PS_X509_WEAK_KEY; - return PS_PARSE_FAIL; - } - break; -# endif -# ifdef USE_RSA - case OID_RSA_KEY_ALG: - psAssert(plen == 0); /* No parameters on RSA pub key OID */ - psInitPubKey(pool, &cert->publicKey, PS_RSA); - if ((rc = psRsaParseAsnPubKey(pool, &p, (uint16_t) (end - p), - &cert->publicKey.key.rsa, sha1KeyHash)) < 0) - { - psTraceCrypto("Couldn't get RSA pub key from cert\n"); - cert->parseStatus = PS_X509_MISSING_RSA; return rc; } - cert->publicKey.keysize = psRsaSize(&cert->publicKey.key.rsa); - - if (cert->publicKey.keysize < (MIN_RSA_BITS / 8)) - { - psTraceIntCrypto("RSA key size < %d\n", MIN_RSA_BITS); - psClearPubKey(&cert->publicKey); - cert->parseStatus = PS_X509_WEAK_KEY; - return PS_PARSE_FAIL; - } - - break; -# endif - default: - /* Note 645:RSA, 515:DSA, 518:ECDSA, 32969:GOST */ - psTraceIntCrypto( - "Unsupported public key algorithm in cert parse: %d\n", - cert->pubKeyAlgorithm); - cert->parseStatus = PS_X509_UNSUPPORTED_KEY_ALG; - return PS_UNSUPPORTED_FAIL; } -# ifdef USE_OCSP - /* A sha1 hash of the public key is useful for OCSP */ - memcpy(cert->sha1KeyHash, sha1KeyHash, SHA1_HASH_SIZE); -# endif + numCerts++; - /* As the next three values are optional, we can do a specific test here */ - if (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED)) - { - if (getImplicitBitString(pool, &p, (uint32) (end - p), - IMPLICIT_ISSUER_ID, &cert->uniqueIssuerId, - &cert->uniqueIssuerIdLen) < 0 || - getImplicitBitString(pool, &p, (uint32) (end - p), - IMPLICIT_SUBJECT_ID, &cert->uniqueSubjectId, - &cert->uniqueSubjectIdLen) < 0 || - getExplicitExtensions(pool, &p, (uint32) (end - p), - EXPLICIT_EXTENSION, &cert->extensions, 0) < 0) - { - psTraceCrypto("There was an error parsing a certificate\n" - "extension. This is likely caused by an\n" - "extension format that is not currently\n" - "recognized. Please email support\n" - "to add support for the extension.\n"); - cert->parseStatus = PS_X509_UNSUPPORTED_EXT; - return PS_PARSE_FAIL; - } - } + /* + Check whether we reached the end of the input DER stream. - /* This is the end of the cert. Do a check here to be certain */ - if (certEnd != p) - { - psTraceCrypto("Error. Expecting end of cert\n"); - cert->parseStatus = PS_X509_EOF; - return PS_LIMIT_FAIL; - } - - /* Reject any cert without a distinguishedName or subjectAltName */ - if (cert->subject.commonName == NULL && - cert->subject.country == NULL && - cert->subject.state == NULL && - cert->subject.organization == NULL && - cert->subject.orgUnit == NULL && - cert->subject.domainComponent == NULL && - cert->extensions.san == NULL) - { - psTraceCrypto("Error. Cert has no name information\n"); - cert->parseStatus = PS_X509_MISSING_NAME; - return PS_PARSE_FAIL; - } -# else /* No TBSCertificate parsing. */ - p = certEnd; -# endif /* USE_CERT_PARSE (end of TBSCertificate parsing) */ - - /* Certificate signature info */ - if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p), - &cert->sigAlgorithm, &plen)) < 0) - { - psTraceCrypto("Couldn't get algorithm identifier for sigAlgorithm\n"); - return rc; - } - - if (plen != 0) - { -# ifdef USE_PKCS1_PSS - if (cert->sigAlgorithm == OID_RSASSA_PSS) - { - /* RSASSA-PSS-params ::= SEQUENCE { - hashAlgorithm [0] HashAlgorithm DEFAULT sha1, - maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, - saltLength [2] INTEGER DEFAULT 20, - trailerField [3] TrailerField DEFAULT trailerFieldBC - } - */ - if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0) - { - psTraceCrypto("ASN sequence parse error\n"); - return rc; - } - /* Something other than defaults to parse here? */ - if (len > 0) - { - if ((rc = getRsaPssParams(&p, len, cert, 1)) < 0) - { - return rc; - } - } - } - else - { - psTraceCrypto("Unsupported X.509 sigAlgorithm\n"); - return PS_UNSUPPORTED_FAIL; - } -# else - psTraceCrypto("Unsupported X.509 sigAlgorithm\n"); - return PS_UNSUPPORTED_FAIL; -# endif /* USE_PKCS1_PSS */ - } -# ifdef USE_CERT_PARSE -/* - https://tools.ietf.org/html/rfc5280#section-4.1.1.2 - This field MUST contain the same algorithm identifier as the - signature field in the sequence tbsCertificate (Section 4.1.2.3). - */ - if (cert->certAlgorithm != cert->sigAlgorithm) - { - psTraceIntCrypto("Parse error: mismatched sig alg (tbs = %d ", - cert->certAlgorithm); - psTraceIntCrypto("sig = %d)\n", cert->sigAlgorithm); - cert->parseStatus = PS_X509_SIG_MISMATCH; - return PS_CERT_AUTH_FAIL; - } -/* - Compute the hash of the cert here for CA validation - */ - switch (cert->certAlgorithm) - { -# ifdef ENABLE_MD5_SIGNED_CERTS -# ifdef USE_MD2 - case OID_MD2_RSA_SIG: - psMd2Init(&hashCtx.md2); - psMd2Update(&hashCtx.md2, tbsCertStart, certLen); - psMd2Final(&hashCtx.md2, cert->sigHash); - break; -# endif /* USE_MD2 */ - case OID_MD5_RSA_SIG: - psMd5Init(&hashCtx.md5); - psMd5Update(&hashCtx.md5, tbsCertStart, certLen); - psMd5Final(&hashCtx.md5, cert->sigHash); - break; -# endif -# ifdef ENABLE_SHA1_SIGNED_CERTS - case OID_SHA1_RSA_SIG: - case OID_SHA1_RSA_SIG2: -# ifdef USE_ECC - case OID_SHA1_ECDSA_SIG: -# endif - psSha1PreInit(&hashCtx.sha1); - psSha1Init(&hashCtx.sha1); - psSha1Update(&hashCtx.sha1, tbsCertStart, certLen); - psSha1Final(&hashCtx.sha1, cert->sigHash); - break; -# endif -# ifdef USE_SHA256 - case OID_SHA256_RSA_SIG: -# ifdef USE_ECC - case OID_SHA256_ECDSA_SIG: -# endif - psSha256PreInit(&hashCtx.sha256); - psSha256Init(&hashCtx.sha256); - psSha256Update(&hashCtx.sha256, tbsCertStart, certLen); - psSha256Final(&hashCtx.sha256, cert->sigHash); - break; -# endif -# ifdef USE_SHA384 - case OID_SHA384_RSA_SIG: -# ifdef USE_ECC - case OID_SHA384_ECDSA_SIG: -# endif - psSha384PreInit(&hashCtx.sha384); - psSha384Init(&hashCtx.sha384); - psSha384Update(&hashCtx.sha384, tbsCertStart, certLen); - psSha384Final(&hashCtx.sha384, cert->sigHash); - break; -# endif -# ifdef USE_SHA512 - case OID_SHA512_RSA_SIG: -# ifdef USE_ECC - case OID_SHA512_ECDSA_SIG: -# endif - psSha512PreInit(&hashCtx.sha512); - psSha512Init(&hashCtx.sha512); - psSha512Update(&hashCtx.sha512, tbsCertStart, certLen); - psSha512Final(&hashCtx.sha512, cert->sigHash); - break; -# endif -# ifdef USE_PKCS1_PSS - case OID_RSASSA_PSS: - switch (cert->pssHash) - { -# ifdef ENABLE_MD5_SIGNED_CERTS - case PKCS1_MD5_ID: - psMd5Init(&hashCtx.md5); - psMd5Update(&hashCtx.md5, tbsCertStart, certLen); - psMd5Final(&hashCtx.md5, cert->sigHash); - break; -# endif -# ifdef ENABLE_SHA1_SIGNED_CERTS - case PKCS1_SHA1_ID: - psSha1PreInit(&hashCtx.sha1); - psSha1Init(&hashCtx.sha1); - psSha1Update(&hashCtx.sha1, tbsCertStart, certLen); - psSha1Final(&hashCtx.sha1, cert->sigHash); - break; -# endif -# ifdef USE_SHA256 - case PKCS1_SHA256_ID: - psSha256PreInit(&hashCtx.sha256); - psSha256Init(&hashCtx.sha256); - psSha256Update(&hashCtx.sha256, tbsCertStart, certLen); - psSha256Final(&hashCtx.sha256, cert->sigHash); - break; -# endif -# ifdef USE_SHA384 - case PKCS1_SHA384_ID: - psSha384PreInit(&hashCtx.sha384); - psSha384Init(&hashCtx.sha384); - psSha384Update(&hashCtx.sha384, tbsCertStart, certLen); - psSha384Final(&hashCtx.sha384, cert->sigHash); - break; -# endif -# ifdef USE_SHA512 - case PKCS1_SHA512_ID: - psSha512PreInit(&hashCtx.sha512); - psSha512Init(&hashCtx.sha512); - psSha512Update(&hashCtx.sha512, tbsCertStart, certLen); - psSha512Final(&hashCtx.sha512, cert->sigHash); - break; -# endif - default: - psTraceIntCrypto("Unsupported pssHash algorithm: %d\n", - cert->pssHash); - cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG; - return PS_UNSUPPORTED_FAIL; - - } /* switch pssHash */ - break; -# endif /* USE_PKCS1_PSS */ - - default: - /* Note 1670:MD2 */ - psTraceIntCrypto("Unsupported cert algorithm: %d\n", - cert->certAlgorithm); - cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG; - return PS_UNSUPPORTED_FAIL; - - } /* switch certAlgorithm */ - - /* 6 empty bytes is plenty enough to know if sigHash didn't calculate */ - if (memcmp(cert->sigHash, "\0\0\0\0\0\0", 6) == 0) - { - psTraceIntCrypto("No library signature alg support for cert: %d\n", - cert->certAlgorithm); - return PS_UNSUPPORTED_FAIL; - } -# endif /* USE_CERT_PARSE */ - - if ((rc = psX509GetSignature(pool, &p, (uint32) (end - p), - &cert->signature, &cert->signatureLen)) < 0) - { - psTraceCrypto("Couldn't parse signature\n"); - cert->parseStatus = PS_X509_SIGNATURE; - return rc; - } - -# ifndef USE_CERT_PARSE - /* Some APIs need certAlgorithm.*/ - cert->certAlgorithm = cert->sigAlgorithm; -# endif /* !USE_CERT_PARSE */ - -/* - The ability to parse additional chained certs is a PKI product - feature addition. Chaining in MatrixSSL is handled internally. - */ - if ((p != far_end) && (p < (far_end + 1))) + An additional sanity check is to ensure that there are least + MIN_CERT_SIZE bytes left in the stream. We wish to avoid + having to call parse_single_cert for any residual garbage + in the stream. + */ + #define MIN_CERT_SIZE 256 + if ((p != far_end) && (p < (far_end + 1)) + && (far_end - p) > MIN_CERT_SIZE) { if (*p == 0x0 && *(p + 1) == 0x0) { @@ -1282,8 +1435,28 @@ int32 psX509ParseCert(psPool_t *pool, const unsigned char *pp, uint32 size, parsing = 0; } } - cert->parseStatus = PS_X509_PARSE_SUCCESS; - return (int32) (p - pp); + + if (numParsedCerts == 0) + return PS_PARSE_FAIL; + + if (flags & CERT_ALLOW_BUNDLE_PARTIAL_PARSE) + { + /* + Return number of successfully parsed certs. + Note: this flag is never set when called from the SSL layer. + */ + psTraceIntCrypto("Parsed %d certs", numParsedCerts); + psTraceIntCrypto(" from a total of %d certs\n", numCerts); + return numParsedCerts; + } + else + { + /* + Return length of parsed DER stream. + Some functions in the SSL layer require this. + */ + return (int32) (p - pp); + } } # ifdef USE_CERT_PARSE @@ -2265,7 +2438,8 @@ static int32_t parseGeneralNames(psPool_t *pool, const unsigned char **buf, p = *buf; end = p + len; - while (len > 0) +# define MIN_GENERALNAME_LEN 3 /* 1 tag, 1 length octet, 1 content octet.*/ + while (len > MIN_GENERALNAME_LEN) { if (firstName == NULL) { @@ -2354,7 +2528,15 @@ static int32_t parseGeneralNames(psPool_t *pool, const unsigned char **buf, } /* TODO - validate *p == STRING type? */ p++; /* Jump over TYPE */ - len -= (p - save); + if (len <= (p - save)) + { + psTraceCrypto("ASN len error in parseGeneralNames\n"); + return PS_PARSE_FAIL; + } + else + { + len -= (p - save); + } break; case GN_EMAIL: strncpy((char *) activeName->name, "email", @@ -2402,7 +2584,15 @@ static int32_t parseGeneralNames(psPool_t *pool, const unsigned char **buf, psTraceCrypto("ASN len error in parseGeneralNames\n"); return PS_PARSE_FAIL; } - len -= (p - save); + if (len <= (p - save)) + { + psTraceCrypto("ASN len error in parseGeneralNames\n"); + return PS_PARSE_FAIL; + } + else + { + len -= (p - save); + } if (len < activeName->dataLen) { psTraceCrypto("ASN len error in parseGeneralNames\n"); @@ -3021,14 +3211,15 @@ int32_t parsePolicyMappings(psPool_t *pool, } p += len; - pol_map->issuerDomainPolicy = psMalloc(pool, len * sizeof(uint32_t)); - memset(pol_map->issuerDomainPolicy, 0, len * sizeof(uint32_t)); + pol_map->issuerDomainPolicy = psMalloc(pool, + oidlen * sizeof(uint32_t)); + memset(pol_map->issuerDomainPolicy, 0, oidlen * sizeof(uint32_t)); for (i = 0; i < oidlen; i++) { pol_map->issuerDomainPolicy[i] = oid[i]; } - pol_map->issuerDomainPolicyLen = len; + pol_map->issuerDomainPolicyLen = oidlen; /* Parse subjectDomainPolicy OID. */ if (*p++ != ASN_OID) @@ -3051,14 +3242,15 @@ int32_t parsePolicyMappings(psPool_t *pool, } p += len; - pol_map->subjectDomainPolicy = psMalloc(pool, len * sizeof(uint32_t)); - memset(pol_map->subjectDomainPolicy, 0, len * sizeof(uint32_t)); + pol_map->subjectDomainPolicy = psMalloc(pool, + oidlen * sizeof(uint32_t)); + memset(pol_map->subjectDomainPolicy, 0, oidlen * sizeof(uint32_t)); for (i = 0; i < oidlen; i++) { pol_map->subjectDomainPolicy[i] = oid[i]; } - pol_map->subjectDomainPolicyLen = len; + pol_map->subjectDomainPolicyLen = oidlen; ++num_mappings; } @@ -4998,7 +5190,7 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, psX509Cert_t *ic, *sc; int32 sigType, rc; uint32 sigLen; - void *rsaData; + void *rsaData = NULL; # ifdef USE_ECC int32 sigStat; @@ -5156,6 +5348,12 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, sigType = RSA_TYPE_SIG; break; # endif +# ifdef USE_SHA224 + case OID_SHA224_RSA_SIG: + sigLen = 10 + SHA224_HASH_SIZE + 9; + sigType = RSA_TYPE_SIG; + break; +# endif # ifdef USE_SHA256 case OID_SHA256_RSA_SIG: sigLen = 10 + SHA256_HASH_SIZE + 9; @@ -5182,6 +5380,12 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, sigType = ECDSA_TYPE_SIG; break; # endif +# ifdef USE_SHA224 + case OID_SHA224_ECDSA_SIG: + sigLen = SHA224_HASH_SIZE; + sigType = ECDSA_TYPE_SIG; + break; +# endif # ifdef USE_SHA256 case OID_SHA256_ECDSA_SIG: sigLen = SHA256_HASH_SIZE; @@ -5216,6 +5420,11 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, sigLen = SHA1_HASH_SIZE; break; # endif +# ifdef USE_SHA224 + case PKCS1_SHA224_ID: + sigLen = SHA224_HASH_SIZE; + break; +# endif # ifdef USE_SHA256 case PKCS1_SHA256_ID: sigLen = SHA256_HASH_SIZE; @@ -5269,8 +5478,6 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, } memcpy(tempSig, sc->signature, sc->signatureLen); - rsaData = NULL; - if ((rc = psRsaDecryptPub(pkiPool, &ic->publicKey.key.rsa, tempSig, sc->signatureLen, sigOut, sigLen, rsaData)) < 0) { @@ -5322,7 +5529,6 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, # ifdef USE_ECC if (sigType == ECDSA_TYPE_SIG) { - rsaData = NULL; if ((rc = psEccDsaVerify(pkiPool, &ic->publicKey.key.ecc, sc->sigHash, sigLen, @@ -5535,6 +5741,15 @@ static int32_t x509ConfirmSignature(const unsigned char *sigHash, } break; # endif +# ifdef USE_SHA224 + case OID_SHA224_ALG: + if (len != SHA224_HASH_SIZE) + { + psTraceCrypto("SHA224_HASH_SIZE error in x509ConfirmSignature\n"); + return PS_LIMIT_FAIL; + } + break; +# endif # ifdef USE_SHA256 case OID_SHA256_ALG: if (len != SHA256_HASH_SIZE) @@ -5840,6 +6055,9 @@ static int32_t ocspParseBasicResponse(psPool_t *pool, uint32_t len, # endif # ifdef USE_SHA384 psSha384_t sha3; +# endif +# ifdef USE_SHA512 + psSha512_t sha512; # endif psSize_t glen, plen; uint32_t blen; @@ -6051,16 +6269,30 @@ static int32_t ocspParseBasicResponse(psPool_t *pool, uint32_t len, case OID_SHA1_ECDSA_SIG: # endif res->hashLen = SHA1_HASH_SIZE; + psSha1PreInit(&sha); psSha1Init(&sha); psSha1Update(&sha, startRes, (int32) (endRes - startRes)); psSha1Final(&sha, res->hashResult); break; +# ifdef USE_SHA224 + case OID_SHA224_RSA_SIG: +# ifdef USE_ECC + case OID_SHA224_ECDSA_SIG: +# endif + res->hashLen = SHA224_HASH_SIZE; + psSha224PreInit(&sha2); + psSha224Init(&sha2); + psSha224Update(&sha2, startRes, (int32) (endRes - startRes)); + psSha224Final(&sha2, res->hashResult); + break; +# endif # ifdef USE_SHA256 case OID_SHA256_RSA_SIG: # ifdef USE_ECC case OID_SHA256_ECDSA_SIG: # endif res->hashLen = SHA256_HASH_SIZE; + psSha256PreInit(&sha2); psSha256Init(&sha2); psSha256Update(&sha2, startRes, (int32) (endRes - startRes)); psSha256Final(&sha2, res->hashResult); @@ -6072,10 +6304,23 @@ static int32_t ocspParseBasicResponse(psPool_t *pool, uint32_t len, case OID_SHA384_ECDSA_SIG: # endif res->hashLen = SHA384_HASH_SIZE; + psSha384PreInit(&sha3); psSha384Init(&sha3); psSha384Update(&sha3, startRes, (int32) (endRes - startRes)); psSha384Final(&sha3, res->hashResult); break; +# endif +# ifdef USE_SHA512 + case OID_SHA512_RSA_SIG: +# ifdef USE_ECC + case OID_SHA512_ECDSA_SIG: +# endif + res->hashLen = SHA512_HASH_SIZE; + psSha512PreInit(&sha512); + psSha512Init(&sha512); + psSha512Update(&sha512, startRes, (int32) (endRes - startRes)); + psSha512Final(&sha512, res->hashResult); + break; # endif default: psTraceCrypto("No support for sigAlg in OCSP ResponseData\n"); @@ -6514,6 +6759,8 @@ static int32_t parseOcspReq(const void *data, size_t datalen, return psParseBufFinish(&ocspRequest); } +#define RESPONDER_NAME_MAX_LENGTH 1024 + static int32_t ocspMatchResponderCert(const psOcspResponse_t *response, const psX509Cert_t *curr) { @@ -6529,12 +6776,15 @@ static int32_t ocspMatchResponderCert(const psOcspResponse_t *response, { uint32_t len; /* Obtain the length of name tag including header. - Note: responderName has already been validated during parsing. */ - const unsigned char *p = response->responderName + 1; - if (getAsnLength32(&p, 4, &len, 0) < 0) - return PS_FAILURE; /* Should not happen. */ + Note: responderName has already been validated during parsing, + so getAsnTagLenUnsafe is ok. + */ + len = getAsnTagLenUnsafe(response->responderName); - len = (uint32_t) (p + len - response->responderName); + if (len < 2 || len > RESPONDER_NAME_MAX_LENGTH) + { + return PS_FAILURE; + } /* Match certificate using subject name. */ if (curr->unparsedBin == NULL || @@ -6809,6 +7059,16 @@ int32_t psOcspResponseValidate(psPool_t *pool, psX509Cert_t *trustedOCSP, /* Finally do the sig validation */ switch (response->sigAlg) { +# ifdef USE_SHA224 + case OID_SHA224_RSA_SIG: + sigOutLen = SHA224_HASH_SIZE; + sigType = PS_RSA; + break; + case OID_SHA224_ECDSA_SIG: + sigOutLen = SHA224_HASH_SIZE; + sigType = PS_ECC; + break; +# endif # ifdef USE_SHA256 case OID_SHA256_RSA_SIG: sigOutLen = SHA256_HASH_SIZE; @@ -6828,6 +7088,16 @@ int32_t psOcspResponseValidate(psPool_t *pool, psX509Cert_t *trustedOCSP, sigOutLen = SHA384_HASH_SIZE; sigType = PS_ECC; break; +# endif +# ifdef USE_SHA512 + case OID_SHA512_RSA_SIG: + sigOutLen = SHA512_HASH_SIZE; + sigType = PS_RSA; + break; + case OID_SHA512_ECDSA_SIG: + sigOutLen = SHA512_HASH_SIZE; + sigType = PS_ECC; + break; # endif case OID_SHA1_RSA_SIG: case OID_SHA1_RSA_SIG2: diff --git a/crypto/keyformat/x509.h b/crypto/keyformat/x509.h index cda303d..ae0092c 100644 --- a/crypto/keyformat/x509.h +++ b/crypto/keyformat/x509.h @@ -64,6 +64,10 @@ enum /* Parsing flags */ # define CERT_STORE_UNPARSED_BUFFER 0x1 # define CERT_STORE_DN_BUFFER 0x2 +/** Allow parsing of a certificate bundle (a concatenated PEM file + or a DER stream) to succeed even when some certs could not be + supported by MatrixSSL. */ +# define CERT_ALLOW_BUNDLE_PARTIAL_PARSE 0x4 # ifdef USE_CERT_PARSE diff --git a/crypto/layer/layer.h b/crypto/layer/layer.h index 04f9b77..381d0c9 100644 --- a/crypto/layer/layer.h +++ b/crypto/layer/layer.h @@ -155,11 +155,14 @@ /* #undef USE_MATRIX_CHACHA20_POLY1305 / * @note, not defined in matrix crypto * / */ # define USE_LIBSODIUM_CHACHA20_POLY1305 # endif - + +/* libsodium AES-GCM is not automatically enabled. + libsodium AES-GCM offers only 256-bit AES-GCM, where as TLS uses 128/256. # ifdef USE_MATRIX_AES_GCM # undef USE_MATRIX_AES_GCM # define USE_LIBSODIUM_AES_GCM # endif +*/ # ifdef USE_MATRIX_SHA256 # undef USE_MATRIX_SHA256 diff --git a/crypto/layer/matrix.c b/crypto/layer/matrix.c index b09fc75..ea06515 100644 --- a/crypto/layer/matrix.c +++ b/crypto/layer/matrix.c @@ -46,34 +46,45 @@ static char g_config[32] = "N"; int32_t psCryptoOpen(const char *config) { uint32_t clen; - + if (*g_config == 'Y') { return PS_SUCCESS; /* Function has been called previously */ } + /* 'config' is cryptoconfig + coreconfig */ - strncpy(g_config, PSCRYPTO_CONFIG, sizeof(g_config) - 1); clen = strlen(PSCRYPTO_CONFIG) - strlen(PSCORE_CONFIG); - if (strncmp(g_config, config, clen) != 0) + if (strncmp(PSCRYPTO_CONFIG, config, clen) != 0) { psErrorStr( "Crypto config mismatch.\n" \ "Library: " PSCRYPTO_CONFIG \ "\nCurrent: %s\n", config); - return -1; + return PS_FAILURE; } if (psCoreOpen(config + clen) < 0) { psError("pscore open failure\n"); return PS_FAILURE; } + #ifdef USE_FLPS_BINDING flps_binding(); + /* Check if FIPS Library Open failed. */ + if ((int)CLS_LibStatus(flps_getCLS()) < 0) + { + return PS_SELFTEST_FAILED; + } #endif /* USE_FLPS_BINDING */ + psOpenPrng(); #ifdef USE_CRL psCrlOpen(); #endif - return 0; + + /* Everything successful, store configuration. */ + strncpy(g_config, PSCRYPTO_CONFIG, sizeof(g_config) - 1); + + return PS_SUCCESS; } void psCryptoClose(void) diff --git a/crypto/pubkey/ecc.c b/crypto/pubkey/ecc.c index 40decab..febeeb8 100644 --- a/crypto/pubkey/ecc.c +++ b/crypto/pubkey/ecc.c @@ -450,6 +450,7 @@ int32_t getEcPubKey(psPool_t *pool, const unsigned char **pp, psSize_t len, Standard form - SHA-1 hash of the value of the BIT STRING subjectPublicKey [excluding the tag, length, and number of unused bits] */ + psSha1PreInit(&dc.sha1); psSha1Init(&dc.sha1); psSha1Update(&dc.sha1, p, arcLen); psSha1Final(&dc.sha1, sha1KeyHash); @@ -464,7 +465,8 @@ int32_t getEcPubKey(psPool_t *pool, const unsigned char **pp, psSize_t len, p += arcLen; *pp = p; - return 0; + + return PS_SUCCESS; } /** diff --git a/crypto/pubkey/pubkey.c b/crypto/pubkey/pubkey.c index b3181de..12ad0af 100644 --- a/crypto/pubkey/pubkey.c +++ b/crypto/pubkey/pubkey.c @@ -119,6 +119,94 @@ void psDeletePubKey(psPubKey_t **key) # ifdef USE_PRIVATE_KEY_PARSING # ifdef MATRIX_USE_FILE_SYSTEM # if defined(USE_ECC) && defined(USE_RSA) +/* + Trial and error private key parse for when ECC or RSA is unknown. + keyBuf must point to a buffer of length keyBufLen, containing + a DER-encoded key. + + Return codes: + 1 RSA key + 2 ECC key + < 0 error + */ +int32_t psParseUnknownPrivKeyMem(psPool_t *pool, + unsigned char *keyBuf, int32 keyBufLen, + const char *password, psPubKey_t *privkey) +{ + psRsaKey_t *rsakey; + psEccKey_t *ecckey; + int32_t keytype = 1; + psBool_t notRsaKey; + + if (keyBuf == NULL || keyBufLen <= 0) + return PS_ARG_FAIL; + + privkey->keysize = 0; + rsakey = &privkey->key.rsa; + ecckey = &privkey->key.ecc; + + /* Examine data to ensure parses which could not succeed are not tried. */ + + /* Guess if this can be RSA key based on length of encoding and content. + Even the smallest (obsolete 512-bit modulus) RSA private keys are > + 256 bytes. + */ + notRsaKey = keyBufLen < 257 || keyBuf[0] != 0x30 || keyBuf[1] < 0x82; + + /* A raw RSAPrivateKey? */ + if (notRsaKey != PS_FALSE || + psRsaParsePkcs1PrivKey(pool, keyBuf, keyBufLen, rsakey) + < PS_SUCCESS) + { + /* A raw ECPrivateKey? */ + if (psEccParsePrivKey(pool, keyBuf, keyBufLen, ecckey, NULL) + < PS_SUCCESS) + { +# ifdef USE_PKCS8 + /* A PKCS #8 PrivateKeyInfo containing an ECPrivateKey? */ + if (psPkcs8ParsePrivBin(pool, keyBuf, keyBufLen, + (char*)password, privkey)) + { +# endif /* USE_PKCS8 */ + /* Nothing worked. */ + psTraceCrypto("Unable to parse private key. " \ + "Supported formats are RSAPrivateKey, " \ + "ECPrivateKey and PKCS #8.\n"); + return PS_FAILURE; +# ifdef USE_PKCS8 + } + if (privkey->type == PS_RSA) + { + keytype = 1; + } + else if (privkey->type == PS_ECC) + { + keytype = 2; + } + goto parsed; +# endif /* USE_PKCS8 */ + } + keytype = 2; + } + +# ifdef USE_PKCS8 +parsed: +# endif /* USE_PKCS8 */ + if (keytype == 1) + { + privkey->type = PS_RSA; + privkey->keysize = psRsaSize(&privkey->key.rsa); + } + else + { + privkey->type = PS_ECC; + privkey->keysize = psEccSize(&privkey->key.ecc); + } + privkey->pool = pool; + + return keytype; +} + /* Trial and error private key parse for when ECC or RSA is unknown. pemOrDer should be 1 if PEM @@ -126,16 +214,18 @@ void psDeletePubKey(psPubKey_t **key) Return codes: 1 RSA key 2 ECC key - -1 error + < 0 error */ -int32_t psParseUnknownPrivKey(psPool_t *pool, int pemOrDer, char *keyfile, - char *password, psPubKey_t *privkey) +int32_t psParseUnknownPrivKey(psPool_t *pool, int pemOrDer, + const char *keyfile, const char *password, + psPubKey_t *privkey) { psRsaKey_t *rsakey; psEccKey_t *ecckey; int keytype = 1; unsigned char *keyBuf; int32 keyBufLen; + int32_t rc; privkey->keysize = 0; rsakey = &privkey->key.rsa; @@ -152,7 +242,7 @@ int32_t psParseUnknownPrivKey(psPool_t *pool, int pemOrDer, char *keyfile, { psTraceStrCrypto("Unable to parse private key file %s\n", keyfile); - return -1; + return PS_FAILURE; } keytype = 2; } @@ -169,61 +259,33 @@ int32_t psParseUnknownPrivKey(psPool_t *pool, int pemOrDer, char *keyfile, psTraceStrCrypto("Unable to open private key file %s\n", keyfile); return -1; } - /* A raw RSAPrivateKey? */ - if (psRsaParsePkcs1PrivKey(pool, keyBuf, keyBufLen, rsakey) - < PS_SUCCESS) + rc = psParseUnknownPrivKeyMem(pool, keyBuf, keyBufLen, password, + privkey); + psFree(keyBuf, pool); + + /* Continue examining result of private key parsing. */ + if (rc < 0) { - /* A raw ECPrivateKey? */ - if (psEccParsePrivKey(pool, keyBuf, keyBufLen, ecckey, NULL) - < PS_SUCCESS) - { -# ifdef USE_PKCS8 - /* A PKCS #8 PrivateKeyInfo containing an ECPrivateKey? */ - if (psPkcs8ParsePrivBin(pool, keyBuf, keyBufLen, password, - privkey)) - { -# endif /* USE_PKCS8 */ - /* Nothing worked. */ - psTraceCrypto("Unable to parse private key. " \ - "Supported formats are RSAPrivateKey, " \ - "ECPrivateKey and PKCS #8.\n"); - psFree(keyBuf, pool); - return -1; - } -# ifdef USE_PKCS8 - if (privkey->type == PS_RSA) - { - keytype = 1; - } - else if (privkey->type == PS_ECC) - { - keytype = 2; - } - goto parsed; -# endif /* USE_PKCS8 */ + psTraceStrCrypto("Unable to parse private key file %s\n", keyfile); + return -1; } - keytype = 2; + keytype = rc; + goto out; /* psParseUnknownPrivKeyMem already set up everything. */ + } + + if (keytype == 1) + { + privkey->type = PS_RSA; + privkey->keysize = psRsaSize(&privkey->key.rsa); } else { - keytype = 1; + privkey->type = PS_ECC; + privkey->keysize = psEccSize(&privkey->key.ecc); } -parsed: - psFree(keyBuf, pool); -} - -if (keytype == 1) -{ - privkey->type = PS_RSA; - privkey->keysize = psRsaSize(&privkey->key.rsa); -} -else -{ - privkey->type = PS_ECC; - privkey->keysize = psEccSize(&privkey->key.ecc); -} -privkey->pool = pool; -return keytype; + privkey->pool = pool; +out: + return keytype; } /* Trial and error public key parse for when ECC or RSA is unknown. @@ -426,6 +488,16 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, psSha1Final(&hash.sha1, hashOut); *hashOutLen = SHA1_HASH_SIZE; break; +#ifdef USE_SHA224 + case OID_SHA224_RSA_SIG: + case OID_SHA224_ECDSA_SIG: + psSha224PreInit(&hash.sha256); + psSha224Init(&hash.sha256); + psSha224Update(&hash.sha256, dataBegin, dataLen); + psSha224Final(&hash.sha256, hashOut); + *hashOutLen = SHA224_HASH_SIZE; + break; +#endif /* USE_SHA224 */ case OID_SHA256_RSA_SIG: case OID_SHA256_ECDSA_SIG: psSha256PreInit(&hash.sha256); @@ -437,7 +509,7 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, # ifdef USE_SHA384 case OID_SHA384_RSA_SIG: case OID_SHA384_ECDSA_SIG: - psSha512PreInit(&hash.sha512); + psSha384PreInit(&hash.sha384); psSha384Init(&hash.sha384); psSha384Update(&hash.sha384, dataBegin, dataLen); psSha384Final(&hash.sha384, hashOut); diff --git a/crypto/pubkey/pubkey.h b/crypto/pubkey/pubkey.h index 1c3da50..36c6f58 100644 --- a/crypto/pubkey/pubkey.h +++ b/crypto/pubkey/pubkey.h @@ -165,7 +165,8 @@ enum PACKED PS_RSA, PS_DSA, PS_ECC, - PS_DH + PS_DH, + PS_CL_PK /* A public key for CL Library. May contain any key format. */ }; /** Signature types */ diff --git a/crypto/test/Makefile b/crypto/test/Makefile index 3a817da..313dee6 100644 --- a/crypto/test/Makefile +++ b/crypto/test/Makefile @@ -17,6 +17,11 @@ VECTOR_EXE:=algorithmTest$(E) SPEED_EXE:=throughputTest$(E) EXE:=$(VECTOR_EXE) $(SPEED_EXE) +CRYPTOOPEN_SRC:=cryptoOpen.c +CRYPTOOPEN_EXE:=cryptoOpen$(E) +SRC+=$(CRYPTOOPEN_SRC) +EXE+=$(CRYPTOOPEN_EXE) + include $(MATRIXSSL_ROOT)/common.mk # Linked files @@ -39,6 +44,9 @@ $(SPEED_EXE): $(SPEED_SRC:.c=.o) $(STATICS) $(VECTOR_EXE): $(VECTOR_SRC:.c=.o) $(STATICS) $(CC) -o $@ $^ $(LDFLAGS) +$(CRYPTOOPEN_EXE): $(CRYPTOOPEN_SRC:.c=.o) $(STATICS) + $(CC) -o $@ $^ $(LDFLAGS) + clean: rm -f $(EXE) $(OBJS) if [ -e rsaperf ]; then $(MAKE) clean --directory=rsaperf;fi diff --git a/crypto/test/algorithmTest.c b/crypto/test/algorithmTest.c index 001b21a..4a77c8f 100644 --- a/crypto/test/algorithmTest.c +++ b/crypto/test/algorithmTest.c @@ -2581,7 +2581,7 @@ int32 psSha224Test(void) int i; unsigned char tmp[28]; - psDigestContext_t md; + psSha256_t md; for (i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i++) { @@ -5286,6 +5286,13 @@ static test_t tests[] = { #endif , "***** SHA1 TESTS *****" }, +#ifdef USE_SHA224 + { psSha224Test +#else + { NULL +#endif + , "***** SHA224 TESTS *****" }, + #ifdef USE_SHA256 { psSha256Test #else diff --git a/crypto/test/cryptoOpen.c b/crypto/test/cryptoOpen.c new file mode 100644 index 0000000..0d82a43 --- /dev/null +++ b/crypto/test/cryptoOpen.c @@ -0,0 +1,55 @@ +#include +#include "crypto/cryptoApi.h" + +int main(void) +{ + psSha256_t md; + int i; + unsigned char out[32 + 2]; + unsigned char txt[3] = { 'a', 'b', 'c' }; + const unsigned char expect[32 + 2] = + { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, + 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad, + 0xfe, 0xfe /* bytes unmodified. */ + }; + unsigned char sum; + psRes_t res; + + memset(out, 0xfe, 32 + 2); + + /* Try opening cryptographic library. */ + res = psCryptoOpen(PSCRYPTO_CONFIG); + if (res == PS_SELFTEST_FAILED) + { + fprintf(stdout, "Library initialization failed: Self-test failure\n"); + return 2; + } + else if (res < PS_SUCCESS) + { + fprintf(stdout, "Library initialization failed\n"); + return 2; + } + + /* Things appear ok. Ensure they are: */ + psSha256PreInit(&md); /* Pre-init before first use. */ + psSha256Init(&md); + psSha256Update(&md, txt, 3); + psSha256Final(&md, out); + + sum = 0; + for(i = 0; i < 32 + 2; i++) + { + sum |= out[i] ^ expect[i]; + } + + if (sum != 0) + { + fprintf(stderr, "Library is broken.\n"); + return 3; + } + + fprintf(stderr, "Successful init.\n"); + return 0; +} diff --git a/crypto/test/cryptoOpenTest.sh b/crypto/test/cryptoOpenTest.sh new file mode 100755 index 0000000..0fc5831 --- /dev/null +++ b/crypto/test/cryptoOpenTest.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +# Try various corruptions on libsafezone-sw-fips.so. +# Intented to be mainly used with CL built with CFLAGS_CLC=-DCLC_VERIFY. + +if [ "X$1" = "X--all" ];then +try_cryptoOpen() +{ + echo -n Default:" " + ./cryptoOpen + ret=$? + if [ X$ret != X0 ]; + then + echo "[Return value: $ret]" + fi + echo -n FL:" " + ./cryptoOpen fl + ret=$? + if [ X$ret != X0 ]; + then + echo "[Return value: $ret]" + fi + echo -n SL:" " + ./cryptoOpen sl + ret=$? + if [ X$ret != X0 ]; + then + echo "[Return value: $ret]" + fi +} +elif [ "X$1" = "X" ];then + try_cryptoOpen() + { + ./cryptoOpen + ret=$? + if [ X$ret != X0 ]; + then + echo "[Return value: $ret]" + fi + } +else + echo "Usage: $0 [--all]" >&2 + exit 1 +fi + +unset NO_SAFEZONE_FIPS + +echo "*** TEST CASE #1: FL File does not exist" +unset LD_LIBRARY_PATH +try_cryptoOpen + +echo "*** TEST CASE #2: Empty LD_LIBRARY_PATH" +export LD_LIBRARY_PATH= +try_cryptoOpen + +rm -rf /tmp/x86-64-libs +mkdir /tmp/x86-64-libs \ + /tmp/x86-64-libs/{nocheck,pad,corrupt1,corrupt2,corrupt_chk,wrong_chk,check} + +echo "*** TEST CASE #3: No checksum" +LIBDIR=/tmp/x86-64-libs/nocheck +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +try_cryptoOpen + +echo "*** TEST CASE #4: Extraneous data in library file." +LIBDIR=/tmp/x86-64-libs/pad +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +../check-lib/create-check-lib.sh $LIBFILE >/dev/null 2>/dev/null +head -c 1024 /dev/zero >>$LIBFILE # Append block of zero bytes +try_cryptoOpen + +echo "*** TEST CASE #5: Corrupt FIPS Library .so file" +LIBDIR=/tmp/x86-64-libs/corrupt1 +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +../check-lib/create-check-lib.sh $LIBFILE >/dev/null 2>/dev/null +dd if=/dev/zero of=$LIBFILE oflag=seek_bytes seek=4096 bs=1M count=1 # Alter large block of file. +try_cryptoOpen + +echo "*** TEST CASE #6: Corrupt [bus error] FIPS Library .so file" +LIBDIR=/tmp/x86-64-libs/corrupt2 +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +../check-lib/create-check-lib.sh $LIBFILE >/dev/null 2>/dev/null +dd if=/dev/zero of=$LIBFILE oflag=seek_bytes seek=2251216 bs=2048 count=1 # Alter a block at critical part of file. +try_cryptoOpen + +echo "*** TEST CASE #7: Corrupt checksum file" +LIBDIR=/tmp/x86-64-libs/corrupt_chk +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +../check-lib/create-check-lib.sh $LIBFILE >/dev/null 2>/dev/null +dd if=/dev/zero of="$LIBFILE".check bs=16 count=1 +try_cryptoOpen + +echo "*** TEST CASE #8: Wrong checksum file" +LIBDIR=/tmp/x86-64-libs/wrong_chk +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/i686-linux-gnu/libsafezone-sw-fips.so $LIBFILE +../check-lib/create-check-lib.sh $LIBFILE >/dev/null 2>/dev/null +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +dd if=/dev/zero of="$LIBFILE".check bs=16 count=1 +try_cryptoOpen + +echo "*** TEST CASE #9: All ok test case." +LIBDIR=/tmp/x86-64-libs/check +LIBFILE=$LIBDIR/libsafezone-sw-fips.so +export LD_LIBRARY_PATH=$LIBDIR +cp -r ../../../FIPSLib11/lib/x86_64-linux-gnu/libsafezone-sw-fips.so $LIBFILE +../check-lib/create-check-lib.sh $LIBFILE >/dev/null 2>/dev/null +try_cryptoOpen diff --git a/crypto/test/ocspTest.c b/crypto/test/ocspTest.c new file mode 100644 index 0000000..93717f9 --- /dev/null +++ b/crypto/test/ocspTest.c @@ -0,0 +1,565 @@ +/* ocspTest.c + * + * Test OCSP APIs. + */ + +/***************************************************************************** +* Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved. +* +* This confidential and proprietary software may be used only as authorized +* by a licensing agreement from INSIDE Secure. +* +* The entire notice above must be reproduced on all authorized copies that +* may only be made to the extent permitted by a licensing agreement from +* INSIDE Secure. +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "crypto/cryptoApi.h" +#include "core/coreApi.h" + +#include "ocspTestData.h" + +#define MAX_EXTRA_INFO 128 +typedef enum { OK, FAILED, WEAK, SKIPPED } TEST_RESULT; + +int write_debug_files; + +# define NOT_SUPPORTED(func_proto) func_proto { \ + return failf("Functionality is currently missing"); \ +} \ + extern int require_semicolon[1] + +static char extra_info[MAX_EXTRA_INFO]; + +int test(int condition) +{ + /* This function is provided as convenience for setting + breakpoint(s). */ + return condition; +} + +int fail(void) +{ + /* This function is provided as convenience for setting + breakpoint(s). */ + return FAILED; +} + +int failf(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + vsnprintf(extra_info, sizeof(extra_info), fmt, va); + va_end(va); + return FAILED; +} + +int okf(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + vsnprintf(extra_info, sizeof(extra_info), fmt, va); + va_end(va); + return OK; +} + +int fail_at(const char *file, int line, const char *cond) +{ + /* This function is provided as convenience for setting + breakpoint(s) and for debug output. */ + fprintf(stderr, "Failure detected at %s:%d: %s\n", file, line, cond); + return fail(); +} + +#define FAIL_IF(condition) \ + do { \ + if (test(condition)) { \ + return fail_at(__FILE__, __LINE__, #condition); } \ + } while (0) + +/* Check existance of function. Fails if the function does not exist. */ +#define CHECK_EXISTS(fun) \ + do { \ + void *ptr = &fun; \ + if (!ptr) { \ + return failf("Unable to locate function "#fun "\n"); \ + } \ + } while (0) + +/* #define VERBOSE(...) do { printf(__VA_ARGS__); } */ +#define VERBOSE(...) do { } while (0) + +/* Give alias (alternative name) for function. */ +#define TEST_ALT_NAME(new_name, old_name) \ + TEST_RESULT new_name(void) \ + { \ + return old_name(); \ + } \ + TEST_RESULT new_name(void) + +/* Test is intended to run only once and cache the results. + This is to be used TEST_ALT_NAME(). + Warning: this macro may call return (i.e. affect control flow). */ +#define TEST_ONCE(fun) \ + do \ + { \ + static unsigned long long test_once_called_times = 0; \ + static TEST_RESULT test_once_result_cached = SKIPPED; \ + test_once_called_times ++; \ + \ + switch (test_once_called_times) \ + { \ + case 1: \ + /* Ensure correct function name used. */ \ + assert(strcmp(#fun, __func__) == 0); \ + test_once_result_cached = fun (); \ + /* fall-through */ \ + default: \ + return test_once_result_cached; \ + case 2: \ + /* actual execution of the function. */ \ + break; \ + } \ + } while (0) \ + +void opt_WRITE_FILE(const char *target, + const void *data, + size_t data_length) +{ + FILE *f; + + if (!write_debug_files) + { + return; /* Do not produce debugging files. */ + } + + f = fopen(target, "w"); + if (f) + { + if (fwrite(data, data_length, 1, f) != 1) + { + fprintf(stderr, "write error\n"); + exit(1); + } + fprintf(stderr, "(Written %lu data bytes to %s)\n", + (long unsigned int) data_length, target); + } + fclose(f); +} + +TEST_RESULT TEST_psOcspRequestWrite(void) +{ + psRes_t res; + psX509Cert_t *revoked_psX509certificate; + psX509Cert_t *issuer_psX509certificate; + uint32 requestLen; + unsigned char *request = NULL; + + res = psX509ParseCert( + NULL, + revoked_certificate, + sizeof revoked_certificate, + &revoked_psX509certificate, 0); + FAIL_IF(res < 0); + res = psX509ParseCert( + NULL, + intermediate_certificate, + sizeof intermediate_certificate, + &issuer_psX509certificate, 0); + FAIL_IF(res < 0); + res = psOcspRequestWrite(MATRIX_NO_POOL, + revoked_psX509certificate, + issuer_psX509certificate, + &request, &requestLen, NULL); + FAIL_IF(res < 0); + opt_WRITE_FILE("/tmp/request", request, requestLen); + FAIL_IF(memcmp(request, ocsp_request, sizeof ocsp_request) != 0); + psX509FreeCert(revoked_psX509certificate); + psX509FreeCert(issuer_psX509certificate); + psFree(request, MATRIX_NO_POOL); + return OK; +} + +TEST_RESULT TEST_psOcspParseResponse(void) +{ + psRes_t res; + psX509Cert_t *revoked_psX509certificate; + psX509Cert_t *issuer_psX509certificate; + unsigned char *p = ocsp_response; + int resp_len = ocsp_response_len; + int32_t res32; + psOcspResponse_t response; + + res = psX509ParseCert( + NULL, + revoked_certificate, + sizeof revoked_certificate, + &revoked_psX509certificate, 0); + FAIL_IF(res < 0); + res = psX509ParseCert( + NULL, + intermediate_certificate, + sizeof intermediate_certificate, + &issuer_psX509certificate, 0); + FAIL_IF(res < 0); + + res32 = psOcspParseResponse(NULL, resp_len, &p, p + resp_len, + &response); + FAIL_IF(res32 < 0); + FAIL_IF(psOcspResponseGetStatus(res32) != 0); + psOcspResponseUninit(&response); + psX509FreeCert(revoked_psX509certificate); + psX509FreeCert(issuer_psX509certificate); + return OK; +} + +TEST_RESULT TEST_psOcspResponseCheckDatesCommon( + unsigned char *p, + int resp_len, + psRes_t res_expect, + struct tm *timeNow_p, + struct tm *ProducedAt_p, + struct tm *thisUpdate_p, + struct tm *nextUpdate_p) +{ + psRes_t res; + psX509Cert_t *revoked_psX509certificate; + psX509Cert_t *issuer_psX509certificate; + int32_t res32; + psOcspResponse_t response; + int32 index = 0; + + res = psX509ParseCert( + NULL, + revoked_certificate, + sizeof revoked_certificate, + &revoked_psX509certificate, 0); + FAIL_IF(res < 0); + res = psX509ParseCert( + NULL, + intermediate_certificate, + sizeof intermediate_certificate, + &issuer_psX509certificate, 0); + FAIL_IF(res < 0); + + res32 = psOcspParseResponse(NULL, resp_len, &p, p + resp_len, + &response); + FAIL_IF(res32 < 0); + res32 = psOcspResponseCheckDates(&response, + index, + timeNow_p, + ProducedAt_p, + thisUpdate_p, + nextUpdate_p, + PS_OCSP_TIME_LINGER); + + FAIL_IF(res32 != res_expect); + psOcspResponseUninit(&response); + psX509FreeCert(revoked_psX509certificate); + psX509FreeCert(issuer_psX509certificate); + return OK; +} + +TEST_RESULT TEST_psOcspResponseCheckDates(void) +{ + struct tm timeNow = { 0 }; + struct tm ProducedAt = { 0 }; + struct tm thisUpdate = { 0 }; + struct tm nextUpdate = { 0 }; + TEST_RESULT res; + + res = TEST_psOcspResponseCheckDatesCommon( + ocsp_response, + ocsp_response_len, + PS_SUCCESS, + &timeNow, + &ProducedAt, + &thisUpdate, + &nextUpdate); + + if (res == OK) + { + FAIL_IF( + ProducedAt.tm_year != 117 || + ProducedAt.tm_mon != 2 || + ProducedAt.tm_mday != 27 || + ProducedAt.tm_hour != 6 || + ProducedAt.tm_min != 0 || + ProducedAt.tm_sec != 0); + + FAIL_IF( + thisUpdate.tm_year != 117 || + thisUpdate.tm_mon != 2 || + thisUpdate.tm_mday != 27 || + thisUpdate.tm_hour != 6 || + thisUpdate.tm_min != 0 || + thisUpdate.tm_sec != 0); + + FAIL_IF( + nextUpdate.tm_year != 117 || + nextUpdate.tm_mon != 2 || + nextUpdate.tm_mday != 27 || + nextUpdate.tm_hour != 6 || + nextUpdate.tm_min != 5 || + nextUpdate.tm_sec != 0); + } + return res; +} + +TEST_RESULT TEST_psOcspResponseCheckDates_future(void) +{ + struct tm timeNow = { 0 }; + struct tm ProducedAt = { 0 }; + struct tm thisUpdate = { 0 }; + struct tm nextUpdate = { 0 }; + TEST_RESULT res; + + res = TEST_psOcspResponseCheckDatesCommon( + ocsp_response_future, + ocsp_response_future_len, + PS_TIMEOUT_FAIL, + &timeNow, + &ProducedAt, + &thisUpdate, + &nextUpdate); + + if (res == OK) + { + FAIL_IF( + ProducedAt.tm_year != 117 || + ProducedAt.tm_mon != 2 || + ProducedAt.tm_mday != 28 || + ProducedAt.tm_hour != 4 || + ProducedAt.tm_min != 13 || + ProducedAt.tm_sec != 8); + + FAIL_IF( + thisUpdate.tm_year != 117 || + thisUpdate.tm_mon != 2 || + thisUpdate.tm_mday != 28 || + thisUpdate.tm_hour != 4 || + thisUpdate.tm_min != 13 || + thisUpdate.tm_sec != 8); + + FAIL_IF( + nextUpdate.tm_year != 117 || + nextUpdate.tm_mon != 2 || + nextUpdate.tm_mday != 28 || + nextUpdate.tm_hour != 4 || + nextUpdate.tm_min != 18 || + nextUpdate.tm_sec != 8); + } + return res; +} + +TEST_RESULT TEST_psOcspResponseValidateCommon( + unsigned char *p, + int resp_len, + psRes_t res_expect, + psValidateOCSPResponseOptions_t *opts_p) +{ + psRes_t res; + psX509Cert_t *revoked_psX509certificate; + psX509Cert_t *issuer_psX509certificate; + int32_t res32; + psOcspResponse_t response; + + res = psX509ParseCert( + NULL, + revoked_certificate, + sizeof revoked_certificate, + &revoked_psX509certificate, 0); + FAIL_IF(res < 0); + res = psX509ParseCert( + NULL, + intermediate_certificate, + sizeof intermediate_certificate, + &issuer_psX509certificate, 0); + FAIL_IF(res < 0); + + res32 = psOcspParseResponse(NULL, resp_len, &p, p + resp_len, + &response); + FAIL_IF(res32 < 0); + res32 = psOcspResponseValidate( + NULL, + issuer_psX509certificate, + revoked_psX509certificate, + &response, + opts_p); + FAIL_IF(res32 != res_expect); + psOcspResponseUninit(&response); + psX509FreeCert(revoked_psX509certificate); + psX509FreeCert(issuer_psX509certificate); + return OK; +} + +TEST_RESULT TEST_psOcspResponseValidate(void) +{ + return TEST_psOcspResponseValidateCommon( + ocsp_response, + ocsp_response_len, + PS_CERT_AUTH_FAIL_REVOKED, + NULL); +} + +TEST_RESULT TEST_psOcspResponseValidate_future(void) +{ + return TEST_psOcspResponseValidateCommon( + ocsp_response_future, + ocsp_response_future_len, + PS_FAILURE, /* The response is invalid (in future). */ + NULL); +} + +TEST_RESULT TEST_psOcspResponseValidate_sha512(void) +{ + return TEST_psOcspResponseValidateCommon( + ocsp_response_sha512, + ocsp_response_sha512_len, + PS_CERT_AUTH_FAIL_REVOKED, + NULL); +} + +int test_match(int argc, char **argv, const char *string) +{ + int i; + + if (argc == 1) + { + return 1; + } + + for (i = 1; i < argc; i++) + { + if (argv[i] != NULL && !strcmp(argv[i], string)) + { + argv[i] = NULL; + return 1; + } + } + + return 0; +} + +#define TEST(fun) \ + do { \ + int res; \ + if (argc == 2 && argv[1] != NULL && \ + !strcmp(argv[1], "--list")) { \ + printf("%s\n", #fun); \ + break; \ + } else if (test_match(argc, argv, #fun)) { \ + printf("%s ... ", #fun); \ + fflush(stdout); \ + res = fun(); \ + counter[(int) res]++; \ + printf("%s%s%s%s\n", res == OK ? "OK" : \ + res == WEAK ? "OK (but size considered weak)" : \ + res == SKIPPED ? "OK (not supported)" : \ + "FAILED", extra_info[0] ? " (" : "", extra_info, \ + extra_info[0] ? ")" : ""); \ + extra_info[0] = 0; \ + } \ + } while (0) + +int main(int argc, char **argv) +{ + int counter[4] = { 0, 0, 0, 0 }; + int do_list = 0; + + time_t currentTime = time(NULL); + if (currentTime < 1490594400 || currentTime > 1490594420) + { + fprintf(stderr, "This test is designed to run via faketime.\n" + "Please set time to 2017-03-27 09:00:00 EET.\n"); + exit(1); + } + +#ifdef USE_MTRACE + if (getenv("MALLOC_TRACE")) + { + mtrace(); + } +#endif /* USE_MTRACE */ + + if (argc == 2 && !strcmp(argv[1], "--list")) + { + printf("Tests available:\n"); + do_list = 1; + } + else + { + printf("Testing OCSP:\n"); + } + + /* Init the MatrixSSL's crypto library */ + if (psCryptoOpen(PSCRYPTO_CONFIG) < PS_SUCCESS) + { + fprintf(stderr, "psCryptoOpen failed: unable to test ocsp.\n"); + exit(1); + } + +/* Template: TEST(TEST_function); */ + + TEST(TEST_psOcspRequestWrite); + TEST(TEST_psOcspParseResponse); + TEST(TEST_psOcspResponseCheckDates); + TEST(TEST_psOcspResponseCheckDates_future); + TEST(TEST_psOcspResponseValidate); + TEST(TEST_psOcspResponseValidate_future); + TEST(TEST_psOcspResponseValidate_sha512); + + /* Add test invocations here... */ + +#ifdef USE_MTRACE + if (getenv("MALLOC_TRACE")) + { + muntrace(); + } +#endif /* USE_MTRACE */ + + psCryptoClose(); + + if (do_list) + { + return 0; + } + + counter[(int) OK] += counter[(int) WEAK]; + { + int counter_sum = counter[(int) OK] + counter[(int) WEAK] + + counter[(int) FAILED] + counter[(int) SKIPPED]; + printf("Ok tests: %d/%d\n", counter[(int) OK], counter_sum); + if (counter[(int) WEAK]) + { + printf("... %d of Ok tests resulted \"WEAK security\" warning\n", + counter[(int) WEAK]); + } + if (counter[(int) FAILED]) + { + printf("Failed tests: %d/%d\n", counter[(int) FAILED], counter_sum); + } + if (counter[(int) SKIPPED]) + { + printf("Skipped tests: %d/%d\n", counter[(int) SKIPPED], + counter_sum); + } + } + counter[(int) OK] += counter[(int) SKIPPED]; + return counter[(int) OK] == 0 || counter[(int) FAILED] != 0; +} + + +/* end of file ocspTest.c */ + + diff --git a/crypto/test/ocspTestData.h b/crypto/test/ocspTestData.h new file mode 100644 index 0000000..0d97ec5 --- /dev/null +++ b/crypto/test/ocspTestData.h @@ -0,0 +1,950 @@ +/* ocspTestData.h + * + * Large inlined data containing keys and certificates and OCSP messages. + */ + +/***************************************************************************** +* Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved. +* +* This confidential and proprietary software may be used only as authorized +* by a licensing agreement from INSIDE Secure. +* +* The entire notice above must be reproduced on all authorized copies that +* may only be made to the extent permitted by a licensing agreement from +* INSIDE Secure. +*****************************************************************************/ + +#ifndef OCSP_TEST_DATA_H +#define OCSP_TEST_DATA_H 1 +#else +#error "ocspTestData.h multiply included" +#endif /* OCSP_TEST_DATA_H */ + +/* subject:/C=FI/ST=Uusimaa/L=Helsinki/O=INSIDE Secure Oy/OU=INSIDE Secure Test/CN=revoked.example.com/emailAddress=support@matrixssl.org */ +/* issuer :/C=FI/ST=Uusimaa/O=INSIDE Secure Oy/OU=INSIDE Secure Test Certificate Authority/CN=INSIDE Secure Test Intermediate CA/emailAddress=support@matrixssl.org */ +unsigned char revoked_subject_name[177]={ +0x30,0x81,0xAE,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49, +0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75,0x73,0x69,0x6D, +0x61,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x48,0x65,0x6C, +0x73,0x69,0x6E,0x6B,0x69,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x0C,0x10, +0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x4F,0x79, +0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x0B,0x0C,0x12,0x49,0x4E,0x53,0x49,0x44, +0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x31,0x1C,0x30, +0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x72,0x65,0x76,0x6F,0x6B,0x65,0x64,0x2E, +0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x24,0x30,0x22,0x06, +0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x15,0x73,0x75,0x70,0x70, +0x6F,0x72,0x74,0x40,0x6D,0x61,0x74,0x72,0x69,0x78,0x73,0x73,0x6C,0x2E,0x6F,0x72, +0x67, +}; +unsigned char revoked_public_key[294]={ +0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, +0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01, +0x00,0xCB,0x6F,0xE7,0xE8,0x91,0xC8,0xBF,0xA2,0x87,0xDD,0x72,0x4C,0x99,0x66,0xB2, +0xEE,0x92,0xDD,0x40,0x4A,0xB0,0xDA,0x71,0x77,0x32,0x95,0xD8,0x3F,0x7B,0xC9,0x69, +0xD7,0xA4,0x64,0x6E,0xB8,0x0F,0xFE,0x74,0x8F,0xEB,0xF2,0xD4,0x27,0x11,0xE5,0x38, +0x0C,0x50,0x3C,0xC8,0x6B,0x5F,0x95,0x8D,0x79,0xB1,0xBE,0xBE,0x0D,0x66,0x3F,0xB4, +0x32,0x2D,0x8E,0x2C,0x3B,0x43,0xEE,0x48,0xC2,0x38,0x41,0x15,0xC2,0xC3,0x8B,0xB8, +0x3C,0x1D,0x9C,0x69,0xE7,0x30,0x37,0xD9,0x55,0xFE,0x20,0x99,0xB2,0x0B,0xC1,0x4F, +0xA4,0x6D,0x44,0xF2,0x7E,0x17,0x21,0x27,0x79,0xE9,0x11,0x4E,0x4E,0xA3,0x6B,0x17, +0x33,0x74,0x63,0x98,0x49,0x87,0xB5,0x73,0xD0,0xBC,0x1E,0x99,0xB4,0x09,0x6E,0xE0, +0xC9,0x69,0x1D,0xCD,0xC5,0x7F,0x5E,0x96,0x7B,0xC2,0x61,0xA3,0xF1,0x19,0x51,0x4F, +0x1F,0xB1,0x07,0x28,0x49,0x0A,0x7A,0x8A,0xF7,0x52,0xC2,0x77,0x91,0x4B,0x76,0xC0, +0x8B,0x8B,0x99,0x78,0x47,0x4C,0x7C,0x05,0xE9,0x1A,0x55,0xA9,0xA1,0xAA,0xCA,0x1F, +0x5A,0x8A,0x46,0x66,0x53,0x59,0x22,0x2F,0x69,0xC4,0xBD,0xA5,0x33,0x4D,0xA4,0x39, +0x85,0x90,0xEC,0x46,0xF4,0xBA,0x83,0x1E,0x6A,0x20,0x33,0x74,0xA0,0x15,0x0F,0x9D, +0xA4,0x0C,0xDC,0x4F,0xED,0xDF,0x01,0x2A,0x93,0xF3,0x45,0xE6,0x31,0x51,0x34,0xD1, +0xCE,0x2D,0x89,0xA1,0x3D,0x02,0xA3,0x7A,0xB1,0x76,0x46,0x7D,0xED,0xEB,0x60,0xF7, +0xF3,0x4F,0xCE,0x16,0x90,0x2D,0x44,0x92,0x83,0xF4,0x44,0x5B,0xD4,0x0A,0x76,0x54, +0xDD,0x02,0x03,0x01,0x00,0x01, +}; +unsigned char revoked_certificate[1676]={ +0x30,0x82,0x06,0x88,0x30,0x82,0x04,0x70,0xA0,0x03,0x02,0x01,0x02,0x02,0x02,0x10, +0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, +0x30,0x81,0xC0,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49, +0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75,0x73,0x69,0x6D, +0x61,0x61,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x0C,0x10,0x49,0x4E,0x53, +0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x4F,0x79,0x31,0x31,0x30, +0x2F,0x06,0x03,0x55,0x04,0x0B,0x0C,0x28,0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53, +0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x65,0x72,0x74,0x69, +0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, +0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x49,0x4E,0x53,0x49,0x44, +0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x49,0x6E, +0x74,0x65,0x72,0x6D,0x65,0x64,0x69,0x61,0x74,0x65,0x20,0x43,0x41,0x31,0x24,0x30, +0x22,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x15,0x73,0x75, +0x70,0x70,0x6F,0x72,0x74,0x40,0x6D,0x61,0x74,0x72,0x69,0x78,0x73,0x73,0x6C,0x2E, +0x6F,0x72,0x67,0x30,0x1E,0x17,0x0D,0x31,0x36,0x30,0x38,0x32,0x39,0x30,0x35,0x35, +0x37,0x35,0x30,0x5A,0x17,0x0D,0x32,0x30,0x31,0x30,0x30,0x37,0x30,0x35,0x35,0x37, +0x35,0x30,0x5A,0x30,0x81,0xAE,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, +0x02,0x46,0x49,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75, +0x73,0x69,0x6D,0x61,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08, +0x48,0x65,0x6C,0x73,0x69,0x6E,0x6B,0x69,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, +0x0A,0x0C,0x10,0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65, +0x20,0x4F,0x79,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x0B,0x0C,0x12,0x49,0x4E, +0x53,0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74, +0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x72,0x65,0x76,0x6F,0x6B, +0x65,0x64,0x2E,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x31,0x24, +0x30,0x22,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x15,0x73, +0x75,0x70,0x70,0x6F,0x72,0x74,0x40,0x6D,0x61,0x74,0x72,0x69,0x78,0x73,0x73,0x6C, +0x2E,0x6F,0x72,0x67,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, +0x02,0x82,0x01,0x01,0x00,0xCB,0x6F,0xE7,0xE8,0x91,0xC8,0xBF,0xA2,0x87,0xDD,0x72, +0x4C,0x99,0x66,0xB2,0xEE,0x92,0xDD,0x40,0x4A,0xB0,0xDA,0x71,0x77,0x32,0x95,0xD8, +0x3F,0x7B,0xC9,0x69,0xD7,0xA4,0x64,0x6E,0xB8,0x0F,0xFE,0x74,0x8F,0xEB,0xF2,0xD4, +0x27,0x11,0xE5,0x38,0x0C,0x50,0x3C,0xC8,0x6B,0x5F,0x95,0x8D,0x79,0xB1,0xBE,0xBE, +0x0D,0x66,0x3F,0xB4,0x32,0x2D,0x8E,0x2C,0x3B,0x43,0xEE,0x48,0xC2,0x38,0x41,0x15, +0xC2,0xC3,0x8B,0xB8,0x3C,0x1D,0x9C,0x69,0xE7,0x30,0x37,0xD9,0x55,0xFE,0x20,0x99, +0xB2,0x0B,0xC1,0x4F,0xA4,0x6D,0x44,0xF2,0x7E,0x17,0x21,0x27,0x79,0xE9,0x11,0x4E, +0x4E,0xA3,0x6B,0x17,0x33,0x74,0x63,0x98,0x49,0x87,0xB5,0x73,0xD0,0xBC,0x1E,0x99, +0xB4,0x09,0x6E,0xE0,0xC9,0x69,0x1D,0xCD,0xC5,0x7F,0x5E,0x96,0x7B,0xC2,0x61,0xA3, +0xF1,0x19,0x51,0x4F,0x1F,0xB1,0x07,0x28,0x49,0x0A,0x7A,0x8A,0xF7,0x52,0xC2,0x77, +0x91,0x4B,0x76,0xC0,0x8B,0x8B,0x99,0x78,0x47,0x4C,0x7C,0x05,0xE9,0x1A,0x55,0xA9, +0xA1,0xAA,0xCA,0x1F,0x5A,0x8A,0x46,0x66,0x53,0x59,0x22,0x2F,0x69,0xC4,0xBD,0xA5, +0x33,0x4D,0xA4,0x39,0x85,0x90,0xEC,0x46,0xF4,0xBA,0x83,0x1E,0x6A,0x20,0x33,0x74, +0xA0,0x15,0x0F,0x9D,0xA4,0x0C,0xDC,0x4F,0xED,0xDF,0x01,0x2A,0x93,0xF3,0x45,0xE6, +0x31,0x51,0x34,0xD1,0xCE,0x2D,0x89,0xA1,0x3D,0x02,0xA3,0x7A,0xB1,0x76,0x46,0x7D, +0xED,0xEB,0x60,0xF7,0xF3,0x4F,0xCE,0x16,0x90,0x2D,0x44,0x92,0x83,0xF4,0x44,0x5B, +0xD4,0x0A,0x76,0x54,0xDD,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x9A,0x30,0x82, +0x01,0x96,0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x11,0x06, +0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40, +0x30,0x33,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,0x04,0x26,0x16, +0x24,0x4F,0x70,0x65,0x6E,0x53,0x53,0x4C,0x20,0x47,0x65,0x6E,0x65,0x72,0x61,0x74, +0x65,0x64,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66, +0x69,0x63,0x61,0x74,0x65,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14, +0x71,0x00,0x98,0x99,0x35,0x07,0xBB,0xA0,0xA3,0xF9,0x30,0x4C,0x6E,0x21,0x13,0x7B, +0x8F,0xCB,0x2B,0x64,0x30,0x81,0xB8,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xB0,0x30, +0x81,0xAD,0x80,0x14,0x64,0x15,0xE2,0x5E,0x3E,0x88,0x1A,0xDD,0x6D,0x29,0x3D,0x1A, +0xE5,0x74,0xE2,0xDB,0x4F,0xF3,0x06,0xB4,0xA1,0x81,0x90,0xA4,0x81,0x8D,0x30,0x81, +0x8A,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49,0x31,0x10, +0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75,0x73,0x69,0x6D,0x61,0x61, +0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x48,0x65,0x6C,0x73,0x69, +0x6E,0x6B,0x69,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x0C,0x10,0x49,0x4E, +0x53,0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x4F,0x79,0x31,0x15, +0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, +0x6F,0x74,0x20,0x43,0x41,0x31,0x24,0x30,0x22,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, +0x0D,0x01,0x09,0x01,0x16,0x15,0x73,0x75,0x70,0x70,0x6F,0x72,0x74,0x40,0x6D,0x61, +0x74,0x72,0x69,0x78,0x73,0x73,0x6C,0x2E,0x6F,0x72,0x67,0x82,0x02,0x10,0x00,0x30, +0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30, +0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x30,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05, +0x05,0x07,0x03,0x01,0x30,0x42,0x06,0x03,0x55,0x1D,0x1F,0x04,0x3B,0x30,0x39,0x30, +0x37,0xA0,0x35,0xA0,0x33,0x86,0x31,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x69,0x6E, +0x73,0x69,0x64,0x65,0x73,0x65,0x63,0x75,0x72,0x65,0x2D,0x74,0x65,0x73,0x74,0x2E, +0x63,0x6F,0x6D,0x2F,0x69,0x6E,0x74,0x65,0x72,0x6D,0x65,0x64,0x69,0x61,0x74,0x65, +0x2E,0x63,0x72,0x6C,0x2E,0x70,0x65,0x6D,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x04,0x9C,0x8F,0xB6, +0x23,0x70,0x3F,0x2A,0x1F,0x50,0x96,0x87,0x4F,0xFD,0xCD,0xCE,0x68,0x68,0xA0,0xF9, +0xD4,0xD3,0xB2,0xD6,0xB2,0x5C,0x14,0x6A,0x32,0x23,0xC5,0x62,0x3C,0x90,0x5E,0xAF, +0x25,0x70,0xA3,0xA4,0x65,0xF3,0x3C,0xBB,0xB4,0xF6,0xC1,0x1F,0x1B,0x45,0xE3,0xA7, +0xF7,0x24,0xA4,0x4F,0x69,0x61,0x39,0xD4,0xCC,0x4B,0x04,0x52,0x90,0xA0,0xE8,0x1E, +0xD1,0xAC,0xE7,0x50,0x7D,0x55,0xD2,0x72,0x70,0x20,0xF7,0xF2,0x4C,0xB7,0x17,0xF7, +0x6E,0xA6,0xEA,0xEC,0x4E,0x41,0x51,0x5A,0x4A,0xB2,0x3E,0x0C,0xF8,0xDD,0xD2,0x1F, +0x8A,0xCE,0xC8,0xBE,0x4F,0x56,0x06,0xB0,0x19,0x9E,0x6C,0x28,0x39,0x6B,0xE0,0xD3, +0x06,0x87,0x31,0x75,0x72,0x71,0x4A,0xB2,0xEB,0xD6,0x74,0xC9,0x74,0xE5,0x40,0xA0, +0xB1,0xFE,0xB7,0x8A,0xC8,0x53,0x6C,0x04,0x65,0x56,0x8E,0xF9,0x01,0xA4,0xC3,0x1C, +0x0F,0xD5,0x04,0xB8,0xF5,0x43,0x40,0x6D,0xE9,0x15,0xBE,0xB7,0x2E,0x72,0xD1,0xED, +0x04,0xFF,0x73,0xF7,0xBC,0x15,0x98,0x13,0xC6,0x02,0xA4,0x01,0x61,0xAC,0x25,0xE2, +0xC5,0x81,0xE9,0x48,0x0F,0x1F,0x09,0x95,0x35,0xCC,0x3C,0x9B,0x03,0xE2,0xD9,0x6A, +0xD6,0x49,0x3B,0xDA,0xA2,0x95,0xC1,0xE0,0x16,0xAE,0x4A,0x94,0xA9,0xCB,0x15,0x46, +0xD0,0x3D,0x93,0xA1,0xDF,0x3B,0xDF,0x13,0xE9,0xB3,0xEE,0x3C,0xA5,0x93,0x1E,0x08, +0xB4,0x95,0x4C,0x71,0x9C,0xC9,0x7B,0x78,0x2A,0x6F,0x6B,0x66,0xE9,0x9A,0xB7,0x91, +0x82,0x01,0x28,0x17,0x54,0x03,0xB3,0x7A,0x49,0x91,0x0E,0x19,0x3D,0xD2,0x7F,0x33, +0xA4,0xFE,0x6E,0xDC,0x5E,0x71,0x25,0xFC,0xB7,0x2C,0xD3,0xA3,0x3C,0xE1,0xE5,0xFE, +0xA6,0xFF,0xBA,0xBC,0x94,0x48,0x09,0x5D,0xB9,0xF4,0x33,0xC7,0x7A,0xA0,0xFD,0x81, +0x77,0x6F,0x4B,0x7D,0x32,0x87,0x94,0x5E,0x17,0x08,0xD8,0x6C,0xDA,0xC1,0x9D,0x73, +0x1C,0x63,0xDA,0xE4,0x22,0x9B,0x8A,0x20,0xDA,0xC2,0xBC,0x31,0x3D,0x9A,0x43,0x57, +0x5C,0xF1,0x0C,0x8F,0x0B,0x66,0x75,0xDA,0x1D,0x4E,0xBF,0x5F,0xCD,0x17,0x3F,0x33, +0x86,0xFD,0xED,0xF3,0x3C,0x66,0x98,0x11,0x66,0x8E,0x50,0x65,0x59,0x22,0x38,0x1B, +0xAD,0xBF,0x32,0x8B,0xBF,0x0F,0x0D,0x71,0x43,0xB1,0xE3,0x20,0xE3,0xBB,0xE0,0xBA, +0x90,0xEE,0xD7,0x4E,0x03,0x86,0x72,0x75,0xBE,0x52,0x50,0xD4,0x88,0x81,0xD5,0x8A, +0x91,0x16,0x70,0xD4,0x30,0xF9,0x44,0xB0,0x2D,0xDE,0xE4,0xBA,0xE7,0xEA,0xE4,0x1E, +0x98,0xA4,0xD9,0xA7,0xA2,0x19,0xBE,0x20,0xBF,0x08,0xFF,0xB3,0x1E,0xCF,0x26,0x95, +0x14,0x39,0xBA,0xD6,0xBD,0x63,0xFD,0x7B,0xCC,0xE2,0x9C,0x4E,0x27,0x65,0xB4,0x55, +0x86,0xEC,0x07,0x19,0xB1,0x8B,0xE8,0x05,0xB5,0x4C,0xF6,0x3A,0xB0,0x9C,0x8B,0x50, +0x91,0xD9,0x6D,0xD3,0x08,0x24,0x0D,0x6E,0xDD,0x84,0x38,0x95,0x8C,0xA7,0xD0,0x4F, +0x7F,0xF2,0xBF,0x45,0x40,0x6A,0x1E,0x71,0xB3,0xEA,0xC8,0xAF,0xEF,0xF6,0xFC,0x34, +0x9D,0xD9,0xE5,0xE8,0x3B,0xE8,0xD1,0x2B,0xAC,0x12,0x2C,0x02,0x97,0xC2,0xB3,0x62, +0xCC,0x3F,0xF6,0xA3,0x3F,0x7C,0x34,0xCD,0xBE,0xC7,0x15,0x43, +}; + +/* subject:/C=FI/ST=Uusimaa/O=INSIDE Secure Oy/OU=INSIDE Secure Test Certificate Authority/CN=INSIDE Secure Test Intermediate CA/emailAddress=support@matrixssl.org */ +/* issuer :/C=FI/ST=Uusimaa/L=Helsinki/O=INSIDE Secure Oy/CN=Test Root CA/emailAddress=support@matrixssl.org */ +unsigned char intermediate_subject_name[195]={ +0x30,0x81,0xC0,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49, +0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75,0x73,0x69,0x6D, +0x61,0x61,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x0C,0x10,0x49,0x4E,0x53, +0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x4F,0x79,0x31,0x31,0x30, +0x2F,0x06,0x03,0x55,0x04,0x0B,0x0C,0x28,0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53, +0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x65,0x72,0x74,0x69, +0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, +0x31,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x49,0x4E,0x53,0x49,0x44, +0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x49,0x6E, +0x74,0x65,0x72,0x6D,0x65,0x64,0x69,0x61,0x74,0x65,0x20,0x43,0x41,0x31,0x24,0x30, +0x22,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x15,0x73,0x75, +0x70,0x70,0x6F,0x72,0x74,0x40,0x6D,0x61,0x74,0x72,0x69,0x78,0x73,0x73,0x6C,0x2E, +0x6F,0x72,0x67, +}; +unsigned char intermediate_public_key[550]={ +0x30,0x82,0x02,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, +0x01,0x05,0x00,0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01, +0x00,0xAC,0x06,0x37,0xA9,0x4F,0xC3,0x93,0xA6,0xCB,0x56,0x04,0xA8,0x7B,0x5B,0x52, +0xDB,0xFD,0x3D,0xD1,0xC8,0x76,0xC9,0x11,0x77,0x11,0xCA,0x9F,0x7C,0xEE,0x40,0xC6, +0x1D,0x3A,0xF1,0x98,0x97,0x8A,0x34,0xB6,0x77,0x05,0xE2,0x98,0x80,0x1D,0x73,0xB9, +0x00,0xD4,0x83,0xE8,0xB0,0xAE,0x06,0xB4,0xC0,0x36,0x6F,0x62,0xEE,0x25,0x8F,0xE5, +0x26,0x29,0x5E,0xBB,0xFB,0x95,0x7F,0x59,0xE8,0x15,0xBF,0xD1,0x56,0xDA,0x75,0xC4, +0xA8,0xA0,0x16,0x7A,0xE2,0x1D,0xBC,0xA4,0xAF,0xF5,0xB6,0x4F,0x1E,0x85,0xF6,0x4C, +0x94,0xD7,0x79,0x2C,0xC4,0x5E,0xEA,0xEE,0x0B,0x8D,0x4F,0x5E,0x4E,0xD4,0x78,0x4D, +0x28,0x02,0x5C,0xA0,0x34,0x14,0x47,0x60,0x82,0x6B,0x39,0x2E,0x3C,0xAE,0x59,0x4B, +0xD6,0xB5,0x56,0xEB,0xF9,0xE9,0x34,0x4F,0x50,0xF0,0x67,0x05,0x58,0xDF,0x03,0x44, +0xC3,0x71,0x19,0x90,0x57,0xAB,0xF7,0x5C,0x7B,0xFB,0xCA,0xF0,0x1A,0xE9,0x29,0x12, +0xA4,0xC4,0x09,0x90,0xF3,0x87,0xA2,0x30,0xDD,0x52,0xB3,0x92,0x3E,0x55,0x3E,0xBD, +0xE5,0x30,0x97,0x8F,0xEF,0x14,0x79,0xFB,0xD4,0xC7,0xCC,0xCF,0x5F,0xB7,0xCD,0x4D, +0xEC,0xCA,0x16,0x1C,0x28,0x6A,0xFF,0xA5,0x48,0xDC,0x23,0x3A,0x85,0x2F,0x12,0xFB, +0x51,0x02,0x82,0x13,0xFA,0xB0,0x06,0x22,0x34,0x0C,0xD2,0x7C,0xE3,0x9B,0xA3,0x9C, +0x28,0x68,0xF5,0xD0,0x4E,0xDB,0xFB,0x1B,0x9E,0xEF,0xDC,0xA7,0xE6,0xBE,0x6B,0x0A, +0xCC,0x7B,0xEB,0x06,0xE9,0xB6,0x0C,0xFD,0xCC,0xC9,0x64,0x44,0xD2,0x58,0xAB,0x0F, +0x9F,0x30,0xD1,0x03,0x51,0x9F,0xE8,0xF5,0x23,0xBE,0x5F,0x14,0x89,0x9E,0xCE,0xAE, +0xF9,0x87,0xD8,0x53,0x9B,0xB6,0xE3,0xA7,0x95,0x25,0x7A,0xAC,0x0C,0xC4,0x8F,0x16, +0xF7,0x10,0xAA,0x2B,0x10,0xC1,0xB4,0x5A,0xEE,0x81,0x08,0x45,0x75,0xCC,0x21,0xB6, +0x0A,0x93,0x58,0xEA,0xBD,0x1E,0xC9,0xB9,0xD7,0x8E,0xC5,0x3A,0x68,0x61,0x23,0x22, +0x30,0x2A,0x60,0x8C,0xEA,0xBA,0xAD,0xA7,0x8C,0x97,0x4C,0xAE,0x72,0x4B,0x2F,0x26, +0xF1,0x15,0xCB,0x4A,0x33,0xFC,0x68,0xDE,0x53,0xBD,0xAE,0x83,0xF0,0x4A,0x92,0xF8, +0x40,0xE9,0xCC,0xC3,0x97,0x74,0xA6,0x4F,0x76,0x7C,0x8D,0xE7,0x30,0x03,0x8F,0xB0, +0x78,0xCB,0x60,0xE4,0xD1,0xE2,0xFF,0xBB,0x91,0x7B,0xE7,0x60,0x62,0xB0,0xA9,0x5B, +0x1B,0x84,0xF8,0xC3,0xDC,0xDA,0x54,0xBA,0x63,0xB9,0xED,0x9B,0x3E,0x7E,0x54,0x98, +0xBF,0x3D,0x46,0xA9,0x75,0x57,0x4C,0x74,0x28,0x6C,0xDA,0x1F,0xA0,0xE0,0xC9,0x99, +0x51,0x6D,0x72,0xA0,0xAF,0x80,0x51,0x52,0x44,0x80,0x6E,0xE3,0xF9,0x5A,0xA8,0x4E, +0xDB,0x46,0x02,0x68,0xD5,0xDC,0x2C,0x81,0x4D,0xB9,0xB4,0xA8,0xAC,0xE7,0x19,0xDD, +0x3D,0x7A,0x18,0x5F,0x19,0x08,0xDA,0x32,0xD6,0x88,0x3F,0x02,0x91,0x8B,0x88,0x82, +0x11,0xB2,0xD9,0x81,0x16,0x8C,0x92,0xDA,0xA1,0x8D,0x4B,0x7A,0xE2,0xD1,0x1E,0x6B, +0x31,0x27,0x60,0xBA,0x26,0x47,0x32,0xE5,0xBD,0x41,0x5B,0x29,0xB4,0x79,0xFB,0xCB, +0xF3,0x99,0xFE,0x79,0x3F,0xB2,0x60,0xAA,0xC7,0x09,0x8B,0xDA,0x18,0x54,0x56,0x66, +0x41,0x02,0x03,0x01,0x00,0x01, +}; +unsigned char intermediate_certificate[1586]={ +0x30,0x82,0x06,0x2E,0x30,0x82,0x04,0x16,0xA0,0x03,0x02,0x01,0x02,0x02,0x02,0x10, +0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, +0x30,0x81,0x8A,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49, +0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75,0x73,0x69,0x6D, +0x61,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x48,0x65,0x6C, +0x73,0x69,0x6E,0x6B,0x69,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x0C,0x10, +0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x4F,0x79, +0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C,0x54,0x65,0x73,0x74,0x20, +0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x31,0x24,0x30,0x22,0x06,0x09,0x2A,0x86,0x48, +0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x15,0x73,0x75,0x70,0x70,0x6F,0x72,0x74,0x40, +0x6D,0x61,0x74,0x72,0x69,0x78,0x73,0x73,0x6C,0x2E,0x6F,0x72,0x67,0x30,0x1E,0x17, +0x0D,0x31,0x36,0x30,0x38,0x32,0x39,0x30,0x35,0x33,0x32,0x31,0x35,0x5A,0x17,0x0D, +0x32,0x36,0x30,0x38,0x32,0x37,0x30,0x35,0x33,0x32,0x31,0x35,0x5A,0x30,0x81,0xC0, +0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49,0x31,0x10,0x30, +0x0E,0x06,0x03,0x55,0x04,0x08,0x0C,0x07,0x55,0x75,0x73,0x69,0x6D,0x61,0x61,0x31, +0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0A,0x0C,0x10,0x49,0x4E,0x53,0x49,0x44,0x45, +0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x4F,0x79,0x31,0x31,0x30,0x2F,0x06,0x03, +0x55,0x04,0x0B,0x0C,0x28,0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53,0x65,0x63,0x75, +0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, +0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x2B,0x30, +0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x49,0x4E,0x53,0x49,0x44,0x45,0x20,0x53, +0x65,0x63,0x75,0x72,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x49,0x6E,0x74,0x65,0x72, +0x6D,0x65,0x64,0x69,0x61,0x74,0x65,0x20,0x43,0x41,0x31,0x24,0x30,0x22,0x06,0x09, +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,0x16,0x15,0x73,0x75,0x70,0x70,0x6F, +0x72,0x74,0x40,0x6D,0x61,0x74,0x72,0x69,0x78,0x73,0x73,0x6C,0x2E,0x6F,0x72,0x67, +0x30,0x82,0x02,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, +0x01,0x05,0x00,0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01, +0x00,0xAC,0x06,0x37,0xA9,0x4F,0xC3,0x93,0xA6,0xCB,0x56,0x04,0xA8,0x7B,0x5B,0x52, +0xDB,0xFD,0x3D,0xD1,0xC8,0x76,0xC9,0x11,0x77,0x11,0xCA,0x9F,0x7C,0xEE,0x40,0xC6, +0x1D,0x3A,0xF1,0x98,0x97,0x8A,0x34,0xB6,0x77,0x05,0xE2,0x98,0x80,0x1D,0x73,0xB9, +0x00,0xD4,0x83,0xE8,0xB0,0xAE,0x06,0xB4,0xC0,0x36,0x6F,0x62,0xEE,0x25,0x8F,0xE5, +0x26,0x29,0x5E,0xBB,0xFB,0x95,0x7F,0x59,0xE8,0x15,0xBF,0xD1,0x56,0xDA,0x75,0xC4, +0xA8,0xA0,0x16,0x7A,0xE2,0x1D,0xBC,0xA4,0xAF,0xF5,0xB6,0x4F,0x1E,0x85,0xF6,0x4C, +0x94,0xD7,0x79,0x2C,0xC4,0x5E,0xEA,0xEE,0x0B,0x8D,0x4F,0x5E,0x4E,0xD4,0x78,0x4D, +0x28,0x02,0x5C,0xA0,0x34,0x14,0x47,0x60,0x82,0x6B,0x39,0x2E,0x3C,0xAE,0x59,0x4B, +0xD6,0xB5,0x56,0xEB,0xF9,0xE9,0x34,0x4F,0x50,0xF0,0x67,0x05,0x58,0xDF,0x03,0x44, +0xC3,0x71,0x19,0x90,0x57,0xAB,0xF7,0x5C,0x7B,0xFB,0xCA,0xF0,0x1A,0xE9,0x29,0x12, +0xA4,0xC4,0x09,0x90,0xF3,0x87,0xA2,0x30,0xDD,0x52,0xB3,0x92,0x3E,0x55,0x3E,0xBD, +0xE5,0x30,0x97,0x8F,0xEF,0x14,0x79,0xFB,0xD4,0xC7,0xCC,0xCF,0x5F,0xB7,0xCD,0x4D, +0xEC,0xCA,0x16,0x1C,0x28,0x6A,0xFF,0xA5,0x48,0xDC,0x23,0x3A,0x85,0x2F,0x12,0xFB, +0x51,0x02,0x82,0x13,0xFA,0xB0,0x06,0x22,0x34,0x0C,0xD2,0x7C,0xE3,0x9B,0xA3,0x9C, +0x28,0x68,0xF5,0xD0,0x4E,0xDB,0xFB,0x1B,0x9E,0xEF,0xDC,0xA7,0xE6,0xBE,0x6B,0x0A, +0xCC,0x7B,0xEB,0x06,0xE9,0xB6,0x0C,0xFD,0xCC,0xC9,0x64,0x44,0xD2,0x58,0xAB,0x0F, +0x9F,0x30,0xD1,0x03,0x51,0x9F,0xE8,0xF5,0x23,0xBE,0x5F,0x14,0x89,0x9E,0xCE,0xAE, +0xF9,0x87,0xD8,0x53,0x9B,0xB6,0xE3,0xA7,0x95,0x25,0x7A,0xAC,0x0C,0xC4,0x8F,0x16, +0xF7,0x10,0xAA,0x2B,0x10,0xC1,0xB4,0x5A,0xEE,0x81,0x08,0x45,0x75,0xCC,0x21,0xB6, +0x0A,0x93,0x58,0xEA,0xBD,0x1E,0xC9,0xB9,0xD7,0x8E,0xC5,0x3A,0x68,0x61,0x23,0x22, +0x30,0x2A,0x60,0x8C,0xEA,0xBA,0xAD,0xA7,0x8C,0x97,0x4C,0xAE,0x72,0x4B,0x2F,0x26, +0xF1,0x15,0xCB,0x4A,0x33,0xFC,0x68,0xDE,0x53,0xBD,0xAE,0x83,0xF0,0x4A,0x92,0xF8, +0x40,0xE9,0xCC,0xC3,0x97,0x74,0xA6,0x4F,0x76,0x7C,0x8D,0xE7,0x30,0x03,0x8F,0xB0, +0x78,0xCB,0x60,0xE4,0xD1,0xE2,0xFF,0xBB,0x91,0x7B,0xE7,0x60,0x62,0xB0,0xA9,0x5B, +0x1B,0x84,0xF8,0xC3,0xDC,0xDA,0x54,0xBA,0x63,0xB9,0xED,0x9B,0x3E,0x7E,0x54,0x98, +0xBF,0x3D,0x46,0xA9,0x75,0x57,0x4C,0x74,0x28,0x6C,0xDA,0x1F,0xA0,0xE0,0xC9,0x99, +0x51,0x6D,0x72,0xA0,0xAF,0x80,0x51,0x52,0x44,0x80,0x6E,0xE3,0xF9,0x5A,0xA8,0x4E, +0xDB,0x46,0x02,0x68,0xD5,0xDC,0x2C,0x81,0x4D,0xB9,0xB4,0xA8,0xAC,0xE7,0x19,0xDD, +0x3D,0x7A,0x18,0x5F,0x19,0x08,0xDA,0x32,0xD6,0x88,0x3F,0x02,0x91,0x8B,0x88,0x82, +0x11,0xB2,0xD9,0x81,0x16,0x8C,0x92,0xDA,0xA1,0x8D,0x4B,0x7A,0xE2,0xD1,0x1E,0x6B, +0x31,0x27,0x60,0xBA,0x26,0x47,0x32,0xE5,0xBD,0x41,0x5B,0x29,0xB4,0x79,0xFB,0xCB, +0xF3,0x99,0xFE,0x79,0x3F,0xB2,0x60,0xAA,0xC7,0x09,0x8B,0xDA,0x18,0x54,0x56,0x66, +0x41,0x02,0x03,0x01,0x00,0x01,0xA3,0x66,0x30,0x64,0x30,0x1D,0x06,0x03,0x55,0x1D, +0x0E,0x04,0x16,0x04,0x14,0x64,0x15,0xE2,0x5E,0x3E,0x88,0x1A,0xDD,0x6D,0x29,0x3D, +0x1A,0xE5,0x74,0xE2,0xDB,0x4F,0xF3,0x06,0xB4,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, +0x04,0x18,0x30,0x16,0x80,0x14,0x3E,0x8B,0xE8,0xAB,0x4F,0x28,0x03,0x89,0x9D,0x5C, +0x37,0xA8,0xC4,0xCF,0x0D,0xDD,0x61,0x2C,0x98,0x7A,0x30,0x12,0x06,0x03,0x55,0x1D, +0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x0E, +0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D, +0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02, +0x01,0x00,0x64,0xBA,0x52,0x03,0xD0,0x1B,0x26,0x58,0xD2,0x26,0xAE,0xAB,0x4B,0x83, +0xD6,0xAD,0x42,0xA8,0xD9,0xF4,0x75,0x12,0xEC,0x72,0x54,0xDF,0xD6,0xFB,0x53,0xAF, +0x52,0xE3,0x5A,0xB5,0x64,0x8E,0x71,0xFF,0xBB,0x52,0xE4,0x50,0xEA,0xDD,0xF9,0x7D, +0xA3,0x73,0xB7,0x89,0x51,0x23,0xA9,0x72,0x42,0x77,0xF8,0xB4,0x28,0x41,0xA0,0x12, +0xD8,0x2B,0x81,0x22,0x95,0xA2,0x87,0x17,0x6B,0xE2,0xB7,0xAA,0x15,0x74,0xBF,0x82, +0x02,0x65,0x59,0x37,0x40,0x4D,0x6D,0xE2,0x52,0xCF,0x89,0xBB,0xEF,0xEF,0xCA,0xAA, +0x9D,0xCD,0x71,0xDD,0xCF,0x01,0xB2,0xB7,0x02,0x0F,0x8F,0xFB,0x5B,0xC0,0x6B,0x4A, +0xE5,0x5E,0xAF,0xA3,0xE8,0x5D,0xD8,0x99,0xF2,0xD9,0xF5,0x5A,0xA8,0xD0,0x0A,0x6C, +0x1E,0x0A,0x50,0x45,0x61,0xC6,0x97,0x70,0x23,0x27,0xC9,0x8E,0xE4,0x24,0xCF,0x2B, +0x1A,0x44,0x0E,0x17,0x7D,0xFE,0xF5,0xC4,0xDB,0x62,0xCA,0x06,0xDD,0x3F,0x3D,0x84, +0x8D,0x0C,0x17,0x15,0x3F,0xF5,0xF5,0x51,0x37,0x82,0xA6,0x7A,0xBF,0xF5,0xA1,0x5E, +0xA5,0x8D,0x9B,0xA6,0x17,0x8F,0xF4,0xBF,0xE7,0x75,0xB0,0x81,0x62,0x98,0xA9,0xEC, +0xB3,0x04,0xB1,0xE3,0x19,0x58,0xC3,0x47,0x9F,0x2D,0xA5,0x2A,0xB1,0xAA,0x91,0x08, +0xD1,0xAF,0x50,0xAE,0xAD,0x47,0x53,0xB0,0xAD,0x75,0x2A,0x04,0x0F,0x27,0x85,0x49, +0x92,0x74,0xB1,0x2B,0x5E,0x35,0x7E,0xF2,0x77,0xF7,0x93,0x3B,0x45,0x97,0x6B,0x79, +0xD4,0x32,0xC0,0x20,0x5A,0x76,0xA5,0x2A,0x37,0xC7,0x1B,0x96,0x4F,0xC2,0xBE,0x66, +0x45,0xBC,0xC2,0x43,0xB7,0x5B,0x3B,0x16,0x82,0x7F,0x7E,0x1C,0x91,0xD9,0x2D,0x4F, +0x6C,0x50,0x6E,0xBF,0xE4,0x38,0x80,0x58,0x6D,0x58,0x1F,0x71,0x83,0xDA,0xFF,0x84, +0x24,0xBF,0x95,0x52,0x4F,0x81,0x42,0xA7,0xCC,0x30,0xFB,0x6B,0x94,0x81,0xF9,0x8A, +0x2F,0xF8,0x54,0x36,0x58,0x91,0x10,0x57,0x4B,0x99,0x3C,0xFF,0x74,0x58,0xF8,0x19, +0x00,0x98,0x75,0xF6,0x38,0x83,0x46,0xD9,0xB9,0xD0,0xFB,0x49,0x4A,0xD8,0xD1,0xD7, +0xDC,0x2C,0x2A,0xF5,0xE3,0x87,0xBB,0xEE,0x27,0xE3,0x3D,0xEC,0xAF,0x8E,0xFD,0x9B, +0x53,0x3E,0x52,0xF6,0x92,0xD6,0x60,0x00,0xB8,0x76,0x68,0x23,0x4D,0x16,0xA2,0x51, +0x2F,0x5B,0x3D,0xF6,0xA7,0x8F,0xB8,0xBE,0x12,0x93,0x2D,0x51,0xCC,0xCC,0x57,0xAC, +0xB5,0x12,0x23,0xC5,0x5B,0x76,0x67,0xD3,0x6A,0xCE,0x7D,0x28,0x04,0x84,0x1F,0x16, +0x66,0x78,0xB8,0x9A,0x12,0x3E,0xF0,0x38,0x1F,0xE5,0x0C,0x12,0x71,0xAC,0x1F,0xE5, +0x39,0xE1,0x0F,0xF2,0xAB,0x90,0xC9,0x84,0xAC,0x33,0x67,0x36,0xF9,0x20,0xF8,0xC9, +0xEF,0x15,0xF3,0xC7,0x26,0x23,0xB8,0xC4,0x57,0x23,0xAC,0x8C,0xE4,0xFC,0x8F,0xD1, +0xF2,0x14,0xBD,0x88,0x8F,0x3F,0xEE,0x0C,0x93,0xFE,0x63,0xFB,0x8B,0x7D,0x55,0xCB, +0x7F,0x3F,0xF4,0x40,0x25,0x1F,0xDB,0xB4,0xA3,0xDF,0x04,0xEE,0x1A,0xFA,0xFC,0x96, +0x72,0xF8,0x13,0xB2,0xEC,0x40,0x65,0x60,0xE7,0x80,0xBD,0x2C,0x57,0xDF,0xD5,0xA2, +0xDA,0x00,0xEB,0x4D,0x4F,0xB4,0xCA,0xCA,0x20,0x11,0x97,0x41,0x66,0x63,0x5E,0x64, +0xC8,0x2E, +}; + +/* Stored basic OCSP request. */ +unsigned char ocsp_request[] = { + 0x30, 0x43, 0x30, 0x41, 0x30, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x30, 0x09, + 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x82, + 0x94, 0x68, 0x3e, 0xa5, 0xf1, 0x04, 0x9e, 0xc6, 0x2b, 0x2b, 0x02, 0xa5, + 0xdd, 0x04, 0x7c, 0x1a, 0xfa, 0xf8, 0x0f, 0x04, 0x14, 0x64, 0x15, 0xe2, + 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, 0x3d, 0x1a, 0xe5, 0x74, 0xe2, + 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x02, 0x02, 0x10, 0x01 +}; +unsigned int ocsp_request_len = 69; + +/* Stored basic OCSP response (revoked certificate). + + Generated using OpenSSL OCSP responder: openssl ocsp -resp_key_id -index ../../index.txt -VAfile ../../certs/ocsp.insidesecure-test.com.cert.pem -CA ../../certs/ca-chain.cert.pem -rsigner ../../certs/ocsp.insidesecure-test.com.cert.pem -rkey ../../private/ocsp.insidesecure-test.com.key-nopass.pem -nmin 5 -noverify -reqin /tmp/request -respout /tmp/response. */ + +unsigned char ocsp_response_future[] = { + 0x30, 0x82, 0x09, 0x4a, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x09, 0x43, 0x30, + 0x82, 0x09, 0x3f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x01, 0x04, 0x82, 0x09, 0x30, 0x30, 0x82, 0x09, 0x2c, 0x30, 0x81, + 0xa1, 0xa2, 0x16, 0x04, 0x14, 0x78, 0xe4, 0xb1, 0x1a, 0x09, 0xef, 0x04, + 0x88, 0x8b, 0x67, 0xbb, 0x81, 0x70, 0xe0, 0x18, 0x01, 0x36, 0xe4, 0x60, + 0xb3, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, 0x30, 0x33, 0x32, 0x38, 0x30, + 0x34, 0x31, 0x33, 0x30, 0x38, 0x5a, 0x30, 0x76, 0x30, 0x74, 0x30, 0x3b, + 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, + 0x14, 0x82, 0x94, 0x68, 0x3e, 0xa5, 0xf1, 0x04, 0x9e, 0xc6, 0x2b, 0x2b, + 0x02, 0xa5, 0xdd, 0x04, 0x7c, 0x1a, 0xfa, 0xf8, 0x0f, 0x04, 0x14, 0x64, + 0x15, 0xe2, 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, 0x3d, 0x1a, 0xe5, + 0x74, 0xe2, 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x02, 0x02, 0x10, 0x01, 0xa1, + 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x36, 0x30, 0x38, 0x32, 0x39, 0x30, + 0x35, 0x35, 0x38, 0x35, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, + 0x30, 0x33, 0x32, 0x38, 0x30, 0x34, 0x31, 0x33, 0x30, 0x38, 0x5a, 0xa0, + 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, 0x30, 0x33, 0x32, 0x38, 0x30, + 0x34, 0x31, 0x38, 0x30, 0x38, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, + 0x01, 0x00, 0x8a, 0x8e, 0x03, 0x6c, 0x4b, 0x83, 0xa9, 0xd0, 0x3a, 0x6a, + 0xd2, 0xae, 0x2d, 0x6c, 0x9d, 0x4b, 0xb2, 0xd1, 0xbd, 0x80, 0xc0, 0xf8, + 0x24, 0x1d, 0x5d, 0x31, 0x43, 0x53, 0x07, 0xee, 0x32, 0x56, 0x78, 0x07, + 0x28, 0xbe, 0x26, 0x5f, 0x54, 0x3c, 0x8b, 0xdf, 0x0d, 0xc6, 0x3b, 0xb1, + 0xc9, 0xbc, 0x4d, 0xba, 0x04, 0x1d, 0x47, 0xa5, 0x6d, 0x12, 0x1a, 0xb7, + 0xec, 0x45, 0x72, 0x79, 0x25, 0x95, 0x77, 0x06, 0xf5, 0x55, 0x6b, 0xa3, + 0x73, 0xf0, 0x55, 0x3a, 0x9a, 0x2a, 0x67, 0xfb, 0xb2, 0x79, 0xa4, 0x5f, + 0xee, 0x9a, 0xd8, 0x9a, 0x51, 0xd7, 0x6c, 0x3b, 0x83, 0x15, 0x59, 0x7c, + 0xbb, 0x08, 0xdb, 0x45, 0x42, 0xb9, 0x75, 0x08, 0x86, 0x54, 0x19, 0x8f, + 0x55, 0x93, 0x8e, 0x27, 0x12, 0x8f, 0xb8, 0xdd, 0x61, 0xc0, 0x86, 0xfe, + 0x39, 0x57, 0x83, 0xfc, 0x5a, 0x8c, 0xe3, 0xb6, 0x31, 0x57, 0xb0, 0x29, + 0x9f, 0x47, 0xae, 0x76, 0x92, 0x6f, 0x05, 0x5b, 0xde, 0xac, 0x63, 0x17, + 0xb3, 0x3f, 0x5e, 0x1b, 0x88, 0x1e, 0x35, 0x95, 0xa0, 0x14, 0xdd, 0xc8, + 0x99, 0x3c, 0x6b, 0x56, 0xc6, 0x2f, 0x7d, 0x33, 0x02, 0xff, 0xf0, 0xb2, + 0x6a, 0x9d, 0xf1, 0xfc, 0xc1, 0x6e, 0xe5, 0xd6, 0x21, 0x14, 0xf7, 0x81, + 0x29, 0x98, 0x2c, 0x8b, 0xce, 0x9e, 0xdb, 0x33, 0x34, 0xe4, 0x00, 0xc5, + 0x45, 0xad, 0xd3, 0x0e, 0x09, 0xe0, 0x39, 0xc3, 0x27, 0x81, 0xc2, 0xfc, + 0xb9, 0xe8, 0x11, 0x46, 0xf4, 0x5c, 0xb7, 0x7a, 0xe8, 0x80, 0x31, 0xd4, + 0x6d, 0x9b, 0xe5, 0xfd, 0xe9, 0x7b, 0x71, 0xa5, 0x58, 0xca, 0x5a, 0x68, + 0x0d, 0x08, 0x2d, 0xa6, 0x34, 0x6b, 0xbd, 0x9c, 0xc1, 0x5a, 0x0c, 0x79, + 0x62, 0xca, 0x4e, 0xf7, 0x12, 0xc6, 0xff, 0x2b, 0xb1, 0x41, 0xb0, 0x6b, + 0x49, 0x40, 0xe3, 0xc7, 0xf7, 0x4b, 0x54, 0xee, 0xd8, 0x30, 0x60, 0x63, + 0x4e, 0xa4, 0x4d, 0xef, 0x68, 0xa5, 0x95, 0xc3, 0xc6, 0xbd, 0x50, 0xfc, + 0x2e, 0x42, 0xe6, 0x73, 0xcc, 0x6c, 0xbf, 0xce, 0xca, 0xc3, 0xfc, 0x06, + 0x60, 0x0d, 0x8d, 0x04, 0x89, 0x41, 0x00, 0x41, 0xd7, 0xe0, 0x59, 0xfb, + 0xee, 0x38, 0x1f, 0x9b, 0x86, 0x45, 0xc0, 0x43, 0x1b, 0x8c, 0x27, 0x32, + 0x20, 0x1b, 0xba, 0xda, 0x22, 0x12, 0x8b, 0xd5, 0xee, 0x8b, 0xed, 0x85, + 0x1e, 0x85, 0x58, 0x3d, 0x8a, 0xa9, 0xa5, 0x4b, 0x05, 0xc0, 0x73, 0x8a, + 0x63, 0xa7, 0x20, 0xff, 0x9d, 0xf8, 0x88, 0x5c, 0x0e, 0xc9, 0x45, 0xc4, + 0x9f, 0xc1, 0xdb, 0x5a, 0xaa, 0x4a, 0x70, 0xb8, 0xca, 0xd1, 0x48, 0x60, + 0xf7, 0x15, 0xc6, 0x90, 0x4c, 0xed, 0xb1, 0x0d, 0xd6, 0x13, 0xfc, 0x6e, + 0x4c, 0x4b, 0x76, 0xbf, 0x81, 0xc4, 0xd8, 0x14, 0x05, 0xa2, 0x33, 0x5e, + 0x28, 0xd7, 0xab, 0x8a, 0xe7, 0x96, 0x43, 0x37, 0xad, 0xb8, 0x04, 0x45, + 0xeb, 0xb6, 0x5c, 0x4f, 0x3c, 0x27, 0x5f, 0x7a, 0x14, 0x75, 0xae, 0x70, + 0x9b, 0xda, 0x53, 0x57, 0xb0, 0xf6, 0x8d, 0x73, 0x81, 0x0b, 0x4d, 0x95, + 0x9e, 0xa4, 0xda, 0xff, 0x6a, 0x22, 0x01, 0xb0, 0xf3, 0x31, 0x56, 0xa9, + 0x56, 0x89, 0x2c, 0x87, 0x65, 0xa5, 0xb0, 0x87, 0xe0, 0x9e, 0xc3, 0x41, + 0x08, 0x62, 0x6e, 0x2e, 0xcd, 0xac, 0x96, 0x7c, 0x70, 0x13, 0xdb, 0xeb, + 0x4b, 0x1f, 0x0f, 0x5d, 0x95, 0x3d, 0x33, 0xba, 0x14, 0x97, 0x21, 0xea, + 0xa9, 0xcd, 0xb6, 0x0d, 0x15, 0x58, 0x70, 0x07, 0xc8, 0x39, 0x31, 0x3b, + 0x28, 0xf4, 0x6b, 0xb4, 0xa3, 0xb5, 0xb3, 0x22, 0x6c, 0x2d, 0x98, 0x83, + 0x62, 0xa1, 0xe9, 0xbe, 0x05, 0x46, 0x1f, 0xe8, 0xda, 0xf2, 0x11, 0x8b, + 0x76, 0x99, 0x69, 0xc3, 0xfd, 0x65, 0x46, 0x08, 0xbe, 0x44, 0xa0, 0x82, + 0x06, 0x70, 0x30, 0x82, 0x06, 0x6c, 0x30, 0x82, 0x06, 0x68, 0x30, 0x82, + 0x04, 0x50, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, 0x02, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x81, 0xc0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x07, 0x55, 0x75, 0x73, 0x69, 0x6d, 0x61, 0x61, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x10, 0x49, + 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x4f, 0x79, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x28, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x22, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x20, 0x43, 0x41, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x40, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, + 0x38, 0x32, 0x39, 0x30, 0x36, 0x30, 0x38, 0x30, 0x31, 0x5a, 0x17, 0x0d, + 0x31, 0x39, 0x30, 0x35, 0x32, 0x36, 0x30, 0x36, 0x30, 0x38, 0x30, 0x31, + 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x07, 0x55, 0x75, 0x73, 0x69, 0x6d, 0x61, 0x61, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, + 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x10, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x4f, 0x79, 0x31, 0x1b, 0x30, + 0x19, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x12, 0x49, 0x4e, 0x53, 0x49, + 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, + 0x73, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x1a, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x40, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xdd, 0xbb, 0xb9, 0x27, 0x84, 0xb2, 0x02, 0x93, 0xdc, 0x68, + 0xe6, 0x06, 0x56, 0xe8, 0xed, 0xcc, 0x4b, 0x0b, 0x11, 0x05, 0x20, 0x72, + 0x1a, 0x1a, 0x08, 0x09, 0xc2, 0x60, 0x33, 0x79, 0x4b, 0xeb, 0xfb, 0x7f, + 0xa1, 0xf3, 0x22, 0xc2, 0xf7, 0x71, 0xe7, 0x0a, 0x5b, 0x81, 0xd1, 0x20, + 0x0a, 0x85, 0xfb, 0x0e, 0x66, 0x33, 0x35, 0x2b, 0x8d, 0x78, 0xf5, 0xd6, + 0x43, 0x0b, 0xe5, 0xce, 0xf8, 0x4a, 0x47, 0x88, 0x03, 0x14, 0x16, 0xb7, + 0xbf, 0x1c, 0xf8, 0x95, 0x9b, 0xac, 0xec, 0x07, 0x9e, 0xa4, 0x91, 0x59, + 0x89, 0xe1, 0xe1, 0xee, 0xaf, 0x4c, 0x7a, 0x98, 0x64, 0x27, 0xe8, 0x63, + 0x0e, 0xd7, 0x75, 0x50, 0x35, 0x6a, 0x53, 0xba, 0x42, 0xb9, 0xc0, 0x11, + 0x1d, 0x6c, 0xf7, 0x22, 0xcf, 0xc5, 0x7a, 0x7d, 0x8f, 0xd2, 0xef, 0x66, + 0x5c, 0xef, 0x93, 0x91, 0x02, 0x8e, 0x2d, 0xac, 0x43, 0x16, 0xd5, 0xc1, + 0xda, 0xdf, 0xcc, 0x6c, 0xc5, 0x03, 0xcb, 0xd5, 0x2d, 0x99, 0xee, 0x93, + 0x7e, 0x62, 0x38, 0x9f, 0xe2, 0x41, 0xe2, 0xe2, 0x55, 0x54, 0xd0, 0xf7, + 0xc7, 0xff, 0x11, 0x99, 0x8c, 0xd1, 0x99, 0x1e, 0xf8, 0x3c, 0xa5, 0x68, + 0xfb, 0x4f, 0x2a, 0x6a, 0x2a, 0x39, 0xf0, 0x19, 0xfc, 0x8e, 0x09, 0x81, + 0x7d, 0xae, 0x7f, 0x6b, 0xdd, 0x54, 0xac, 0x84, 0x48, 0x51, 0x01, 0x6d, + 0x53, 0xe7, 0xb6, 0xf7, 0x7a, 0x67, 0x73, 0x7c, 0xe8, 0x82, 0x70, 0xc4, + 0x4e, 0x62, 0x98, 0xc2, 0x2c, 0x66, 0xe6, 0xbd, 0xcd, 0xda, 0x82, 0x7d, + 0x4a, 0xf7, 0xb3, 0x60, 0x5f, 0x75, 0x26, 0xfd, 0x5f, 0x5c, 0xa1, 0x42, + 0xd3, 0xed, 0x06, 0x31, 0x48, 0x54, 0xd1, 0xd7, 0x8f, 0x53, 0x14, 0xb1, + 0x80, 0x81, 0x8f, 0x8f, 0x7a, 0x7d, 0x1f, 0xf9, 0xfa, 0x6a, 0x9e, 0xdf, + 0xb0, 0x02, 0x3a, 0x5f, 0x31, 0x28, 0x3d, 0xe0, 0xfb, 0x06, 0xed, 0x35, + 0x11, 0x4e, 0x99, 0x05, 0xef, 0x7a, 0xb4, 0xa3, 0x52, 0xec, 0x55, 0x8d, + 0xf2, 0xc4, 0x0d, 0x41, 0xb0, 0x2e, 0x61, 0xdf, 0x7d, 0x11, 0x23, 0x07, + 0x00, 0xf1, 0x7d, 0x7b, 0xeb, 0xfc, 0xcd, 0xf6, 0x2e, 0xa3, 0xbf, 0x17, + 0xe9, 0x92, 0x75, 0xd6, 0x80, 0x79, 0x22, 0x1e, 0xa6, 0x71, 0x42, 0x62, + 0x65, 0x48, 0xe8, 0x7a, 0x03, 0xf5, 0x30, 0x37, 0x2b, 0xa8, 0xb4, 0x3d, + 0x9a, 0xb5, 0xb4, 0xf7, 0x0a, 0x51, 0x64, 0xff, 0x33, 0x3d, 0x79, 0x43, + 0x08, 0xa9, 0xda, 0x83, 0x6e, 0xcc, 0x1c, 0x98, 0x02, 0x33, 0x0f, 0xe3, + 0x88, 0x02, 0x28, 0x94, 0x88, 0xcf, 0xea, 0xf9, 0x29, 0x59, 0x9b, 0x8c, + 0x46, 0x23, 0x96, 0x8a, 0x2a, 0x3a, 0x46, 0xa8, 0x9b, 0x8b, 0x41, 0x77, + 0x7f, 0xb9, 0x8e, 0x79, 0xc7, 0x9a, 0x39, 0x0c, 0xa2, 0xf8, 0xe7, 0xf7, + 0x28, 0x50, 0xa3, 0x79, 0x09, 0xd4, 0x7a, 0xa4, 0xba, 0x6b, 0xdf, 0xb2, + 0xd3, 0x5f, 0x47, 0x10, 0x49, 0x91, 0xa8, 0x68, 0xe7, 0x2d, 0x13, 0x9d, + 0x18, 0xd0, 0x7f, 0x43, 0xf9, 0x32, 0x81, 0x98, 0x15, 0x7f, 0x7a, 0x6a, + 0xc3, 0x52, 0x6f, 0x9b, 0xf7, 0xaf, 0xd2, 0x50, 0x2b, 0x54, 0x0e, 0x63, + 0x88, 0x98, 0x2e, 0xeb, 0x1c, 0x31, 0x9d, 0xa6, 0xda, 0xfd, 0xfd, 0x6d, + 0x9d, 0xbb, 0xb8, 0x7f, 0x16, 0x99, 0x7b, 0xfd, 0xc8, 0x7d, 0x21, 0xe9, + 0x05, 0x25, 0xe3, 0xc0, 0x4a, 0x1a, 0x69, 0x95, 0xed, 0xa8, 0xb1, 0x8c, + 0x60, 0xb5, 0xee, 0xd7, 0x36, 0x49, 0x2b, 0xd3, 0x00, 0x04, 0xda, 0x16, + 0x41, 0xa3, 0xd0, 0x38, 0x1b, 0xf2, 0xfc, 0x23, 0x22, 0xcf, 0xe4, 0x62, + 0xee, 0x95, 0x3f, 0x0f, 0x7f, 0x89, 0xb0, 0x56, 0x20, 0x3e, 0xd9, 0xff, + 0x14, 0x91, 0xe7, 0x32, 0x1f, 0xcd, 0x55, 0x7a, 0x1a, 0x43, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x78, 0xe4, 0xb1, 0x1a, 0x09, 0xef, 0x04, + 0x88, 0x8b, 0x67, 0xbb, 0x81, 0x70, 0xe0, 0x18, 0x01, 0x36, 0xe4, 0x60, + 0xb3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x64, 0x15, 0xe2, 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, + 0x3d, 0x1a, 0xe5, 0x74, 0xe2, 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, + 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x04, 0xd8, + 0x13, 0x9f, 0x61, 0x0c, 0xcc, 0x49, 0x72, 0xf9, 0x66, 0x62, 0xb6, 0xdc, + 0x10, 0x7e, 0x44, 0x2e, 0x07, 0x44, 0x0a, 0x75, 0x00, 0xf7, 0x85, 0x95, + 0x11, 0x8b, 0xc7, 0xd3, 0xf6, 0x67, 0x4f, 0x14, 0x80, 0x93, 0x3b, 0xb0, + 0x35, 0xa3, 0x55, 0xef, 0xe8, 0xb5, 0x0c, 0x37, 0xaa, 0xc2, 0x86, 0x4b, + 0x59, 0x69, 0x5b, 0x87, 0x05, 0xe7, 0x5e, 0x20, 0x32, 0x16, 0x62, 0xe1, + 0xeb, 0x04, 0x47, 0xec, 0x77, 0x46, 0x08, 0x72, 0xe2, 0xd7, 0x8c, 0xb4, + 0xd8, 0x33, 0x2c, 0x26, 0xee, 0xb1, 0x30, 0xe6, 0xe8, 0x97, 0xde, 0x21, + 0x71, 0x25, 0xcd, 0x83, 0xee, 0x6c, 0x59, 0x7a, 0x75, 0x0f, 0xdb, 0x89, + 0x21, 0x72, 0x47, 0xe2, 0x0a, 0x8a, 0xb4, 0x10, 0x4e, 0xd1, 0xb9, 0x54, + 0x5e, 0xd1, 0x9d, 0x99, 0xe9, 0x4d, 0x99, 0x74, 0x62, 0x92, 0xe1, 0x68, + 0x5a, 0xb4, 0x8e, 0x4d, 0x46, 0xc4, 0x04, 0x1d, 0xc0, 0x5f, 0xf9, 0xa0, + 0x08, 0x88, 0x2c, 0x49, 0xdf, 0x39, 0x39, 0x9c, 0x6b, 0xdc, 0x7c, 0x61, + 0xd3, 0x26, 0xf3, 0x3c, 0xd2, 0x5e, 0xf5, 0xee, 0x5d, 0x91, 0x47, 0x7f, + 0x0e, 0xee, 0x77, 0x81, 0x23, 0x72, 0x62, 0xcf, 0x01, 0x68, 0x4e, 0x8c, + 0x78, 0xb8, 0x47, 0xb8, 0x33, 0x6f, 0x0f, 0x38, 0x41, 0x41, 0x42, 0x6e, + 0x25, 0xe9, 0xb1, 0x3d, 0x3a, 0x2f, 0x4e, 0x01, 0xa0, 0xfd, 0x98, 0x2a, + 0x96, 0x94, 0xc6, 0xd6, 0x81, 0x68, 0x2a, 0x8d, 0x06, 0x85, 0x9e, 0x3e, + 0x13, 0xf1, 0x21, 0xef, 0xf3, 0x87, 0xc8, 0xc1, 0xf1, 0x16, 0x21, 0x49, + 0x45, 0x2c, 0xa4, 0x85, 0x15, 0x3d, 0xfc, 0x0e, 0x39, 0x75, 0xe8, 0x8c, + 0x23, 0xba, 0x2d, 0x24, 0x9f, 0x72, 0xfb, 0x37, 0x89, 0xbb, 0x02, 0x90, + 0xd1, 0x1f, 0x93, 0x4d, 0xdb, 0x8d, 0x25, 0x87, 0xff, 0x62, 0xc9, 0x38, + 0x4c, 0x87, 0xfe, 0xa2, 0xec, 0x00, 0x29, 0x3e, 0xa0, 0x6c, 0x4f, 0x6c, + 0x91, 0x8b, 0x61, 0xad, 0xbe, 0xa7, 0x34, 0x4d, 0xd3, 0xc6, 0xae, 0x04, + 0x57, 0x78, 0xf1, 0x9d, 0x46, 0x93, 0x8f, 0x70, 0x64, 0xea, 0x64, 0x93, + 0xb3, 0x06, 0xb3, 0xbb, 0x58, 0x88, 0xd7, 0x27, 0x55, 0xe0, 0x47, 0x94, + 0x13, 0x0c, 0xb5, 0x8c, 0xc0, 0x15, 0x04, 0x8c, 0x3a, 0xd5, 0x83, 0xe0, + 0x1d, 0x69, 0x63, 0x3e, 0xa5, 0x52, 0x06, 0xe2, 0x74, 0xcb, 0x21, 0xbb, + 0x5f, 0x54, 0xa1, 0xce, 0x82, 0x5a, 0xfb, 0x02, 0x70, 0x55, 0x32, 0x16, + 0x40, 0xfd, 0xcf, 0x2a, 0xb1, 0xf1, 0x12, 0x7b, 0xe0, 0x05, 0x14, 0xd4, + 0xdf, 0x56, 0xc0, 0x12, 0x59, 0xcd, 0xe1, 0x2f, 0xf1, 0xac, 0x70, 0x1a, + 0x59, 0x5e, 0xb0, 0x7c, 0xa3, 0xa9, 0x09, 0x49, 0xd2, 0x32, 0x71, 0x5a, + 0xb7, 0xc9, 0x8a, 0xac, 0x75, 0xa5, 0x9f, 0x49, 0xc9, 0xb7, 0xd3, 0xa9, + 0x6d, 0x13, 0xc4, 0xba, 0x92, 0x71, 0xb8, 0x48, 0xe4, 0x59, 0x62, 0x03, + 0xa0, 0x35, 0x67, 0xf5, 0xe2, 0x12, 0x18, 0xf8, 0xa8, 0xff, 0x80, 0x67, + 0x77, 0xfb, 0x2a, 0x01, 0x88, 0x90, 0x9c, 0x3d, 0xd4, 0x0a, 0xb0, 0x70, + 0xd8, 0x3d, 0x57, 0x67, 0xba, 0xcb, 0x55, 0x53, 0x65, 0x44, 0x9e, 0xba, + 0x46, 0x50, 0x58, 0x0e, 0x80, 0x74, 0xa2, 0x3c, 0xb4, 0x05, 0x3d, 0x1f, + 0x23, 0x37, 0x61, 0x21, 0x30, 0x61, 0xba, 0x2b, 0x72, 0x2c, 0xac, 0xc2, + 0xdc, 0x4c, 0xd7, 0x8b, 0x6d, 0xdd, 0xe8, 0x40, 0x35, 0x4f, 0xa9, 0xf7, + 0x31, 0xe7, 0xca, 0xca, 0xb3, 0x2c, 0xda, 0x79, 0x78, 0x8e, 0x74, 0x25, + 0x46, 0xf3, 0xf0, 0x00, 0xbb, 0x3f, 0x50, 0x07, 0x23, 0x97, 0x17, 0xd1, + 0x59, 0xe0, 0x6c, 0xc8, 0x27, 0x1b, 0xb5, 0xcb, 0x77, 0x1a, 0x83, 0xf4, + 0x1d, 0xfd, 0xa6, 0xf8, 0x05, 0xc8 +}; +unsigned int ocsp_response_future_len = 2382; + +/* Stored basic OCSP response (revoked certificate). */ +unsigned char ocsp_response[] = { + 0x30, 0x82, 0x09, 0x4a, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x09, 0x43, 0x30, + 0x82, 0x09, 0x3f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x01, 0x04, 0x82, 0x09, 0x30, 0x30, 0x82, 0x09, 0x2c, 0x30, 0x81, + 0xa1, 0xa2, 0x16, 0x04, 0x14, 0x78, 0xe4, 0xb1, 0x1a, 0x09, 0xef, 0x04, + 0x88, 0x8b, 0x67, 0xbb, 0x81, 0x70, 0xe0, 0x18, 0x01, 0x36, 0xe4, 0x60, + 0xb3, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, 0x30, 0x33, 0x32, 0x37, 0x30, + 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x76, 0x30, 0x74, 0x30, 0x3b, + 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, + 0x14, 0x82, 0x94, 0x68, 0x3e, 0xa5, 0xf1, 0x04, 0x9e, 0xc6, 0x2b, 0x2b, + 0x02, 0xa5, 0xdd, 0x04, 0x7c, 0x1a, 0xfa, 0xf8, 0x0f, 0x04, 0x14, 0x64, + 0x15, 0xe2, 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, 0x3d, 0x1a, 0xe5, + 0x74, 0xe2, 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x02, 0x02, 0x10, 0x01, 0xa1, + 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x36, 0x30, 0x38, 0x32, 0x39, 0x30, + 0x35, 0x35, 0x38, 0x35, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, + 0x30, 0x33, 0x32, 0x37, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0xa0, + 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, 0x30, 0x33, 0x32, 0x37, 0x30, + 0x36, 0x30, 0x35, 0x30, 0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, + 0x01, 0x00, 0x78, 0x4d, 0x19, 0x33, 0xfe, 0x8d, 0x3f, 0xb1, 0x2b, 0x86, + 0xed, 0x2b, 0x8f, 0xfa, 0xf5, 0x8b, 0x72, 0xf4, 0x70, 0x05, 0x4d, 0x3b, + 0x04, 0xd6, 0x68, 0xae, 0x77, 0x18, 0x64, 0xc9, 0x53, 0xe1, 0x30, 0x20, + 0xb5, 0xf0, 0x05, 0x7e, 0xb3, 0x41, 0x23, 0x6e, 0x07, 0xef, 0xba, 0xc6, + 0x1b, 0x10, 0xb8, 0x74, 0x5a, 0x29, 0x33, 0x32, 0xc0, 0x37, 0x64, 0x16, + 0x2a, 0xd3, 0x07, 0x9d, 0xd8, 0xcc, 0xd4, 0x70, 0x8e, 0xd4, 0xc5, 0x55, + 0x1b, 0xe6, 0x62, 0x73, 0xed, 0x2f, 0x11, 0x0a, 0x8f, 0x0a, 0x58, 0xcb, + 0xbd, 0x5c, 0x9a, 0xd9, 0x10, 0xa7, 0xe8, 0x9e, 0xb6, 0x3a, 0x9f, 0x8f, + 0xcf, 0x52, 0xb4, 0xd6, 0x91, 0xb9, 0xa9, 0xa1, 0x51, 0x3a, 0x46, 0x10, + 0x67, 0xc0, 0xed, 0xd1, 0x23, 0x08, 0x00, 0x56, 0x89, 0x22, 0x8a, 0xfa, + 0x7c, 0x8a, 0x0a, 0x4c, 0x5a, 0x32, 0x1c, 0x6a, 0x20, 0x6d, 0x38, 0xd8, + 0x31, 0xc7, 0xcf, 0xba, 0xa6, 0x91, 0xed, 0xb7, 0x65, 0xaf, 0xbf, 0xdc, + 0xf7, 0x7c, 0x2f, 0x2c, 0x76, 0x86, 0x2c, 0x66, 0x94, 0x4b, 0x7c, 0xb7, + 0xac, 0x1d, 0x23, 0x03, 0xf7, 0x50, 0xc4, 0x38, 0xc8, 0x2f, 0xcf, 0x9e, + 0x4d, 0x41, 0x74, 0x45, 0xf1, 0xdd, 0xd6, 0xaa, 0xa7, 0xf4, 0xa3, 0x8f, + 0xe3, 0xa5, 0xf7, 0xdd, 0xaf, 0x99, 0xc3, 0x7f, 0xfe, 0x2f, 0x67, 0x48, + 0xeb, 0xbf, 0xca, 0xc6, 0xe8, 0x4c, 0x6b, 0x73, 0xdd, 0xe7, 0xb2, 0x7b, + 0xff, 0x2e, 0x22, 0x49, 0xe6, 0x46, 0xbd, 0x2f, 0xd3, 0x79, 0x1f, 0x86, + 0x56, 0x63, 0xaa, 0xa6, 0xf4, 0xd2, 0xaa, 0x4d, 0x0f, 0xdd, 0xce, 0xf9, + 0x80, 0x64, 0xf3, 0xc2, 0x3d, 0x75, 0xed, 0xba, 0x2f, 0x8d, 0x10, 0x01, + 0x4d, 0xaa, 0x2a, 0x82, 0x4b, 0x20, 0x75, 0x2e, 0x19, 0x2a, 0x22, 0x91, + 0xd9, 0x34, 0xb2, 0x4b, 0xfc, 0x14, 0xce, 0x3d, 0x36, 0x1a, 0x35, 0x98, + 0xdb, 0xdc, 0x20, 0x2e, 0x62, 0x70, 0x82, 0xf8, 0x4f, 0x76, 0x87, 0xad, + 0x40, 0x08, 0x60, 0x4b, 0xc9, 0x20, 0xd7, 0x56, 0x0f, 0x04, 0x1e, 0x82, + 0xe0, 0xf5, 0x95, 0x5d, 0x4d, 0x5d, 0xf8, 0x03, 0x5c, 0x78, 0xc0, 0x9e, + 0xe6, 0xfc, 0xa2, 0x05, 0x98, 0x32, 0x91, 0x50, 0xba, 0x31, 0xa0, 0x40, + 0x28, 0xe4, 0xd0, 0x0c, 0x96, 0x4b, 0x1e, 0x6b, 0x2a, 0x35, 0xcf, 0xe2, + 0xf4, 0x0d, 0xf6, 0x9e, 0xf3, 0xaa, 0x28, 0xba, 0x7d, 0xd8, 0xba, 0x11, + 0xb5, 0xd0, 0xa1, 0xb5, 0x89, 0x45, 0x02, 0x6f, 0x6d, 0x24, 0x2f, 0x29, + 0x5f, 0xfd, 0x38, 0x6e, 0xde, 0x08, 0x8d, 0x4f, 0xa0, 0xa7, 0x4c, 0x83, + 0x0c, 0x13, 0x8f, 0x1c, 0x04, 0x0d, 0xaa, 0xd2, 0x19, 0x4b, 0x9e, 0x56, + 0x1b, 0xe9, 0x4e, 0x61, 0xcb, 0xa0, 0x56, 0xc5, 0x47, 0x34, 0xba, 0xb9, + 0x30, 0xfd, 0xa3, 0xbb, 0x36, 0x09, 0x45, 0x2c, 0x81, 0x4f, 0xfe, 0xd4, + 0x03, 0xbf, 0x9f, 0xfc, 0xcf, 0x29, 0x66, 0x23, 0x7c, 0x74, 0x91, 0xd5, + 0xde, 0x1c, 0x5f, 0x08, 0x22, 0x3f, 0x01, 0x51, 0x0e, 0x6c, 0x2f, 0x4c, + 0x48, 0x8b, 0x68, 0xa9, 0x38, 0x8a, 0xd7, 0xc7, 0xea, 0x4b, 0xac, 0x79, + 0xa2, 0xff, 0xff, 0x69, 0x49, 0x7f, 0x99, 0x8d, 0x68, 0x57, 0xfd, 0xac, + 0xbb, 0xc1, 0xdf, 0xaa, 0x9f, 0x67, 0x33, 0xd4, 0xf2, 0xb8, 0xe3, 0x64, + 0xaa, 0x53, 0xd6, 0x80, 0x5e, 0x15, 0x35, 0x0c, 0xa5, 0xa9, 0x07, 0x6a, + 0xe7, 0xaf, 0x98, 0x9c, 0x46, 0xce, 0x51, 0x60, 0x32, 0x17, 0x5c, 0x10, + 0x4d, 0x42, 0x79, 0xa1, 0xc2, 0x63, 0xe9, 0x1b, 0x92, 0x52, 0x1e, 0x44, + 0xd8, 0x7d, 0x2c, 0x76, 0x68, 0x0b, 0xd5, 0xda, 0x1b, 0xa2, 0xcc, 0xd1, + 0xdd, 0x2d, 0xa5, 0x76, 0x5f, 0x39, 0xae, 0xb3, 0x32, 0x14, 0xa0, 0x82, + 0x06, 0x70, 0x30, 0x82, 0x06, 0x6c, 0x30, 0x82, 0x06, 0x68, 0x30, 0x82, + 0x04, 0x50, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, 0x02, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x81, 0xc0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x07, 0x55, 0x75, 0x73, 0x69, 0x6d, 0x61, 0x61, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x10, 0x49, + 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x4f, 0x79, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x28, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x22, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x20, 0x43, 0x41, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x40, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, + 0x38, 0x32, 0x39, 0x30, 0x36, 0x30, 0x38, 0x30, 0x31, 0x5a, 0x17, 0x0d, + 0x31, 0x39, 0x30, 0x35, 0x32, 0x36, 0x30, 0x36, 0x30, 0x38, 0x30, 0x31, + 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x07, 0x55, 0x75, 0x73, 0x69, 0x6d, 0x61, 0x61, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, + 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x10, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x4f, 0x79, 0x31, 0x1b, 0x30, + 0x19, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x12, 0x49, 0x4e, 0x53, 0x49, + 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, + 0x73, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x1a, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x40, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xdd, 0xbb, 0xb9, 0x27, 0x84, 0xb2, 0x02, 0x93, 0xdc, 0x68, + 0xe6, 0x06, 0x56, 0xe8, 0xed, 0xcc, 0x4b, 0x0b, 0x11, 0x05, 0x20, 0x72, + 0x1a, 0x1a, 0x08, 0x09, 0xc2, 0x60, 0x33, 0x79, 0x4b, 0xeb, 0xfb, 0x7f, + 0xa1, 0xf3, 0x22, 0xc2, 0xf7, 0x71, 0xe7, 0x0a, 0x5b, 0x81, 0xd1, 0x20, + 0x0a, 0x85, 0xfb, 0x0e, 0x66, 0x33, 0x35, 0x2b, 0x8d, 0x78, 0xf5, 0xd6, + 0x43, 0x0b, 0xe5, 0xce, 0xf8, 0x4a, 0x47, 0x88, 0x03, 0x14, 0x16, 0xb7, + 0xbf, 0x1c, 0xf8, 0x95, 0x9b, 0xac, 0xec, 0x07, 0x9e, 0xa4, 0x91, 0x59, + 0x89, 0xe1, 0xe1, 0xee, 0xaf, 0x4c, 0x7a, 0x98, 0x64, 0x27, 0xe8, 0x63, + 0x0e, 0xd7, 0x75, 0x50, 0x35, 0x6a, 0x53, 0xba, 0x42, 0xb9, 0xc0, 0x11, + 0x1d, 0x6c, 0xf7, 0x22, 0xcf, 0xc5, 0x7a, 0x7d, 0x8f, 0xd2, 0xef, 0x66, + 0x5c, 0xef, 0x93, 0x91, 0x02, 0x8e, 0x2d, 0xac, 0x43, 0x16, 0xd5, 0xc1, + 0xda, 0xdf, 0xcc, 0x6c, 0xc5, 0x03, 0xcb, 0xd5, 0x2d, 0x99, 0xee, 0x93, + 0x7e, 0x62, 0x38, 0x9f, 0xe2, 0x41, 0xe2, 0xe2, 0x55, 0x54, 0xd0, 0xf7, + 0xc7, 0xff, 0x11, 0x99, 0x8c, 0xd1, 0x99, 0x1e, 0xf8, 0x3c, 0xa5, 0x68, + 0xfb, 0x4f, 0x2a, 0x6a, 0x2a, 0x39, 0xf0, 0x19, 0xfc, 0x8e, 0x09, 0x81, + 0x7d, 0xae, 0x7f, 0x6b, 0xdd, 0x54, 0xac, 0x84, 0x48, 0x51, 0x01, 0x6d, + 0x53, 0xe7, 0xb6, 0xf7, 0x7a, 0x67, 0x73, 0x7c, 0xe8, 0x82, 0x70, 0xc4, + 0x4e, 0x62, 0x98, 0xc2, 0x2c, 0x66, 0xe6, 0xbd, 0xcd, 0xda, 0x82, 0x7d, + 0x4a, 0xf7, 0xb3, 0x60, 0x5f, 0x75, 0x26, 0xfd, 0x5f, 0x5c, 0xa1, 0x42, + 0xd3, 0xed, 0x06, 0x31, 0x48, 0x54, 0xd1, 0xd7, 0x8f, 0x53, 0x14, 0xb1, + 0x80, 0x81, 0x8f, 0x8f, 0x7a, 0x7d, 0x1f, 0xf9, 0xfa, 0x6a, 0x9e, 0xdf, + 0xb0, 0x02, 0x3a, 0x5f, 0x31, 0x28, 0x3d, 0xe0, 0xfb, 0x06, 0xed, 0x35, + 0x11, 0x4e, 0x99, 0x05, 0xef, 0x7a, 0xb4, 0xa3, 0x52, 0xec, 0x55, 0x8d, + 0xf2, 0xc4, 0x0d, 0x41, 0xb0, 0x2e, 0x61, 0xdf, 0x7d, 0x11, 0x23, 0x07, + 0x00, 0xf1, 0x7d, 0x7b, 0xeb, 0xfc, 0xcd, 0xf6, 0x2e, 0xa3, 0xbf, 0x17, + 0xe9, 0x92, 0x75, 0xd6, 0x80, 0x79, 0x22, 0x1e, 0xa6, 0x71, 0x42, 0x62, + 0x65, 0x48, 0xe8, 0x7a, 0x03, 0xf5, 0x30, 0x37, 0x2b, 0xa8, 0xb4, 0x3d, + 0x9a, 0xb5, 0xb4, 0xf7, 0x0a, 0x51, 0x64, 0xff, 0x33, 0x3d, 0x79, 0x43, + 0x08, 0xa9, 0xda, 0x83, 0x6e, 0xcc, 0x1c, 0x98, 0x02, 0x33, 0x0f, 0xe3, + 0x88, 0x02, 0x28, 0x94, 0x88, 0xcf, 0xea, 0xf9, 0x29, 0x59, 0x9b, 0x8c, + 0x46, 0x23, 0x96, 0x8a, 0x2a, 0x3a, 0x46, 0xa8, 0x9b, 0x8b, 0x41, 0x77, + 0x7f, 0xb9, 0x8e, 0x79, 0xc7, 0x9a, 0x39, 0x0c, 0xa2, 0xf8, 0xe7, 0xf7, + 0x28, 0x50, 0xa3, 0x79, 0x09, 0xd4, 0x7a, 0xa4, 0xba, 0x6b, 0xdf, 0xb2, + 0xd3, 0x5f, 0x47, 0x10, 0x49, 0x91, 0xa8, 0x68, 0xe7, 0x2d, 0x13, 0x9d, + 0x18, 0xd0, 0x7f, 0x43, 0xf9, 0x32, 0x81, 0x98, 0x15, 0x7f, 0x7a, 0x6a, + 0xc3, 0x52, 0x6f, 0x9b, 0xf7, 0xaf, 0xd2, 0x50, 0x2b, 0x54, 0x0e, 0x63, + 0x88, 0x98, 0x2e, 0xeb, 0x1c, 0x31, 0x9d, 0xa6, 0xda, 0xfd, 0xfd, 0x6d, + 0x9d, 0xbb, 0xb8, 0x7f, 0x16, 0x99, 0x7b, 0xfd, 0xc8, 0x7d, 0x21, 0xe9, + 0x05, 0x25, 0xe3, 0xc0, 0x4a, 0x1a, 0x69, 0x95, 0xed, 0xa8, 0xb1, 0x8c, + 0x60, 0xb5, 0xee, 0xd7, 0x36, 0x49, 0x2b, 0xd3, 0x00, 0x04, 0xda, 0x16, + 0x41, 0xa3, 0xd0, 0x38, 0x1b, 0xf2, 0xfc, 0x23, 0x22, 0xcf, 0xe4, 0x62, + 0xee, 0x95, 0x3f, 0x0f, 0x7f, 0x89, 0xb0, 0x56, 0x20, 0x3e, 0xd9, 0xff, + 0x14, 0x91, 0xe7, 0x32, 0x1f, 0xcd, 0x55, 0x7a, 0x1a, 0x43, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x78, 0xe4, 0xb1, 0x1a, 0x09, 0xef, 0x04, + 0x88, 0x8b, 0x67, 0xbb, 0x81, 0x70, 0xe0, 0x18, 0x01, 0x36, 0xe4, 0x60, + 0xb3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x64, 0x15, 0xe2, 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, + 0x3d, 0x1a, 0xe5, 0x74, 0xe2, 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, + 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x04, 0xd8, + 0x13, 0x9f, 0x61, 0x0c, 0xcc, 0x49, 0x72, 0xf9, 0x66, 0x62, 0xb6, 0xdc, + 0x10, 0x7e, 0x44, 0x2e, 0x07, 0x44, 0x0a, 0x75, 0x00, 0xf7, 0x85, 0x95, + 0x11, 0x8b, 0xc7, 0xd3, 0xf6, 0x67, 0x4f, 0x14, 0x80, 0x93, 0x3b, 0xb0, + 0x35, 0xa3, 0x55, 0xef, 0xe8, 0xb5, 0x0c, 0x37, 0xaa, 0xc2, 0x86, 0x4b, + 0x59, 0x69, 0x5b, 0x87, 0x05, 0xe7, 0x5e, 0x20, 0x32, 0x16, 0x62, 0xe1, + 0xeb, 0x04, 0x47, 0xec, 0x77, 0x46, 0x08, 0x72, 0xe2, 0xd7, 0x8c, 0xb4, + 0xd8, 0x33, 0x2c, 0x26, 0xee, 0xb1, 0x30, 0xe6, 0xe8, 0x97, 0xde, 0x21, + 0x71, 0x25, 0xcd, 0x83, 0xee, 0x6c, 0x59, 0x7a, 0x75, 0x0f, 0xdb, 0x89, + 0x21, 0x72, 0x47, 0xe2, 0x0a, 0x8a, 0xb4, 0x10, 0x4e, 0xd1, 0xb9, 0x54, + 0x5e, 0xd1, 0x9d, 0x99, 0xe9, 0x4d, 0x99, 0x74, 0x62, 0x92, 0xe1, 0x68, + 0x5a, 0xb4, 0x8e, 0x4d, 0x46, 0xc4, 0x04, 0x1d, 0xc0, 0x5f, 0xf9, 0xa0, + 0x08, 0x88, 0x2c, 0x49, 0xdf, 0x39, 0x39, 0x9c, 0x6b, 0xdc, 0x7c, 0x61, + 0xd3, 0x26, 0xf3, 0x3c, 0xd2, 0x5e, 0xf5, 0xee, 0x5d, 0x91, 0x47, 0x7f, + 0x0e, 0xee, 0x77, 0x81, 0x23, 0x72, 0x62, 0xcf, 0x01, 0x68, 0x4e, 0x8c, + 0x78, 0xb8, 0x47, 0xb8, 0x33, 0x6f, 0x0f, 0x38, 0x41, 0x41, 0x42, 0x6e, + 0x25, 0xe9, 0xb1, 0x3d, 0x3a, 0x2f, 0x4e, 0x01, 0xa0, 0xfd, 0x98, 0x2a, + 0x96, 0x94, 0xc6, 0xd6, 0x81, 0x68, 0x2a, 0x8d, 0x06, 0x85, 0x9e, 0x3e, + 0x13, 0xf1, 0x21, 0xef, 0xf3, 0x87, 0xc8, 0xc1, 0xf1, 0x16, 0x21, 0x49, + 0x45, 0x2c, 0xa4, 0x85, 0x15, 0x3d, 0xfc, 0x0e, 0x39, 0x75, 0xe8, 0x8c, + 0x23, 0xba, 0x2d, 0x24, 0x9f, 0x72, 0xfb, 0x37, 0x89, 0xbb, 0x02, 0x90, + 0xd1, 0x1f, 0x93, 0x4d, 0xdb, 0x8d, 0x25, 0x87, 0xff, 0x62, 0xc9, 0x38, + 0x4c, 0x87, 0xfe, 0xa2, 0xec, 0x00, 0x29, 0x3e, 0xa0, 0x6c, 0x4f, 0x6c, + 0x91, 0x8b, 0x61, 0xad, 0xbe, 0xa7, 0x34, 0x4d, 0xd3, 0xc6, 0xae, 0x04, + 0x57, 0x78, 0xf1, 0x9d, 0x46, 0x93, 0x8f, 0x70, 0x64, 0xea, 0x64, 0x93, + 0xb3, 0x06, 0xb3, 0xbb, 0x58, 0x88, 0xd7, 0x27, 0x55, 0xe0, 0x47, 0x94, + 0x13, 0x0c, 0xb5, 0x8c, 0xc0, 0x15, 0x04, 0x8c, 0x3a, 0xd5, 0x83, 0xe0, + 0x1d, 0x69, 0x63, 0x3e, 0xa5, 0x52, 0x06, 0xe2, 0x74, 0xcb, 0x21, 0xbb, + 0x5f, 0x54, 0xa1, 0xce, 0x82, 0x5a, 0xfb, 0x02, 0x70, 0x55, 0x32, 0x16, + 0x40, 0xfd, 0xcf, 0x2a, 0xb1, 0xf1, 0x12, 0x7b, 0xe0, 0x05, 0x14, 0xd4, + 0xdf, 0x56, 0xc0, 0x12, 0x59, 0xcd, 0xe1, 0x2f, 0xf1, 0xac, 0x70, 0x1a, + 0x59, 0x5e, 0xb0, 0x7c, 0xa3, 0xa9, 0x09, 0x49, 0xd2, 0x32, 0x71, 0x5a, + 0xb7, 0xc9, 0x8a, 0xac, 0x75, 0xa5, 0x9f, 0x49, 0xc9, 0xb7, 0xd3, 0xa9, + 0x6d, 0x13, 0xc4, 0xba, 0x92, 0x71, 0xb8, 0x48, 0xe4, 0x59, 0x62, 0x03, + 0xa0, 0x35, 0x67, 0xf5, 0xe2, 0x12, 0x18, 0xf8, 0xa8, 0xff, 0x80, 0x67, + 0x77, 0xfb, 0x2a, 0x01, 0x88, 0x90, 0x9c, 0x3d, 0xd4, 0x0a, 0xb0, 0x70, + 0xd8, 0x3d, 0x57, 0x67, 0xba, 0xcb, 0x55, 0x53, 0x65, 0x44, 0x9e, 0xba, + 0x46, 0x50, 0x58, 0x0e, 0x80, 0x74, 0xa2, 0x3c, 0xb4, 0x05, 0x3d, 0x1f, + 0x23, 0x37, 0x61, 0x21, 0x30, 0x61, 0xba, 0x2b, 0x72, 0x2c, 0xac, 0xc2, + 0xdc, 0x4c, 0xd7, 0x8b, 0x6d, 0xdd, 0xe8, 0x40, 0x35, 0x4f, 0xa9, 0xf7, + 0x31, 0xe7, 0xca, 0xca, 0xb3, 0x2c, 0xda, 0x79, 0x78, 0x8e, 0x74, 0x25, + 0x46, 0xf3, 0xf0, 0x00, 0xbb, 0x3f, 0x50, 0x07, 0x23, 0x97, 0x17, 0xd1, + 0x59, 0xe0, 0x6c, 0xc8, 0x27, 0x1b, 0xb5, 0xcb, 0x77, 0x1a, 0x83, 0xf4, + 0x1d, 0xfd, 0xa6, 0xf8, 0x05, 0xc8 +}; +unsigned int ocsp_response_len = 2382; + +/* Response with SHA-512 hash algorithm, generated using: + faketime '2017-03-27 09:00:00' openssl ocsp -rmd sha512 -resp_key_id -index ../../index.txt -VAfile ../../certs/ocsp.insidesecure-test.com.cert.pem -CA ../../certs/ca-chain.cert.pem -rsigner ../../certs/ocsp.insidesecure-test.com.cert.pem -rkey ../../private/ocsp.insidesecure-test.com.key-nopass.pem -nmin 5 -noverify -reqin /tmp/request -respout /tmp/response -resp_text */ +unsigned char ocsp_response_sha512[] = { + 0x30, 0x82, 0x09, 0x4a, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x09, 0x43, 0x30, + 0x82, 0x09, 0x3f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x01, 0x04, 0x82, 0x09, 0x30, 0x30, 0x82, 0x09, 0x2c, 0x30, 0x81, + 0xa1, 0xa2, 0x16, 0x04, 0x14, 0x78, 0xe4, 0xb1, 0x1a, 0x09, 0xef, 0x04, + 0x88, 0x8b, 0x67, 0xbb, 0x81, 0x70, 0xe0, 0x18, 0x01, 0x36, 0xe4, 0x60, + 0xb3, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, 0x30, 0x33, 0x32, 0x37, 0x30, + 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x76, 0x30, 0x74, 0x30, 0x3b, + 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, + 0x14, 0x82, 0x94, 0x68, 0x3e, 0xa5, 0xf1, 0x04, 0x9e, 0xc6, 0x2b, 0x2b, + 0x02, 0xa5, 0xdd, 0x04, 0x7c, 0x1a, 0xfa, 0xf8, 0x0f, 0x04, 0x14, 0x64, + 0x15, 0xe2, 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, 0x3d, 0x1a, 0xe5, + 0x74, 0xe2, 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x02, 0x02, 0x10, 0x01, 0xa1, + 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x36, 0x30, 0x38, 0x32, 0x39, 0x30, + 0x35, 0x35, 0x38, 0x35, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, + 0x30, 0x33, 0x32, 0x37, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0xa0, + 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x37, 0x30, 0x33, 0x32, 0x37, 0x30, + 0x36, 0x30, 0x35, 0x30, 0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x03, 0x82, 0x02, + 0x01, 0x00, 0xb2, 0x55, 0xd2, 0xee, 0x3a, 0xc7, 0xe1, 0x00, 0xa2, 0xef, + 0xa8, 0xa0, 0x66, 0x27, 0x64, 0xf9, 0x4a, 0xfc, 0xf0, 0x34, 0xc3, 0x94, + 0xd3, 0x8c, 0x9f, 0x85, 0x37, 0x31, 0x6a, 0x7b, 0xc0, 0x0f, 0x7c, 0x13, + 0xc7, 0xdd, 0x4b, 0xf1, 0xd2, 0xd0, 0xfd, 0xa9, 0x8c, 0x4a, 0x24, 0x28, + 0xe1, 0xa5, 0x13, 0x02, 0xf6, 0x18, 0x50, 0x05, 0xc3, 0x6c, 0x53, 0x6e, + 0xe1, 0xf0, 0xeb, 0x5b, 0xef, 0xea, 0x20, 0x54, 0x36, 0x9f, 0x45, 0x82, + 0x1b, 0x41, 0x92, 0x0f, 0xbf, 0xa2, 0xa8, 0x85, 0x5c, 0x06, 0x2d, 0x37, + 0xb4, 0x7c, 0x07, 0x60, 0x78, 0xe8, 0x66, 0x6b, 0xa7, 0x3e, 0xea, 0x5c, + 0xb2, 0x86, 0xe8, 0x77, 0x18, 0x9b, 0xdb, 0x6d, 0xdd, 0x62, 0x6a, 0x40, + 0xf8, 0xe3, 0x1b, 0x67, 0x69, 0xb4, 0x7d, 0x60, 0x02, 0x72, 0x53, 0xfd, + 0x11, 0x16, 0xb8, 0xeb, 0x18, 0x9d, 0x0c, 0xa9, 0xdc, 0x59, 0xce, 0x41, + 0xcd, 0xf8, 0xd7, 0xfa, 0xef, 0x0d, 0x41, 0x52, 0x12, 0xd7, 0x4e, 0x22, + 0x5d, 0x9a, 0xdf, 0xa8, 0x2a, 0x11, 0x0c, 0xed, 0x75, 0xf0, 0x25, 0xfc, + 0x06, 0x0a, 0x3c, 0xb3, 0x5e, 0xde, 0x7a, 0xc3, 0xf6, 0xbf, 0xc7, 0x23, + 0x6d, 0xc3, 0xdc, 0x09, 0x49, 0x96, 0x8e, 0x41, 0xa8, 0xaa, 0xe8, 0x9e, + 0xa0, 0x02, 0x20, 0x22, 0x44, 0xc0, 0xae, 0xbd, 0x0b, 0xa9, 0x7c, 0xb0, + 0x91, 0xa9, 0x15, 0x5b, 0x36, 0x66, 0xfe, 0xae, 0x44, 0xa5, 0xe2, 0xba, + 0x7f, 0xcb, 0xf2, 0x78, 0xdc, 0xb7, 0x10, 0x09, 0x30, 0x24, 0xaa, 0x61, + 0x12, 0x37, 0x91, 0x2b, 0x75, 0xe4, 0x3c, 0x69, 0x70, 0x34, 0x62, 0x6c, + 0x14, 0xfd, 0x4b, 0x19, 0xe0, 0x96, 0xfa, 0x95, 0x24, 0x46, 0x83, 0x70, + 0xc0, 0x36, 0x93, 0x5b, 0x98, 0x9a, 0x20, 0x41, 0x8a, 0x33, 0x80, 0xd1, + 0x84, 0xcf, 0x82, 0xfc, 0x0c, 0x5d, 0xe7, 0x03, 0x35, 0x78, 0x0b, 0x29, + 0xe2, 0x5b, 0x76, 0x5b, 0x0f, 0xfd, 0xa7, 0x3a, 0x40, 0xe9, 0x56, 0x12, + 0x4c, 0x52, 0x34, 0xce, 0x37, 0x92, 0xfd, 0xa5, 0xf4, 0x5f, 0x38, 0xf1, + 0xeb, 0xb3, 0xc4, 0xc4, 0x72, 0x7f, 0x91, 0xa5, 0x8d, 0x86, 0x36, 0x2b, + 0xac, 0x7b, 0x71, 0xc0, 0x2a, 0x4c, 0xde, 0x72, 0x79, 0x62, 0x28, 0x4c, + 0x92, 0x87, 0xe1, 0x45, 0x5d, 0x7a, 0xf4, 0xb6, 0x00, 0x5d, 0x91, 0x9a, + 0xa5, 0xb3, 0xae, 0x49, 0xa5, 0x4e, 0xea, 0x98, 0x7d, 0x1c, 0x8d, 0xf5, + 0xa5, 0x75, 0xae, 0x06, 0xe5, 0xa4, 0x6e, 0x0a, 0x65, 0x7e, 0x21, 0xa4, + 0x7c, 0x95, 0xcd, 0x52, 0xcc, 0x20, 0x5a, 0x55, 0xad, 0x86, 0x2a, 0x09, + 0x96, 0x1b, 0x94, 0xbb, 0x15, 0xbb, 0x04, 0xdd, 0xd1, 0x90, 0xdd, 0x39, + 0x27, 0x29, 0xff, 0x80, 0xd8, 0x9f, 0x65, 0x99, 0xcb, 0x41, 0xe6, 0xd2, + 0x8f, 0xbd, 0xb0, 0xd5, 0x56, 0x02, 0x7b, 0x3b, 0x7a, 0xc2, 0xfb, 0xd0, + 0x3a, 0x72, 0x52, 0x86, 0x6b, 0x53, 0xd3, 0xc7, 0xc1, 0xbb, 0x47, 0x52, + 0x58, 0x72, 0x19, 0x6f, 0xb8, 0x95, 0xc3, 0x86, 0x3b, 0x67, 0xf8, 0xda, + 0x34, 0x1d, 0x67, 0xb6, 0xe9, 0x7e, 0x62, 0xbd, 0x9e, 0x8f, 0x9b, 0xd1, + 0x81, 0x5b, 0x03, 0x4b, 0x0f, 0x3e, 0xef, 0xe8, 0x80, 0x40, 0x26, 0x8a, + 0x58, 0x53, 0x7d, 0x94, 0x57, 0xba, 0x10, 0x8d, 0xac, 0xea, 0x85, 0x67, + 0xcc, 0x35, 0x16, 0x48, 0x6b, 0x7f, 0xc8, 0x6b, 0x5f, 0x44, 0xb4, 0x89, + 0x4d, 0x95, 0x58, 0xd2, 0xe0, 0xb8, 0x2a, 0x26, 0x17, 0xed, 0x49, 0x63, + 0x4e, 0x64, 0x3e, 0x9e, 0x72, 0x36, 0xaf, 0xb8, 0x84, 0xa0, 0x3f, 0x18, + 0xae, 0x0d, 0x91, 0x9c, 0x9e, 0x65, 0x2d, 0xb7, 0xf2, 0x0b, 0xcf, 0xec, + 0x49, 0xc6, 0x9f, 0xca, 0x23, 0x19, 0x91, 0x9d, 0xf4, 0x97, 0xa0, 0x82, + 0x06, 0x70, 0x30, 0x82, 0x06, 0x6c, 0x30, 0x82, 0x06, 0x68, 0x30, 0x82, + 0x04, 0x50, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, 0x02, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x30, 0x81, 0xc0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x07, 0x55, 0x75, 0x73, 0x69, 0x6d, 0x61, 0x61, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x10, 0x49, + 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x4f, 0x79, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x28, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x22, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x20, 0x43, 0x41, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x40, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, + 0x38, 0x32, 0x39, 0x30, 0x36, 0x30, 0x38, 0x30, 0x31, 0x5a, 0x17, 0x0d, + 0x31, 0x39, 0x30, 0x35, 0x32, 0x36, 0x30, 0x36, 0x30, 0x38, 0x30, 0x31, + 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x07, 0x55, 0x75, 0x73, 0x69, 0x6d, 0x61, 0x61, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, + 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x10, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x4f, 0x79, 0x31, 0x1b, 0x30, + 0x19, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x12, 0x49, 0x4e, 0x53, 0x49, + 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, + 0x73, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x1a, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x24, 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x15, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x40, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xdd, 0xbb, 0xb9, 0x27, 0x84, 0xb2, 0x02, 0x93, 0xdc, 0x68, + 0xe6, 0x06, 0x56, 0xe8, 0xed, 0xcc, 0x4b, 0x0b, 0x11, 0x05, 0x20, 0x72, + 0x1a, 0x1a, 0x08, 0x09, 0xc2, 0x60, 0x33, 0x79, 0x4b, 0xeb, 0xfb, 0x7f, + 0xa1, 0xf3, 0x22, 0xc2, 0xf7, 0x71, 0xe7, 0x0a, 0x5b, 0x81, 0xd1, 0x20, + 0x0a, 0x85, 0xfb, 0x0e, 0x66, 0x33, 0x35, 0x2b, 0x8d, 0x78, 0xf5, 0xd6, + 0x43, 0x0b, 0xe5, 0xce, 0xf8, 0x4a, 0x47, 0x88, 0x03, 0x14, 0x16, 0xb7, + 0xbf, 0x1c, 0xf8, 0x95, 0x9b, 0xac, 0xec, 0x07, 0x9e, 0xa4, 0x91, 0x59, + 0x89, 0xe1, 0xe1, 0xee, 0xaf, 0x4c, 0x7a, 0x98, 0x64, 0x27, 0xe8, 0x63, + 0x0e, 0xd7, 0x75, 0x50, 0x35, 0x6a, 0x53, 0xba, 0x42, 0xb9, 0xc0, 0x11, + 0x1d, 0x6c, 0xf7, 0x22, 0xcf, 0xc5, 0x7a, 0x7d, 0x8f, 0xd2, 0xef, 0x66, + 0x5c, 0xef, 0x93, 0x91, 0x02, 0x8e, 0x2d, 0xac, 0x43, 0x16, 0xd5, 0xc1, + 0xda, 0xdf, 0xcc, 0x6c, 0xc5, 0x03, 0xcb, 0xd5, 0x2d, 0x99, 0xee, 0x93, + 0x7e, 0x62, 0x38, 0x9f, 0xe2, 0x41, 0xe2, 0xe2, 0x55, 0x54, 0xd0, 0xf7, + 0xc7, 0xff, 0x11, 0x99, 0x8c, 0xd1, 0x99, 0x1e, 0xf8, 0x3c, 0xa5, 0x68, + 0xfb, 0x4f, 0x2a, 0x6a, 0x2a, 0x39, 0xf0, 0x19, 0xfc, 0x8e, 0x09, 0x81, + 0x7d, 0xae, 0x7f, 0x6b, 0xdd, 0x54, 0xac, 0x84, 0x48, 0x51, 0x01, 0x6d, + 0x53, 0xe7, 0xb6, 0xf7, 0x7a, 0x67, 0x73, 0x7c, 0xe8, 0x82, 0x70, 0xc4, + 0x4e, 0x62, 0x98, 0xc2, 0x2c, 0x66, 0xe6, 0xbd, 0xcd, 0xda, 0x82, 0x7d, + 0x4a, 0xf7, 0xb3, 0x60, 0x5f, 0x75, 0x26, 0xfd, 0x5f, 0x5c, 0xa1, 0x42, + 0xd3, 0xed, 0x06, 0x31, 0x48, 0x54, 0xd1, 0xd7, 0x8f, 0x53, 0x14, 0xb1, + 0x80, 0x81, 0x8f, 0x8f, 0x7a, 0x7d, 0x1f, 0xf9, 0xfa, 0x6a, 0x9e, 0xdf, + 0xb0, 0x02, 0x3a, 0x5f, 0x31, 0x28, 0x3d, 0xe0, 0xfb, 0x06, 0xed, 0x35, + 0x11, 0x4e, 0x99, 0x05, 0xef, 0x7a, 0xb4, 0xa3, 0x52, 0xec, 0x55, 0x8d, + 0xf2, 0xc4, 0x0d, 0x41, 0xb0, 0x2e, 0x61, 0xdf, 0x7d, 0x11, 0x23, 0x07, + 0x00, 0xf1, 0x7d, 0x7b, 0xeb, 0xfc, 0xcd, 0xf6, 0x2e, 0xa3, 0xbf, 0x17, + 0xe9, 0x92, 0x75, 0xd6, 0x80, 0x79, 0x22, 0x1e, 0xa6, 0x71, 0x42, 0x62, + 0x65, 0x48, 0xe8, 0x7a, 0x03, 0xf5, 0x30, 0x37, 0x2b, 0xa8, 0xb4, 0x3d, + 0x9a, 0xb5, 0xb4, 0xf7, 0x0a, 0x51, 0x64, 0xff, 0x33, 0x3d, 0x79, 0x43, + 0x08, 0xa9, 0xda, 0x83, 0x6e, 0xcc, 0x1c, 0x98, 0x02, 0x33, 0x0f, 0xe3, + 0x88, 0x02, 0x28, 0x94, 0x88, 0xcf, 0xea, 0xf9, 0x29, 0x59, 0x9b, 0x8c, + 0x46, 0x23, 0x96, 0x8a, 0x2a, 0x3a, 0x46, 0xa8, 0x9b, 0x8b, 0x41, 0x77, + 0x7f, 0xb9, 0x8e, 0x79, 0xc7, 0x9a, 0x39, 0x0c, 0xa2, 0xf8, 0xe7, 0xf7, + 0x28, 0x50, 0xa3, 0x79, 0x09, 0xd4, 0x7a, 0xa4, 0xba, 0x6b, 0xdf, 0xb2, + 0xd3, 0x5f, 0x47, 0x10, 0x49, 0x91, 0xa8, 0x68, 0xe7, 0x2d, 0x13, 0x9d, + 0x18, 0xd0, 0x7f, 0x43, 0xf9, 0x32, 0x81, 0x98, 0x15, 0x7f, 0x7a, 0x6a, + 0xc3, 0x52, 0x6f, 0x9b, 0xf7, 0xaf, 0xd2, 0x50, 0x2b, 0x54, 0x0e, 0x63, + 0x88, 0x98, 0x2e, 0xeb, 0x1c, 0x31, 0x9d, 0xa6, 0xda, 0xfd, 0xfd, 0x6d, + 0x9d, 0xbb, 0xb8, 0x7f, 0x16, 0x99, 0x7b, 0xfd, 0xc8, 0x7d, 0x21, 0xe9, + 0x05, 0x25, 0xe3, 0xc0, 0x4a, 0x1a, 0x69, 0x95, 0xed, 0xa8, 0xb1, 0x8c, + 0x60, 0xb5, 0xee, 0xd7, 0x36, 0x49, 0x2b, 0xd3, 0x00, 0x04, 0xda, 0x16, + 0x41, 0xa3, 0xd0, 0x38, 0x1b, 0xf2, 0xfc, 0x23, 0x22, 0xcf, 0xe4, 0x62, + 0xee, 0x95, 0x3f, 0x0f, 0x7f, 0x89, 0xb0, 0x56, 0x20, 0x3e, 0xd9, 0xff, + 0x14, 0x91, 0xe7, 0x32, 0x1f, 0xcd, 0x55, 0x7a, 0x1a, 0x43, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x75, 0x30, 0x73, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x78, 0xe4, 0xb1, 0x1a, 0x09, 0xef, 0x04, + 0x88, 0x8b, 0x67, 0xbb, 0x81, 0x70, 0xe0, 0x18, 0x01, 0x36, 0xe4, 0x60, + 0xb3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x64, 0x15, 0xe2, 0x5e, 0x3e, 0x88, 0x1a, 0xdd, 0x6d, 0x29, + 0x3d, 0x1a, 0xe5, 0x74, 0xe2, 0xdb, 0x4f, 0xf3, 0x06, 0xb4, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x07, 0x80, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, + 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x04, 0xd8, + 0x13, 0x9f, 0x61, 0x0c, 0xcc, 0x49, 0x72, 0xf9, 0x66, 0x62, 0xb6, 0xdc, + 0x10, 0x7e, 0x44, 0x2e, 0x07, 0x44, 0x0a, 0x75, 0x00, 0xf7, 0x85, 0x95, + 0x11, 0x8b, 0xc7, 0xd3, 0xf6, 0x67, 0x4f, 0x14, 0x80, 0x93, 0x3b, 0xb0, + 0x35, 0xa3, 0x55, 0xef, 0xe8, 0xb5, 0x0c, 0x37, 0xaa, 0xc2, 0x86, 0x4b, + 0x59, 0x69, 0x5b, 0x87, 0x05, 0xe7, 0x5e, 0x20, 0x32, 0x16, 0x62, 0xe1, + 0xeb, 0x04, 0x47, 0xec, 0x77, 0x46, 0x08, 0x72, 0xe2, 0xd7, 0x8c, 0xb4, + 0xd8, 0x33, 0x2c, 0x26, 0xee, 0xb1, 0x30, 0xe6, 0xe8, 0x97, 0xde, 0x21, + 0x71, 0x25, 0xcd, 0x83, 0xee, 0x6c, 0x59, 0x7a, 0x75, 0x0f, 0xdb, 0x89, + 0x21, 0x72, 0x47, 0xe2, 0x0a, 0x8a, 0xb4, 0x10, 0x4e, 0xd1, 0xb9, 0x54, + 0x5e, 0xd1, 0x9d, 0x99, 0xe9, 0x4d, 0x99, 0x74, 0x62, 0x92, 0xe1, 0x68, + 0x5a, 0xb4, 0x8e, 0x4d, 0x46, 0xc4, 0x04, 0x1d, 0xc0, 0x5f, 0xf9, 0xa0, + 0x08, 0x88, 0x2c, 0x49, 0xdf, 0x39, 0x39, 0x9c, 0x6b, 0xdc, 0x7c, 0x61, + 0xd3, 0x26, 0xf3, 0x3c, 0xd2, 0x5e, 0xf5, 0xee, 0x5d, 0x91, 0x47, 0x7f, + 0x0e, 0xee, 0x77, 0x81, 0x23, 0x72, 0x62, 0xcf, 0x01, 0x68, 0x4e, 0x8c, + 0x78, 0xb8, 0x47, 0xb8, 0x33, 0x6f, 0x0f, 0x38, 0x41, 0x41, 0x42, 0x6e, + 0x25, 0xe9, 0xb1, 0x3d, 0x3a, 0x2f, 0x4e, 0x01, 0xa0, 0xfd, 0x98, 0x2a, + 0x96, 0x94, 0xc6, 0xd6, 0x81, 0x68, 0x2a, 0x8d, 0x06, 0x85, 0x9e, 0x3e, + 0x13, 0xf1, 0x21, 0xef, 0xf3, 0x87, 0xc8, 0xc1, 0xf1, 0x16, 0x21, 0x49, + 0x45, 0x2c, 0xa4, 0x85, 0x15, 0x3d, 0xfc, 0x0e, 0x39, 0x75, 0xe8, 0x8c, + 0x23, 0xba, 0x2d, 0x24, 0x9f, 0x72, 0xfb, 0x37, 0x89, 0xbb, 0x02, 0x90, + 0xd1, 0x1f, 0x93, 0x4d, 0xdb, 0x8d, 0x25, 0x87, 0xff, 0x62, 0xc9, 0x38, + 0x4c, 0x87, 0xfe, 0xa2, 0xec, 0x00, 0x29, 0x3e, 0xa0, 0x6c, 0x4f, 0x6c, + 0x91, 0x8b, 0x61, 0xad, 0xbe, 0xa7, 0x34, 0x4d, 0xd3, 0xc6, 0xae, 0x04, + 0x57, 0x78, 0xf1, 0x9d, 0x46, 0x93, 0x8f, 0x70, 0x64, 0xea, 0x64, 0x93, + 0xb3, 0x06, 0xb3, 0xbb, 0x58, 0x88, 0xd7, 0x27, 0x55, 0xe0, 0x47, 0x94, + 0x13, 0x0c, 0xb5, 0x8c, 0xc0, 0x15, 0x04, 0x8c, 0x3a, 0xd5, 0x83, 0xe0, + 0x1d, 0x69, 0x63, 0x3e, 0xa5, 0x52, 0x06, 0xe2, 0x74, 0xcb, 0x21, 0xbb, + 0x5f, 0x54, 0xa1, 0xce, 0x82, 0x5a, 0xfb, 0x02, 0x70, 0x55, 0x32, 0x16, + 0x40, 0xfd, 0xcf, 0x2a, 0xb1, 0xf1, 0x12, 0x7b, 0xe0, 0x05, 0x14, 0xd4, + 0xdf, 0x56, 0xc0, 0x12, 0x59, 0xcd, 0xe1, 0x2f, 0xf1, 0xac, 0x70, 0x1a, + 0x59, 0x5e, 0xb0, 0x7c, 0xa3, 0xa9, 0x09, 0x49, 0xd2, 0x32, 0x71, 0x5a, + 0xb7, 0xc9, 0x8a, 0xac, 0x75, 0xa5, 0x9f, 0x49, 0xc9, 0xb7, 0xd3, 0xa9, + 0x6d, 0x13, 0xc4, 0xba, 0x92, 0x71, 0xb8, 0x48, 0xe4, 0x59, 0x62, 0x03, + 0xa0, 0x35, 0x67, 0xf5, 0xe2, 0x12, 0x18, 0xf8, 0xa8, 0xff, 0x80, 0x67, + 0x77, 0xfb, 0x2a, 0x01, 0x88, 0x90, 0x9c, 0x3d, 0xd4, 0x0a, 0xb0, 0x70, + 0xd8, 0x3d, 0x57, 0x67, 0xba, 0xcb, 0x55, 0x53, 0x65, 0x44, 0x9e, 0xba, + 0x46, 0x50, 0x58, 0x0e, 0x80, 0x74, 0xa2, 0x3c, 0xb4, 0x05, 0x3d, 0x1f, + 0x23, 0x37, 0x61, 0x21, 0x30, 0x61, 0xba, 0x2b, 0x72, 0x2c, 0xac, 0xc2, + 0xdc, 0x4c, 0xd7, 0x8b, 0x6d, 0xdd, 0xe8, 0x40, 0x35, 0x4f, 0xa9, 0xf7, + 0x31, 0xe7, 0xca, 0xca, 0xb3, 0x2c, 0xda, 0x79, 0x78, 0x8e, 0x74, 0x25, + 0x46, 0xf3, 0xf0, 0x00, 0xbb, 0x3f, 0x50, 0x07, 0x23, 0x97, 0x17, 0xd1, + 0x59, 0xe0, 0x6c, 0xc8, 0x27, 0x1b, 0xb5, 0xcb, 0x77, 0x1a, 0x83, 0xf4, + 0x1d, 0xfd, 0xa6, 0xf8, 0x05, 0xc8 +}; +unsigned int ocsp_response_sha512_len = 2382; diff --git a/doc/CHANGES_v3.9.html b/doc/CHANGES_v3.9.html index 93dfddf..9ab7dfe 100644 --- a/doc/CHANGES_v3.9.html +++ b/doc/CHANGES_v3.9.html @@ -9,6 +9,35 @@

MatrixSSL 3.9 changelog

+

Changes between 3.9.2 and 3.9.3 [June 2017]

+

Fix serious buffer handling vulnerabilities along with other smaller bug fixes.

+
    +
  • Fixed buffer overflow vulnerability in parsePolicyMappings and buffer underflow in parseGeneralNames. Vulnerabilities discovered by Aleksandar Nikolic of Cisco Talos.

  • +
  • psX509ParseCert modified not to call parse_single_cert when there are only a few bytes remaining.

  • +
  • Fix compilation when USE_PKCS8 is not defined.

  • +
  • Added common makefiles directory for reusable makefile components.

  • +
  • Added new result code PS_SELFTEST_FAILED for detecting psCryptoOpen() failure due to self-test failure of underlying cryptographic primitivers.

  • +
  • Debugging build log output can be redirected to a file using PSCORE_DEBUG_FILE/PSCORE_DEBUG_FILE_APPEND/FLPS_DEBUG_FILE/ FLPS_DEBUG_FILE_APPEND environment variables.

  • +
  • New example configuration for use of libopenssl-compat. This configuration enables TLS 1.0, which is common to use with libopenssl-compat.

  • +
  • Add client side option for rejecting version downgrade during TLS handshake.

  • +
  • ECDSA cipher suites were errorneously rejected by client using CAs with only RSA certificates.

  • +
  • Small improvements to psBuf and psDynBuf functions.

  • +
  • CMS library improvements, support for multiple recipients with authenticated encrypted data.

  • +
  • CMS library improvements, support for zero or multiple signers for signed data.

  • +
  • Signed data can now contain X.509 CRLs.

  • +
  • Fixed handling of OCSP responses using OCSP responderName.

  • +
  • Fixed memory leak in freeing of OCSP requestor id.

  • +
  • MatrixSSL client sometimes prevented ECDSA cipher suites from being used due to flaw in key material compatibility test. The test has been removed.

  • +
+

Changes between 3.9.1 and 3.9.2

+

3.9.2. only released as a part of SafeZone FIPS SW SDK.

+
    +
  • Added support for OCSP response with SHA-512 signature.

  • +
  • psPkcs8ParsePrivBin() function now supports any SafeZone CL library supported PKCS #8 key formats, in addition to PKCS #8 keys ordinarily supported by MatrixSSL. (Only applicable to MatrixSSL FIPS Edition.)

  • +
  • Added matrixSslLoadKeys and matrixSslLoadKeysMem. This key loading function can be used in situations where the type of private key (RSA or EC) to load is unknown.

  • +
  • Added support for loading CA bundles containing both supported and unsupported certificates. Previously, the loading of a CA bundle failed if any of the certificates could not be fully parsed by MatrixSSL, due to e.g. disabled v1 certificate support. The new feature can be enabled by defining ALLOW_CA_BUNDLE_PARTIAL_PARSE in matrixsslConfig.h. Also the crypto-level psX509ParseCert and psX509ParseCertFile functions support the same feature when passed the CERT_ALLOW_BUNDLE_PARTIAL_PARSE flag.

  • +
  • Added support for RSA-SHA224 and ECDSA-SHA224 signatures in CSR generation, CSR parsing and certificate generation. Expanded X.509 Generation API test.

  • +

Changes between 3.9.0 and 3.9.1

  • Disabled support for SHA-1 signed certificates by default. SHA-1 can no longer be considered secure for this purpose (see https://shattered.it/static/shattered.pdf). We decided to disable SHA-1 signed certificates by default to ensure that MatrixSSL customers consider the security implications before enabling them. Support for SHA-1 signed certificates can be restored by defining ENABLE_SHA1_SIGNED_CERTS in cryptoConfig.h.

  • diff --git a/doc/CHANGES_v3.9.md b/doc/CHANGES_v3.9.md index 9de472f..8f61af6 100644 --- a/doc/CHANGES_v3.9.md +++ b/doc/CHANGES_v3.9.md @@ -1,5 +1,79 @@ # MatrixSSL 3.9 changelog +## Changes between 3.9.2 and 3.9.3 [June 2017] + +Fix serious buffer handling vulnerabilities along with other smaller bug fixes. + +- Fixed buffer overflow vulnerability in parsePolicyMappings and buffer + underflow in parseGeneralNames. Vulnerabilities discovered by Aleksandar + Nikolic of Cisco Talos. + +- psX509ParseCert modified not to call parse_single_cert when there are + only a few bytes remaining. + +- Fix compilation when USE_PKCS8 is not defined. + +- Added common makefiles directory for reusable makefile components. + +- Added new result code PS_SELFTEST_FAILED for detecting psCryptoOpen() failure + due to self-test failure of underlying cryptographic primitivers. + +- Debugging build log output can be redirected to a file using + PSCORE_DEBUG_FILE/PSCORE_DEBUG_FILE_APPEND/FLPS_DEBUG_FILE/ + FLPS_DEBUG_FILE_APPEND environment variables. + +- New example configuration for use of libopenssl-compat. + This configuration enables TLS 1.0, which is common to use with + libopenssl-compat. + +- Add client side option for rejecting version downgrade during TLS handshake. + +- ECDSA cipher suites were errorneously rejected by client using CAs with only + RSA certificates. + +- Small improvements to psBuf and psDynBuf functions. + +- CMS library improvements, support for multiple recipients with + authenticated encrypted data. + +- CMS library improvements, support for zero or multiple signers + for signed data. + +- Signed data can now contain X.509 CRLs. + +- Fixed handling of OCSP responses using OCSP responderName. + +- Fixed memory leak in freeing of OCSP requestor id. + +- MatrixSSL client sometimes prevented ECDSA cipher suites from being used + due to flaw in key material compatibility test. The test has been removed. + +## Changes between 3.9.1 and 3.9.2 + +3.9.2. only released as a part of SafeZone FIPS SW SDK. + +- Added support for OCSP response with SHA-512 signature. + +- psPkcs8ParsePrivBin() function now supports any SafeZone CL library supported + PKCS #8 key formats, in addition to PKCS #8 keys ordinarily supported by + MatrixSSL. (Only applicable to MatrixSSL FIPS Edition.) + +- Added matrixSslLoadKeys and matrixSslLoadKeysMem. This key loading + function can be used in situations where the type of private key + (RSA or EC) to load is unknown. + +- Added support for loading CA bundles containing both supported and + unsupported certificates. Previously, the loading of a CA bundle failed + if any of the certificates could not be fully parsed by MatrixSSL, due to + e.g. disabled v1 certificate support. The new feature can be enabled + by defining ALLOW_CA_BUNDLE_PARTIAL_PARSE in matrixsslConfig.h. Also + the crypto-level psX509ParseCert and psX509ParseCertFile functions support + the same feature when passed the CERT_ALLOW_BUNDLE_PARTIAL_PARSE flag. + +- Added support for RSA-SHA224 and ECDSA-SHA224 signatures in CSR generation, + CSR parsing and certificate generation. Expanded X.509 Generation API + test. + ## Changes between 3.9.0 and 3.9.1 - Disabled support for SHA-1 signed certificates by default. SHA-1 can diff --git a/doc/CHANGES_v3.9.txt b/doc/CHANGES_v3.9.txt index 9429b23..c3fdbe6 100644 --- a/doc/CHANGES_v3.9.txt +++ b/doc/CHANGES_v3.9.txt @@ -3,6 +3,88 @@ MATRIXSSL 3.9 CHANGELOG +Changes between 3.9.2 and 3.9.3 [June 2017] + +Fix serious buffer handling vulnerabilities along with other smaller bug +fixes. + +- Fixed buffer overflow vulnerability in parsePolicyMappings and + buffer underflow in parseGeneralNames. Vulnerabilities discovered by + Aleksandar Nikolic of Cisco Talos. + +- psX509ParseCert modified not to call parse_single_cert when there + are only a few bytes remaining. + +- Fix compilation when USE_PKCS8 is not defined. + +- Added common makefiles directory for reusable makefile components. + +- Added new result code PS_SELFTEST_FAILED for + detecting psCryptoOpen() failure due to self-test failure of + underlying cryptographic primitivers. + +- Debugging build log output can be redirected to a file using + PSCORE_DEBUG_FILE/PSCORE_DEBUG_FILE_APPEND/FLPS_DEBUG_FILE/ + FLPS_DEBUG_FILE_APPEND environment variables. + +- New example configuration for use of libopenssl-compat. This + configuration enables TLS 1.0, which is common to use + with libopenssl-compat. + +- Add client side option for rejecting version downgrade during + TLS handshake. + +- ECDSA cipher suites were errorneously rejected by client using CAs + with only RSA certificates. + +- Small improvements to psBuf and psDynBuf functions. + +- CMS library improvements, support for multiple recipients with + authenticated encrypted data. + +- CMS library improvements, support for zero or multiple signers for + signed data. + +- Signed data can now contain X.509 CRLs. + +- Fixed handling of OCSP responses using OCSP responderName. + +- Fixed memory leak in freeing of OCSP requestor id. + +- MatrixSSL client sometimes prevented ECDSA cipher suites from being + used due to flaw in key material compatibility test. The test has + been removed. + + +Changes between 3.9.1 and 3.9.2 + +3.9.2. only released as a part of SafeZone FIPS SW SDK. + +- Added support for OCSP response with SHA-512 signature. + +- psPkcs8ParsePrivBin() function now supports any SafeZone CL library + supported PKCS #8 key formats, in addition to PKCS #8 keys + ordinarily supported by MatrixSSL. (Only applicable to MatrixSSL + FIPS Edition.) + +- Added matrixSslLoadKeys and matrixSslLoadKeysMem. This key loading + function can be used in situations where the type of private key + (RSA or EC) to load is unknown. + +- Added support for loading CA bundles containing both supported and + unsupported certificates. Previously, the loading of a CA bundle + failed if any of the certificates could not be fully parsed by + MatrixSSL, due to e.g. disabled v1 certificate support. The new + feature can be enabled by defining ALLOW_CA_BUNDLE_PARTIAL_PARSE + in matrixsslConfig.h. Also the crypto-level psX509ParseCert and + psX509ParseCertFile functions support the same feature when passed + the CERT_ALLOW_BUNDLE_PARTIAL_PARSE flag. + +- Added support for RSA-SHA224 and ECDSA-SHA224 signatures in CSR + generation, CSR parsing and certificate generation. Expanded X.509 + Generation API test. + + Changes between 3.9.0 and 3.9.1 - Disabled support for SHA-1 signed certificates by default. SHA-1 can diff --git a/doc/MatrixSSL_GettingStarted.pdf b/doc/MatrixSSL_GettingStarted.pdf index e81e92f..62fbed9 100644 Binary files a/doc/MatrixSSL_GettingStarted.pdf and b/doc/MatrixSSL_GettingStarted.pdf differ diff --git a/doc/matrixssl_dev_guide.md b/doc/matrixssl_dev_guide.md index 729d7c8..4fc258b 100644 --- a/doc/matrixssl_dev_guide.md +++ b/doc/matrixssl_dev_guide.md @@ -1,65 +1,79 @@ -#MatrixSSL Developer's Guide +# Developer's Guide {#DevelopersGuide} -![INSIDE Secure](http://www.insidesecure.com/extension/isinside/design/front/images/logo.png) -**Version 3.9** -*© INSIDE Secure - 2017 - All Rights Reserved* +**@matrixssl version @version** + +@releasemonth @copyrightyear + +*Copyright © @company @copyrightyear. All Rights Reserved.* + [TOC] -#1 OVERVIEW -This developer's guide is a general SSL/TLS overview and a MatrixSSL specific integration reference for adding SSL security into an application. -This document is primarily intended for the software developer performing MatrixSSL integration into their custom application but is also a useful reference for anybody wishing to learn more about MatrixSSL or the SSL/TLS protocol in general. -For additional information on the APIs discussed here please see the _MatrixSSL API_ document included in this package. -##1.1 Nomenclature -MatrixSSL supports both the TLS and SSL protocols. Despite the difference in acronym, TLS 1.0 is simply version 3.1 of SSL. There are no practical security differences between the protocols, and only minor differences in how they are implemented. It was felt that ‘Transport Layer Security’ was a more appropriate name than ‘Secure Sockets Layer’ going forward beyond SSL 3.0. In this documentation, the term SSL is used generically to mean SSL/TLS, and TLS is used to indicate specifically the TLS protocol. SSL 2.0 is deprecated and not supported. MatrixSSL supports SSL 3.0, TLS 1.0, TLS 1.1 and TLS 1.2 protocols. In addition, the DTLS protocol is based closely on TLS 1.1 and beyond. +# OVERVIEW -##1.2 Supported RFCs +This developer's guide is a general SSL/TLS overview and a @matrixssl specific integration reference for adding SSL security into an application. -The following TLS RFCs are implemented by MatrixSSL. +This document is primarily intended for the software developer performing @matrixssl integration into their custom application but is also a useful reference for anybody wishing to learn more about @matrixssl or the SSL/TLS protocol in general. -[RFC 3749](https://tools.ietf.org/html/rfc3749) Transport Layer Security Protocol Compression Methods -: Supported. Disabled by default due to security issues. [See CRIME below](#21-ssltls-version-security). +For additional information on the APIs discussed here please see the API document included in the product package. -[RFC 4162](https://tools.ietf.org/html/rfc4162) Addition of SEED Cipher Suites to Transport Layer Security (TLS) -: Supported. Disabled by default at compile time. -[RFC 4279](https://tools.ietf.org/html/rfc4279) Pre-Shared Key Ciphersuites for Transport Layer Security (TLS) +## Nomenclature + +@matrixssl supports both the TLS and SSL protocols. Despite the difference in acronym, TLS 1.0 is simply version 3.1 of SSL. There are no practical security differences between the protocols, and only minor differences in how they are implemented. + +It was felt that ‘Transport Layer Security’ was a more appropriate name than ‘Secure Sockets Layer’ going forward beyond SSL 3.0. In this documentation, the term SSL is used generically to mean SSL/TLS, and TLS is used to indicate specifically the TLS protocol. SSL 2.0 is deprecated and not supported. @matrixssl supports SSL 3.0, TLS 1.0, TLS 1.1 and TLS 1.2 protocols. In addition, the DTLS protocol is based closely on TLS 1.1 and beyond. + + +## Supported RFCs + +The following TLS RFCs are implemented by @matrixssl. + +* [RFC 3749](https://tools.ietf.org/html/rfc3749) Transport Layer Security Protocol Compression Methods: Supported. Disabled by default due to security issues. See CRIME. + +* [RFC 4162](https://tools.ietf.org/html/rfc4162) Addition of SEED Cipher Suites to Transport Layer Security (TLS): Supported. Disabled by default at compile time. + +* [RFC 4279](https://tools.ietf.org/html/rfc4279) Pre-Shared Key Ciphersuites for Transport Layer Security (TLS) : Supported: -`TLS_DHE_PSK_WITH_AES_256_CBC_SHA` -`TLS_DHE_PSK_WITH_AES_128_CBC_SHA` -`TLS_PSK_WITH_AES_256_CBC_SHA` -`TLS_PSK_WITH_AES_128_CBC_SHA` + * `TLS_DHE_PSK_WITH_AES_256_CBC_SHA`, + * `TLS_DHE_PSK_WITH_AES_128_CBC_SHA`, + * `TLS_PSK_WITH_AES_256_CBC_SHA`, + * `TLS_PSK_WITH_AES_128_CBC_SHA`. -[RFC 4492](https://tools.ietf.org/html/rfc4492) Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) -: Supported: -`TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA` -`TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA` -`TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA` -`TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA` -`TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA` -`TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA` -`TLS_ECDH_RSA_WITH_AES_256_CBC_SHA` -`TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA` -`TLS_ECDH_RSA_WITH_AES_128_CBC_SHA` -Supported Elliptic Curves: -`secp192r1`, `secp224r1`, `secp256r1`, `secp384r1`, `secp521r1` -Supported Point Formats: -`uncompressed` +* [RFC 4492](https://tools.ietf.org/html/rfc4492) Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS): Supported: + * `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA`, + * `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`, + * `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA`, + * `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`, + * `TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA`, + * `TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA`, + * `TLS_ECDH_RSA_WITH_AES_256_CBC_SHA`, + * `TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA`, + * `TLS_ECDH_RSA_WITH_AES_128_CBC_SHA`. -[RFC5077](https://tools.ietf.org/html/rfc5077) Transport Layer Security (TLS) Session Resumption without Server-Side State + Supported Elliptic Curves: + * `secp192r1`, + * `secp224r1`, + * `secp256r1`, + * `secp384r1`, + * `secp521r1`. + + Supported Point Formats: `uncompressed`. + +* [RFC5077](https://tools.ietf.org/html/rfc5077) Transport Layer Security (TLS) Session Resumption without Server-Side State : Supported (Session Tickets). -[RFC5246](https://tools.ietf.org/html/rfc5081) The Transport Layer Security (TLS) Protocol Version 1.2. +* [RFC5246](https://tools.ietf.org/html/rfc5081) The Transport Layer Security (TLS) Protocol Version 1.2. : Supported, including TLS 1.1 and 1.0. -[RFC 5288](https://tools.ietf.org/html/rfc5288) AES Galois Counter Mode (GCM) Cipher Suites for TLS +* [RFC 5288](https://tools.ietf.org/html/rfc5288) AES Galois Counter Mode (GCM) Cipher Suites for TLS : Supported: `TLS_RSA_WITH_AES_256_GCM_SHA384` `TLS_RSA_WITH_AES_128_GCM_SHA256` -[RFC 5289](https://tools.ietf.org/html/rfc5289) TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) +* [RFC 5289](https://tools.ietf.org/html/rfc5289) TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) : Supported: `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` @@ -71,22 +85,25 @@ Supported Point Formats: `TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256` `TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256` -[RFC 5430](https://tools.ietf.org/html/rfc5430) Suite B Profile for Transport Layer Security (TLS) +* [RFC 5430](https://tools.ietf.org/html/rfc5430) Suite B Profile for Transport Layer Security (TLS) : Supported via compile time configuration. -[RFC 5469](https://tools.ietf.org/html/rfc5469) DES and IDEA Cipher Suites for Transport Layer Security (TLS) -: These ciphers are removed per spec: -> ...the single-DES cipher suites SHOULD NOT be implemented by TLS libraries ...the IDEA cipher suite SHOULD NOT be implemented by TLS libraries and SHOULD be removed from existing implementations. +* [RFC 5469](https://tools.ietf.org/html/rfc5469) DES and IDEA Cipher Suites for Transport Layer Security (TLS). These ciphers are removed per spec: + +> ...the single-DES cipher suites SHOULD NOT be +> implemented by TLS libraries ...the IDEA cipher suite +> SHOULD NOT be implemented by TLS libraries and SHOULD +> be removed from existing implementations. -[RFC 5487](https://tools.ietf.org/html/rfc5487) Pre-Shared Key Cipher Suites for TLS with SHA-256/384 and AES Galois Counter Mode +* [RFC 5487](https://tools.ietf.org/html/rfc5487) Pre-Shared Key Cipher Suites for TLS with SHA-256/384 and AES Galois Counter Mode : Supported: `TLS_PSK_WITH_AES_256_CBC_SHA384` `TLS_PSK_WITH_AES_128_CBC_SHA256` -[RFC 5746](https://tools.ietf.org/html/rfc5746) Transport Layer Security (TLS) Renegotiation Indication Extension +* [RFC 5746](https://tools.ietf.org/html/rfc5746) Transport Layer Security (TLS) Renegotiation Indication Extension : Supported. Extension required by compile time default. -[RFC 6066](https://tools.ietf.org/html/rfc6066) Transport Layer Security (TLS) Extensions: Extension Definitions +* [RFC 6066](https://tools.ietf.org/html/rfc6066) Transport Layer Security (TLS) Extensions: Extension Definitions : `server_name` Server Name Indication Supported `max_fragment_length` Supported `client_certificate_url` Unsupported (denial of service risk) @@ -94,65 +111,80 @@ Supported Point Formats: `truncated_hmac` Supported `status_request` OCSP Supported -[RFC 6176](https://tools.ietf.org/html/rfc6176) Prohibiting Secure Sockets Layer (SSL) Version 2.0 +* [RFC 6176](https://tools.ietf.org/html/rfc6176) Prohibiting Secure Sockets Layer (SSL) Version 2.0 : Supported. SSL 2.0 (including ClientHello) deprecated. -[RFC 6347](https://tools.ietf.org/html/rfc6347) Datagram Transport Layer Security Version 1.2 +* [RFC 6347](https://tools.ietf.org/html/rfc6347) Datagram Transport Layer Security Version 1.2 : Supported, including DTLS 1.0. -[RFC 7027](https://tools.ietf.org/html/rfc7027) Elliptic Curve Cryptography (ECC) Brainpool Curves for Transport Layer Security (TLS) +* [RFC 7027](https://tools.ietf.org/html/rfc7027) Elliptic Curve Cryptography (ECC) Brainpool Curves for Transport Layer Security (TLS) : Supported Curves: `brainpoolP224r1`, `brainpoolP256r1`, `brainpoolP384r1`, `brainpoolP512r1` -[RFC 7301](https://tools.ietf.org/html/rfc7301) Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension +* [RFC 7301](https://tools.ietf.org/html/rfc7301) Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension : Supported -[RFC 7457](https://tools.ietf.org/html/rfc7457) Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS) +* [RFC 7457](https://tools.ietf.org/html/rfc7457) Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS) : Supported. [See Security Considerations below](#2-security-considerations). -[RFC 7465](https://tools.ietf.org/html/rfc7465) Prohibiting RC4 Cipher Suites +* [RFC 7465](https://tools.ietf.org/html/rfc7465) Prohibiting RC4 Cipher Suites : Supported. RC4 ciphers are disabled by default at compile time. -[RFC 7507](https://tools.ietf.org/html/rfc7507) TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks +* [RFC 7507](https://tools.ietf.org/html/rfc7507) TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks : Supported -[RFC 7525](https://tools.ietf.org/html/rfc7525) Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) +* [RFC 7525](https://tools.ietf.org/html/rfc7525) Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) : Supported. [See Security Considerations below](#2-security-considerations). -[RFC 7568](https://tools.ietf.org/html/rfc7568) Deprecating Secure Sockets Layer Version 3.0 +* [RFC 7568](https://tools.ietf.org/html/rfc7568) Deprecating Secure Sockets Layer Version 3.0 : Supported. SSL 3.0 is disabled by default at compile time. -[RFC 7627](https://tools.ietf.org/html/rfc7627) Transport Layer Security (TLS) Session Hash and Extended Master Secret Extension +* [RFC 7627](https://tools.ietf.org/html/rfc7627) Transport Layer Security (TLS) Session Hash and Extended Master Secret Extension : Supported -[draft-ietf-dice-profile-17](https://datatracker.ietf.org/doc/draft-ietf-dice-profile/) TLS/DTLS Profiles for the Internet of Things -: Supported via compile time configuration. +* [draft-ietf-dice-profile-17](https://datatracker.ietf.org/doc/draft-ietf-dice-profile/) TLS/DTLS Profiles for the Internet of Things. Supported via compile time configuration. -[draft-ietf-tls-chacha20-poly1305](https://datatracker.ietf.org/doc/draft-ietf-tls-chacha20-poly1305/) ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) -: Supported: +* [draft-ietf-tls-chacha20-poly1305](https://datatracker.ietf.org/doc/draft-ietf-tls-chacha20-poly1305/) ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS). Supported: `TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256` `TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256` -[draft-ietf-tls-falsestart](https://datatracker.ietf.org/doc/draft-ietf-tls-falsestart/) Transport Layer Security (TLS) False Start -: Supported. Disabled by default due to security concerns. [See False Start below](#21-ssltls-version-security). +* [draft-ietf-tls-falsestart](https://datatracker.ietf.org/doc/draft-ietf-tls-falsestart/) Transport Layer Security (TLS) False Start +: Supported. Disabled by default due to security concerns. See [False Start](#21-ssltls-version-security). + + +## Currently Unsupported RFCs -##1.3 Currently Unsupported RFCs The following "Proposed Standard RFCs" for TLS are not currently supported. Numerous "Experimental" and "Informational" RFCs are not listed here. -[RFC 2712](https://tools.ietf.org/html/rfc2712) Addition of Kerberos Cipher Suites to Transport Layer Security (TLS) -[RFC 4785](https://tools.ietf.org/html/rfc4785) Pre-Shared Key (PSK) Ciphersuites with NULL Encryption for Transport Layer Security (TLS) -[RFC 5705](https://tools.ietf.org/html/rfc5705) Keying Material Exporters for Transport Layer Security (TLS) -[RFC 5929](https://tools.ietf.org/html/rfc5929) Channel Bindings for TLS -[RFC 5932](https://tools.ietf.org/html/rfc5932) Camellia Cipher Suites for TLS -[RFC 6520](https://tools.ietf.org/html/rfc6520) Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension -[RFC 6655](https://tools.ietf.org/html/rfc6655) AES-CCM Cipher Suites for Transport Layer Security (TLS) -[RFC 6961](https://tools.ietf.org/html/rfc6961) The Transport Layer Security (TLS) Multiple Certificate Status Request Extension -[RFC 7250](https://tools.ietf.org/html/rfc7250) Using Raw Public Keys in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) -[RFC 7366](https://tools.ietf.org/html/rfc7366) Encrypt-then-MAC for Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) -[RFC 7633](https://tools.ietf.org/html/rfc7685) X.509v3 Transport Layer Security (TLS) Feature Extension -[RFC 7685](https://tools.ietf.org/html/rfc7685) A Transport Layer Security (TLS) ClientHello Padding Extension -##1.4 Supported Cipher Suites +* [RFC 2712](https://tools.ietf.org/html/rfc2712) Addition of Kerberos Cipher Suites to Transport Layer Security (TLS) + +* [RFC 4785](https://tools.ietf.org/html/rfc4785) Pre-Shared Key (PSK) Ciphersuites with NULL Encryption for Transport Layer Security (TLS) + +* [RFC 5705](https://tools.ietf.org/html/rfc5705) Keying Material Exporters for Transport Layer Security (TLS) + +* [RFC 5929](https://tools.ietf.org/html/rfc5929) Channel Bindings for TLS + +* [RFC 5932](https://tools.ietf.org/html/rfc5932) Camellia Cipher Suites for TLS + +* [RFC 6520](https://tools.ietf.org/html/rfc6520) Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension + +* [RFC 6655](https://tools.ietf.org/html/rfc6655) AES-CCM Cipher Suites for Transport Layer Security (TLS) + +* [RFC 6961](https://tools.ietf.org/html/rfc6961) The Transport Layer Security (TLS) Multiple Certificate Status Request Extension + +* [RFC 7250](https://tools.ietf.org/html/rfc7250) Using Raw Public Keys in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) + +* [RFC 7366](https://tools.ietf.org/html/rfc7366) Encrypt-then-MAC for Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) + +* [RFC 7633](https://tools.ietf.org/html/rfc7685) X.509v3 Transport Layer Security (TLS) Feature Extension + +* [RFC 7685](https://tools.ietf.org/html/rfc7685) A Transport Layer Security (TLS) ClientHello Padding Extension + + +## Supported Cipher Suites + Supported suites in priority order (not all suites are enabled by default): + ``` TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 @@ -200,7 +232,9 @@ TLS_PSK_WITH_AES_128_CBC_SHA256 TLS_PSK_WITH_AES_256_CBC_SHA TLS_PSK_WITH_AES_128_CBC_SHA ``` + Deprecated, disabled by default: + ``` SSL_RSA_WITH_RC4_128_SHA TLS_RSA_WITH_SEED_CBC_SHA @@ -213,35 +247,41 @@ TLS_DH_anon_WITH_AES_128_CBC_SHA SSL_DH_anon_WITH_3DES_EDE_CBC_SHA SSL_DH_anon_WITH_RC4_128_MD5 ``` -#2 SECURITY CONSIDERATIONS -Prior to working directly with the MatrixSSL library there are some critical SSL security concepts that application integrators should be familiar with. -##2.1 SSL/TLS Version Security + +# SECURITY CONSIDERATIONS + +Prior to working directly with the @matrixssl library there are some critical SSL security concepts that application integrators should be familiar with. + + +## SSL/TLS Version Security + Although TLS 1.0 and above can be considered secure if configured correctly, several weaknesses have been discovered in some versions and cipher combinations. For an overview, see: [RFC7457 Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS)](https://tools.ietf.org/html/rfc7457) ->Timing and Power Attacks ->: While attempts are made for constant-time operation, the MatrixSSL crypto library is not explicitly designed to be resilient to every type of timing, cache and power attack. If these are a concern, MatrixSSL TLS protocol library has support for hardware crypto, DPA resistant tokens, and hardened software crypto implementations. +### Timing and Power Attacks -All of the issues discovered below are mitigated by default in MatrixSSL. Additionally, SSL 3.0 and weak ciphers and key strengths are disabled by default in MatrixSSL to reduce version downgrade attacks and the padding oracle attack (POODLE). TLS 1.0 is also disabled by default at compile time in an effort to move protocol support forward. +While attempts are made for constant-time operation, the @matrixssl crypto library is not explicitly designed to be resilient to every type of timing, cache and power attack. If these are a concern, @matrixssl TLS protocol library has support for hardware crypto, DPA resistant tokens, and hardened software crypto implementations. + +All of the issues discovered below are mitigated by default in @matrixssl. Additionally, SSL 3.0 and weak ciphers and key strengths are disabled by default in @matrixssl to reduce version downgrade attacks and the padding oracle attack (POODLE). TLS 1.0 is also disabled by default at compile time in an effort to move protocol support forward. [BEAST](https://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack) : `USE_BEAST_WORKAROUND` enabled by default for SSL 3.0 and TLS 1.0. Some implementations of TLS are not compatible with this workaround. -TLS 1.1 and above are not vulnerable to this attack. By default TLS 1.1 is the minimum compiled-in version for MatrixSSL. +TLS 1.1 and above are not vulnerable to this attack. By default TLS 1.1 is the minimum compiled-in version for @matrixssl. [Bleichenbacher Type Attacks](https://en.wikipedia.org/wiki/Adaptive_chosen-ciphertext_attack) -: Private RSA key information can be leaked if libraries aren't careful in their implementation of RSA PKCS#1 padding. MatrixSSL has been analyzed as secure by internal and 3rd party security researchers. Additionally, the more secure RSA-PSS signatures are supported, however TLS 1.2 and below allows only PKCS#1v1.5 signatures. +: Private RSA key information can be leaked if libraries aren't careful in their implementation of RSA PKCS#1 padding. @matrixssl has been analyzed as secure by internal and 3rd party security researchers. Additionally, the more secure RSA-PSS signatures are supported, however TLS 1.2 and below allows only PKCS#1v1.5 signatures. [CRIME](https://en.wikipedia.org/wiki/CRIME_%28security_exploit%29), [BREACH](https://en.wikipedia.org/wiki/BREACH_%28security_exploit%29) : `USE_ZLIB_COMPRESSION` disabled and deprecated by default. Application code should not compress frequently used headers. [DROWN](https://drownattack.com/) -: SSLv2 and export ciphers are not part of the MatrixSSL codebase so this attack cannot be applied. +: SSLv2 and export ciphers are not part of the @matrixssl codebase so this attack cannot be applied. [Lenstra Type Attacks](https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/) -: Private RSA key information can be leaked if a hardware error or memory overrun occurs on the private key, or on intermediate results of the RSA signature operation. MatrixSSL verifies all RSA private key signatures before they are transmitted, so these rareerrors will be caught before they can be exploited. +: Private RSA key information can be leaked if a hardware error or memory overrun occurs on the private key, or on intermediate results of the RSA signature operation. @matrixssl verifies all RSA private key signatures before they are transmitted, so these rareerrors will be caught before they can be exploited. [LUCKY13](https://en.wikipedia.org/wiki/Lucky_Thirteen_attack) : Internal blinding for block cipher padding automatically applied. @@ -252,19 +292,19 @@ Stream and AEAD ciphers are not affected. TLS 1.0 and above are not affected. [FREAK](https://en.wikipedia.org/wiki/FREAK) -: MatrixSSL has never supported weak, export grade ciphers. +: @matrixssl has never supported weak, export grade ciphers. [Logjam](https://en.wikipedia.org/wiki/Logjam_%28computer_security%29) : `USE_DH` is disabled by default. In addition, `MIN_DH_BITS` can be increased from the default 1024 bits to reduce the feasibility of this attack. Custom Diffie-Hellman parameters are loaded by the API `pkcs3ParseDhParam`. [Heartbleed](https://en.wikipedia.org/wiki/Heartbleed) -: MatrixSSL does not support the Heartbeat extension. +: @matrixssl does not support the Heartbeat extension. [BERserk](http://www.intelsecurity.com/advanced-threat-research/berserk.html) -: MatrixSSL was tested against this PKCS#1 v1.5 RSA parsing bug and is not vulnerable. +: @matrixssl was tested against this PKCS#1 v1.5 RSA parsing bug and is not vulnerable. [SMACK](https://www.mitls.org/pages/attacks/SMACK) -: MatrixSSL was tested against state machine attacks where are messages are missing or out of order and is not vulnerable. MatrixSSL tracks both the current state and the expected state of the state machine against incoming handshake messages. +: @matrixssl was tested against state machine attacks where are messages are missing or out of order and is not vulnerable. @matrixssl tracks both the current state and the expected state of the state machine against incoming handshake messages. [Renegotiation Attacks](https://en.wikipedia.org/wiki/Transport_Layer_Security#Renegotiation_attack) : `REQUIRE_SECURE_REHANDSHAKES` enabled by default, as per [RFC 5746](https://tools.ietf.org/html/rfc5746). @@ -286,7 +326,9 @@ MD5 Certificate Weakness SHA1 Certificate Weakness : `ENABLE_SHA1_SIGNED_CERTS` can be disabled. Many certificates still use SHA1, so enabling may introduce compatibility issues with certain hosts. -##2.2 Selecting Cipher Suites + +## Selecting Cipher Suites + The strength of the secure communications is primarily determined by the choice of cipher suites that will be supported. A cipher suite determines how two peers progress through an SSL handshake as well as how the final application data will be encrypted over the secure connection. The four components of any given cipher suite are key exchange, authentication, encryption and digest hash. Key exchange mechanisms refer to how the peers agree upon a common symmetric key that will be used to encrypt data after handshaking is complete. The two common key exchange algorithms are RSA and Diffie-Hellman (DH or ECDH). Currently, when Diffie-Hellman is chosen it is used almost exclusively in ephemeral mode (DHE or ECDHE) in which new private key pairs are generated for each connection to allow perfect forward secrecy. The trade-off for DHE is a much slower SSL handshake as key generation is a relatively processor-intensive operation. Some older protocols also specify DH, as it was the first widely publicized key exchange algorithm. The elliptic curve variations on the Diffie-Hellman algorithms are denoted ECDH or ECDHE in the cipher suite name. @@ -310,7 +352,8 @@ Cipher Suite|Key Exchange|Auth Type|Encryption|MAC The `AES_GCM` and `CHACHA20_POLY1305` are [AEAD ciphers](https://en.wikipedia.org/wiki/Authenticated_encryption) that combine the encryption and digest hash components so a dedicated hash algorithm is not used in these suites. The hash algorithm that is specified is the hash to use for the handshake hash in TLS 1.2 and greater. -**Symmetric Algorithms Supported by MatrixSSL** + +**Symmetric Algorithms Supported by @matrixssl** Algorithm|Ok?|Typical Risks ---|---|--- @@ -322,7 +365,8 @@ AES-CBC|Yes|AES-256 preferred over AES-192 and AES-128. Lucky13 Attack mitigated AES-GCM|Yes|AES-256 preferred over AES-192 and AES-128. Not vulnerable to Lucky13 Attack. Without hardware acceleration, can be slower than AES-SHA. Risk that an as-yet undiscovered AES attack will compromise both encryption and record validation. ChaCha20|Yes|Stream cipher with 256 bit equivalent security. Supported as per [IETF Draft](https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305) -**Hash Algorithms Supported by MatrixSSL** + +**Hash Algorithms Supported by @matrixssl** Algorithm|Ok?|Typical Risks ---|---|--- @@ -335,7 +379,8 @@ SHA-384|Yes|Assumed secure. SHA-512|Yes|Assumed secure. Poly1305|Yes|Supported as per [IETF Draft](https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305) -**Key Exchange Algorithms Supported by MatrixSSL** + +**Key Exchange Algorithms Supported by @matrixssl** Algorithm|Key Size|Ok?|Typical Risks ---|---|---|--- @@ -347,10 +392,11 @@ DH|1024|No|In wide usage. Recommended to not use going forward DH|\> 1024|Yes|Recommend at least 2048 bit DH group per NIST and FIPS. DHE|\> 1024|Yes|See chart below. Ephemeral cipher suites provide perfect forward secrecy, and are generally the strongest available, although they are also the slowest performing for key exchange. ECDHE|\>= 192|Yes|See chart below. Ephemeral cipher suites provide perfect forward secrecy, and are generally the strongest available, although they are also the slowest performing for key exchange. 224 and greater required by FIPS. -ECDH|\>= 192|Yes|192 bit DH group and above is currently assumed secure. Smaller groups are not supported in MatrixSSL. Below `MIN_ECC_SIZE` connections will be refused. 224 and greater required by FIPS. +ECDH|\>= 192|Yes|192 bit DH group and above is currently assumed secure. Smaller groups are not supported in @matrixssl. Below `MIN_ECC_SIZE` connections will be refused. 224 and greater required by FIPS. PSK|\>= 128|Yes|Pre-shared Key ciphers rely on offline key agreement. They avoid any weaknesses of Key Exchange Algorithms, however, it is not easy to change keys once they are installed when used as session keys. When PSK is used only for authentication (`DHE_PSK` and `ECDHE_PSK` cipher suites), the session encryption keys are generated each connection. -**Authentication Methods Supported by MatrixSSL** + +**Authentication Methods Supported by @matrixssl** Suite Type|Auth|Exchange|Ok?|Typical Risks ---|---|---|---|--- @@ -365,16 +411,21 @@ Suite Type|Auth|Exchange|Ok?|Typical Risks `ECDHE_ECDSA`|ECC DSA|ECC Diffie-Hellman Ephemeral|Yes|ECC key exchange with ephemeral keys, ECC DSA authentication. Most commonly used in embedded devices supporting hardware based ECC support. `ECDHE_RSA`|RSA|ECC Diffie-Hellman Ephemeral|Yes|Ephemeral counterpart to ECDH_RSA. -##2.3 Authentication Mode + +## Authentication Mode + By default in SSL, it is the server that is authenticated by a client. It is easiest to remember this when thinking about purchasing a product online with a credit card over an HTTPS (SSL) connection. The client Web browser must authenticate the server in order to be confident the credit card information is being sent to a trusted source. This is referred to as one-way authentication or server authentication and is performed as part of all standard SSL connections (unless, of course, a cipher suite with an authentication type of anonymous has been agreed upon). However, in some use-case scenarios the user may require that both peers authenticate each other. This is referred to as mutual authentication or client authentication. If the project requires client authentication there is an additional set of key material that must be used to support it as described in the next section. Client authentication is also done inherently in Pre-shared Key cipher suites, as both sides of a connection must have a common shared secret. -##2.4 Authentication and Key Exchange -###2.4.1 Server and Client Authentication +## Authentication and Key Exchange + + +### Server and Client Authentication + With a cipher suite and authentication mode chosen, the user will need to obtain or generate the necessary key material for supporting the authentication and key exchange mechanisms. X.509 is the standard for how key material is stored in certificate files. The peer that is being authenticated must have a private key and a public certificate. The peer performing the authentication must have the Certificate Authority (CA) certificate that was used to issue the public certificate. In the standard one-way authentication scenario this means the server will load a private key and certificate while the client will load the CA file. @@ -386,40 +437,44 @@ Authentication Mode|Server Key Files|Client Key Files One-way server authentication|RSA server certificate file and corresponding RSA private key file.|Certificate Authority certificate file that issued the server certificate Additions for client authentication|Certificate Authority certificate file that issued the client certificate|RSA client certificate file and corresopnding RSA private key file. -###2.4.2 Certificate Validation and Authentication + +### Certificate Validation and Authentication + Authentication in SSL is most often based on X.509 Certificate chain validation. -Example [Equifax GeoTrust](https://www.geotrust.com/resources/root-certificates/) trusted root certificate loaded by a MatrixSSL client with `matrixSslLoadRsaKeys`. ->**Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority** -*Authority KeyId*:48:E6:68:F9:2B:D2:B2:95... [Valid, self-signed OK for root] -*Subject KeyId*: 48:E6:68:F9:2B:D2:B2:95... -*Basic Constraints*: critical CA:TRUE [Valid, this certificate can sign others] -*Key Usage*: critical Certificate Sign, CRL Sign [Valid, able to sign certificates] -*Validity*: (Aug 22 16:41:51 1998 GMT to Aug 22 16:41:51 2018 GMT) [Valid] +Example [Equifax GeoTrust](https://www.geotrust.com/resources/root-certificates/) trusted root certificate loaded by a @matrixssl client with `matrixSslLoadRsaKeys`. -Certificate chain sent to a MatrixSSL client during SSL handshake Certificate message by remote server https://www.google.com. + **Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority** + *Authority KeyId*:48:E6:68:F9:2B:D2:B2:95... [Valid, self-signed OK for root] + *Subject KeyId*: 48:E6:68:F9:2B:D2:B2:95... + *Basic Constraints*: critical CA:TRUE [Valid, this certificate can sign others] + *Key Usage*: critical Certificate Sign, CRL Sign [Valid, able to sign certificates] + *Validity*: (Aug 22 16:41:51 1998 GMT to Aug 22 16:41:51 2018 GMT) [Valid] + +Certificate chain sent to a @matrixssl client during SSL handshake Certificate message by remote server https://www.google.com. + + **C=US, O=GeoTrust Inc., CN=GeoTrust Global CA** + *Issuer*: C=US, O=Equifax, OU=Equifax Secure Certificate Authority [Valid, matches a loaded trusted root subject] + *Authority KeyId*: 48:E6:68:F9:2B:D2:B2:95... [Valid, matches the Issuer Subject KeyId] + *Subject KeyId*: C0:7A:98:68:8D:89:FB:AB... + *Basic Constraints*: critical CA:TRUE [Valid, this certificate can sign others] + *Key Usage*: critical Certificate Sign, CRL Sign [Valid, able to sign certificates] + *Validity*: (May 21 04:00:00 2002 GMT to Aug 21 04:00:00 2018 GMT) [Valid] + >>**C=US, O=Google Inc, CN=Google Internet Authority G2** + *Issuer*: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA [Valid, matches parent subject] + *Authority KeyId*: C0:7A:98:68:8D:89:FB:AB... [Valid, matches the Issuer Subject KeyId] + *Subject KeyId*: 4A:DD:06:16:1B:BC:F6:68... + *Validity*: (Apr 5 15:15:55 2013 GMT to Apr 4 15:15:55 2015 GMT) [Valid] + *Basic Constraints*: critical CA:TRUE, pathlen:0 [Valid, this certificate can sign others and the signed certificate is not also a CA] + *Key Usage*: critical Certificate Sign, CRL Sign [Valid, able to sign certificates] + *Version*: 3 [Valid] + >>>**C=US, ST=California, L=Mountain View, O=Google Inc, CN=*.google.com** + *Issuer*: C=US, O=Google Inc, CN=Google Internet Authority G2 [Valid, matches parent subject] + *X509v3 Basic Constraints*: critical CA:FALSE [Valid, this is a leaf cert] + *Extended Key Usage*: TLS Web Server Authentication, TLS Web Client Authentication [Valid] + *X509v3 Subject Alternative Name*: DNS:*.google.com, DNS:*.android.com... [Valid, matches expected DNS name] + *Validity*: (Mar 12 09:53:40 2014 GMT to Jun 10 00:00:00 2014 GMT) [Valid] ->**C=US, O=GeoTrust Inc., CN=GeoTrust Global CA** -*Issuer*: C=US, O=Equifax, OU=Equifax Secure Certificate Authority [Valid, matches a loaded trusted root subject] -*Authority KeyId*: 48:E6:68:F9:2B:D2:B2:95... [Valid, matches the Issuer Subject KeyId] -*Subject KeyId*: C0:7A:98:68:8D:89:FB:AB... -*Basic Constraints*: critical CA:TRUE [Valid, this certificate can sign others] -*Key Usage*: critical Certificate Sign, CRL Sign [Valid, able to sign certificates] -*Validity*: (May 21 04:00:00 2002 GMT to Aug 21 04:00:00 2018 GMT) [Valid] ->>**C=US, O=Google Inc, CN=Google Internet Authority G2** -*Issuer*: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA [Valid, matches parent subject] -*Authority KeyId*: C0:7A:98:68:8D:89:FB:AB... [Valid, matches the Issuer Subject KeyId] -*Subject KeyId*: 4A:DD:06:16:1B:BC:F6:68... -*Validity*: (Apr 5 15:15:55 2013 GMT to Apr 4 15:15:55 2015 GMT) [Valid] -*Basic Constraints*: critical CA:TRUE, pathlen:0 [Valid, this certificate can sign others and the signed certificate is not also a CA] -*Key Usage*: critical Certificate Sign, CRL Sign [Valid, able to sign certificates] -*Version*: 3 [Valid] ->>>**C=US, ST=California, L=Mountain View, O=Google Inc, CN=*.google.com** -*Issuer*: C=US, O=Google Inc, CN=Google Internet Authority G2 [Valid, matches parent subject] -*X509v3 Basic Constraints*: critical CA:FALSE [Valid, this is a leaf cert] -*Extended Key Usage*: TLS Web Server Authentication, TLS Web Client Authentication [Valid] -*X509v3 Subject Alternative Name*: DNS:*.google.com, DNS:*.android.com... [Valid, matches expected DNS name] -*Validity*: (Mar 12 09:53:40 2014 GMT to Jun 10 00:00:00 2014 GMT) [Valid] **Validity checks that are done on all certificates** @@ -441,54 +496,64 @@ Authority Key Identifier|If specified, the direct Issuer of the certificate must Subject Key Identifier|If specified, any direct children of the Issuer must have a defined, matching `Authority Key Identifier`. CRL Distribution Points|If USE_CRL is defined, `matrixSslGetCRL` will download the CRL files from each URI type distribution point provided for each trusted root certificate (Note: not intermediate certificates). CRL Validation|CRL file must be signed by certificate with `CrlSign` Basic constraints. MD5 signatures not supported by default. -Unknown Extensions|Unknown extensions are ignored, unless flagged as `Critical`. Validation will fail for any Critical extension unrecognized by MatrixSSL. +Unknown Extensions|Unknown extensions are ignored, unless flagged as `Critical`. Validation will fail for any Critical extension unrecognized by @matrixssl. -In _MatrixSSL Commercial Edition_, Certificate Authority root and child certificates can be created using the provided command-line tools and API. For more information, please consult the _Matrix Key and Cert Generation Utilities_ and _MatrixSSL Certificates and Certificate Revocation Lists_ documents. +In _@matrixssl Commercial Edition_, Certificate Authority root and child certificates can be created using the provided command-line tools and API. For more information, please consult the *Key and Cert Generation Utilities* and *@matrixssl Certificates and Certificate Revocation Lists* documents. -#3 APPLICATION INTEGRATION FLOW -MatrixSSL is a C code library that provides a security layer for client and server applications allowing them to securely communicate with other SSL enabled peers. MatrixSSL is transport agnostic and can just as easily integrate with an HTTP server as it could with a device communicating through a serial port. For simplicity, this developer's guide will assume a socket-based implementation for all its examples unless otherwise noted. -The term application in this document refers to the peer (client or server) application the MatrixSSL library is being integrated into. +# APPLICATION INTEGRATION FLOW -This section will detail the specific points in the application life cycle where MatrixSSL should be integrated. In general, MatrixSSL APIs are used for initialization/cleanup, when new secure connections are being established (handshaking), and when encrypting/decrypting messages exchanged with peers. +@matrixssl is a C code library that provides a security layer for client and server applications allowing them to securely communicate with other SSL enabled peers. @matrixssl is transport agnostic and can just as easily integrate with an HTTP server as it could with a device communicating through a serial port. For simplicity, this developer's guide will assume a socket-based implementation for all its examples unless otherwise noted. -Refer to the MatrixSSL API document to get familiar with the interface to the library and with the example code to see how they are used at implementation. Follow the guidelines below when using these APIs to integrate MatrixSSL into an application. +The term application in this document refers to the peer (client or server) application the @matrixssl library is being integrated into. -##3.1 `ssl_t` Structure -The `ssl_t` structure holds the state and keys for each client or server connection as well as buffers for encoding and decoding SSL data. The buffers are dynamically managed internally to make the integration with existing non-secure software easier. SSL is a record based protocol, and the internal buffer management makes a better 'impedance match' with classic stream based protocols. For example, data may be read from a socket, but if a full SSL record has not been received, no data is available for the caller to process. This partial record is held within the `ssl_t` buffer. The MatrixSSL API is also designed so there are no buffer copies, and the caller is able to read and write network data directly into the SSL buffers, providing a very low memory overhead per session. +This section will detail the specific points in the application life cycle where @matrixssl should be integrated. In general, @matrixssl APIs are used for initialization/cleanup, when new secure connections are being established (handshaking), and when encrypting/decrypting messages exchanged with peers. -##3.2 Initialization -MatrixSSL must be initialized as part of the application initialization with a call to `matrixSslOpen`. This function sets up the internal structures needed by the library. +Refer to the @matrixssl API document to get familiar with the interface to the library and with the example code to see how they are used at implementation. Follow the guidelines below when using these APIs to integrate @matrixssl into an application. + + +## `ssl_t` Structure + +The `ssl_t` structure holds the state and keys for each client or server connection as well as buffers for encoding and decoding SSL data. The buffers are dynamically managed internally to make the integration with existing non-secure software easier. SSL is a record based protocol, and the internal buffer management makes a better 'impedance match' with classic stream based protocols. For example, data may be read from a socket, but if a full SSL record has not been received, no data is available for the caller to process. This partial record is held within the `ssl_t` buffer. The @matrixssl API is also designed so there are no buffer copies, and the caller is able to read and write network data directly into the SSL buffers, providing a very low memory overhead per session. + + +## Initialization + +@matrixssl must be initialized as part of the application initialization with a call to `matrixSslOpen`. This function sets up the internal structures needed by the library. In most cases, the application will subsequently load the key material from the file system. RSA or EC certificates, Diffie-Hellman parameters, and Pre-Shared Keys for the specific peer application must be parsed before creating a new SSL session. The `matrixSslNewKeys` function is used to allocate the key storage and `matrixSslLoadRsaKeys`, `matrixSslLoadEcKeys`, `matrixSslLoadDhParams`, and `matrixSslLoadPsk` are used to parse the key material into the `sslKeys_t` structure during initialization. The populated key structure will be used as an input parameter to `matrixSslNewClientSession` or `matrixSslNewServerSession`. The allocation and loading of the `sslKeys_t` structure is most commonly done a single time at start and the application uses those keys for each connection. Alternatively, a new `sslKeys_t` structure can be allocated once for each secure connection and freed immediately after the connection is closed. This should be done if the application has multiple certificate files depending on the identity of the connecting entity or if there is a security concern with keeping the RSA keys in memory for extended periods of time. Once the application is done with the keys, the associated memory is freed with a call to `matrixSslDeleteKeys`. -##3.3 Creating a Session -The next MatrixSSL integration point in the application is when a new session is starting. In the case of a client, this is whenever it chooses to begin one because SSL is a client-initiated protocol (like HTTP). In the case of a server, a new session should be started when the server accepts an incoming connection from a client on a secure port. In a socket based application, this would typically happen when the accept socket call returns with a valid incoming socket. The application sets up a new session with the API `matrixSslNewClientSession` or `matrixSslNewServerSession`. The returned `ssl_t` context will become the input parameter for all public APIs that act at a per-session level. + +## Creating a Session + +The next @matrixssl integration point in the application is when a new session is starting. In the case of a client, this is whenever it chooses to begin one because SSL is a client-initiated protocol (like HTTP). In the case of a server, a new session should be started when the server accepts an incoming connection from a client on a secure port. In a socket based application, this would typically happen when the accept socket call returns with a valid incoming socket. The application sets up a new session with the API `matrixSslNewClientSession` or `matrixSslNewServerSession`. The returned `ssl_t` context will become the input parameter for all public APIs that act at a per-session level. The required input parameters to the session creation APIs differ based on whether the application is assuming a server or client role. Both require a populated keys structure (discussed in the previous section) but a client can also nominate a specific cipher suite or session ID when starting a session. The ciphers that the server will accept are determined at compile time. The client should also always nominate a certificate callback function during `matrixSslNewClientSession`. This callback function will be invoked mid-handshake to allow the user to inspect the key material, date and other certificate information sent from the server. For detailed information on this callback function, see the API documentation for the _Certificate Validation Callback Function_ section. -The server may also choose to nominate a certificate callback function if client authentication is desired. The MatrixSSL library must have been compiled with `USE_CLIENT_AUTH` defined in order to use this parameter in the `matrixSslNewServerSession` function. +The server may also choose to nominate a certificate callback function if client authentication is desired. The @matrixssl library must have been compiled with `USE_CLIENT_AUTH` defined in order to use this parameter in the `matrixSslNewServerSession` function. -For clients wishing to quickly (and securely) reconnect to a server that it has recently connected to, there is an optional sessonId parameter that may be used to initiate a faster resumed handshake (the cpu intensive public key exchange is omitted). To use the session parameter, a client should allocate a `sslSessionId_t` structure with `matrixSslNewSessionId` and pass it to `matrixSslNewClientSession` during the initial connection with the server. Over the course of the session negotiation, the MatrixSSL library will populate that structure behind-the-scenes so that during the next connection the same sessionId parameter address can be used to initiate the resumed session. +For clients wishing to quickly (and securely) reconnect to a server that it has recently connected to, there is an optional sessonId parameter that may be used to initiate a faster resumed handshake (the cpu intensive public key exchange is omitted). To use the session parameter, a client should allocate a `sslSessionId_t` structure with `matrixSslNewSessionId` and pass it to `matrixSslNewClientSession` during the initial connection with the server. Over the course of the session negotiation, the @matrixssl library will populate that structure behind-the-scenes so that during the next connection the same sessionId parameter address can be used to initiate the resumed session. + + +## Handshaking -##3.4 Handshaking During client session initialization with `matrixSslNewClientSession` the SSL handshake message `CLIENT_HELLO` is encoded to the internal outgoing buffer. The client now needs to send this message to the server over a communication channel. The sequence of events that should always be used to transmit pending handshake data is as follows: -1. The user calls `matrixSslGetOutdata` to retrieve the encoded data and number of bytes to be sent -2. The user sends the number of bytes indicated from the out data buffer pointer to the peer -3. The user calls `matrixSslSentData` with the actual number of bytes that were sent -4. If more data remains (bytes sent < bytes to be sent), repeat the above 3 steps when the transport layer is ready to send again +1. The user calls `matrixSslGetOutdata` to retrieve the encoded data and number of bytes to be sent. +2. The user sends the number of bytes indicated from the out data buffer pointer to the peer. +3. The user calls `matrixSslSentData` with the actual number of bytes that were sent. +4. If more data remains (bytes sent < bytes to be sent), repeat the above 3 steps when the transport layer is ready to send again. When the server receives notice that a client is starting a new session the `matrixSslNewServerSession` API is invoked and the incoming data is retrieved and processed. The sequence of events that should always be used when expecting handshake data from a peer is as follows: -1. The application calls `matrixSslGetReadbuf` to retrieve a pointer to available buffer space in the `ssl_t` structure. -2. The application reads (or copies) incoming data into that buffer -3. The application calls `matrixSslReceivedData` to process the data +1. The application calls `matrixSslGetReadbuf` to retrieve a pointer to available buffer space in the `ssl_t` structure. +2. The application reads (or copies) incoming data into that buffer. +3. The application calls `matrixSslReceivedData` to process the data. 4. The application examines the return code from `matrixSslReceivedData` to determine the next step All incoming messages should be copied into the provided buffer and passed to `matrixSslReceivedData`, which processes the message and drives the handshake through the built-in SSLv3 or TLS state machine. The parameters include the SSL context and the number of bytes that have been received. The return code from `matrixSslReceivedData` tells the application what the message was and how it is to be handled: @@ -514,56 +579,71 @@ All incoming messages should be copied into the provided buffer and passed to `m `< 0` : Failure. See API documentation -##3.5 Communicating Securely With Peers -###3.5.1 Encrypting Data +## Communicating Securely With Peers + + +### Encrypting Data + Once the handshake is complete, the application wishing to encrypt data that will be sent to the peer has the choice between two encoding options. -**In-Situ Encryption** -An in-situ encryption occurs when the outputted cipher text overwrites the plain text during the encoding process. In this case, the user will retrieve an allocated buffer from the MatrixSSL library, populate the buffer with the desired plaintext, and then notify the library that the plaintext is ready to be encoded. The API steps for the in-situ method are as follows: -1. The application first determines the length of the plaintext that needs to be sent -2. The application calls `matrixSslGetWritebuf` with that length to retrieve a pointer to an internally allocated buffer. -3. The application writes the plaintext into the buffer and then calls `matrixSslEncodeWritebuf` to encrypt the plaintext -4. The application calls `matrixSslGetOutdata` to retrieve the encoded data and length to be sent (SSL always adds some overhead to the message size) -5. The application sends the out data buffer contents to the peer. +**In-Situ Encryption** + +An in-situ encryption occurs when the outputted cipher text overwrites the plain text during the encoding process. In this case, the user will retrieve an allocated buffer from the @matrixssl library, populate the buffer with the desired plaintext, and then notify the library that the plaintext is ready to be encoded. The API steps for the in-situ method are as follows: + +1. The application first determines the length of the plaintext that needs to be sent +2. The application calls `matrixSslGetWritebuf` with that length to retrieve a pointer to an internally allocated buffer. +3. The application writes the plaintext into the buffer and then calls `matrixSslEncodeWritebuf` to encrypt the plaintext. +4. The application calls `matrixSslGetOutdata` to retrieve the encoded data and length to be sent (SSL always adds some overhead to the message size). +5. The application sends the out data buffer contents to the peer. 6. The application calls `matrixSslSentData` with the number of bytes that were actually sent + **User provided plaintext data location** -The alternative to in-situ encryption is to allow the user to provide the location and length of the plaintext data that needs to be encoded. In this case, the encrypted data is still written to the internal MatrixSSL out data buffer but the user provided plaintext data is left untouched. The API steps for this method are as follows: -1. The user passes the plaintext and length to `matrixSslEncodeToOutdata` -2. The application calls `matrixSslGetOutdata` to retrieve the encoded data and length to be sent (SSL always adds some overhead to the message size) -3. The application sends the out data buffer contents to the peer. -4. The application calls `matrixSslSentData` with the # of bytes that were actually sent +The alternative to in-situ encryption is to allow the user to provide the location and length of the plaintext data that needs to be encoded. In this case, the encrypted data is still written to the internal @matrixssl out data buffer but the user provided plaintext data is left untouched. The API steps for this method are as follows: + +1. The user passes the plaintext and length to `matrixSslEncodeToOutdata`. +2. The application calls `matrixSslGetOutdata` to retrieve the encoded data and length to be sent (SSL always adds some overhead to the message size). +3. The application sends the out data buffer contents to the peer. +4. The application calls `matrixSslSentData` with the # of bytes that were actually sent. + + +### Decrypting Data -###3.5.2 Decrypting Data The sequence of events that should always be used when expecting application data from a peer is as follows: -1. The application calls `matrixSslGetReadbuf` to retrieve an allocated buffer -2. The application copies the incoming data into that buffer -3. The application calls `matrixSslReceivedData` to process the data -4. The application confirms the return code from `matrixSslReceivedData` is `MATRIXSSL_APP_DATA` and parses `ptLen` bytes of the returned plain text -5. If the return code does not indicate application data, handle the return code as described in the handshaking section above. +1. The application calls `matrixSslGetReadbuf` to retrieve an allocated buffer. +2. The application copies the incoming data into that buffer. +3. The application calls `matrixSslReceivedData` to process the data. +4. The application confirms the return code from `matrixSslReceivedData` is `MATRIXSSL_APP_DATA` and parses `ptLen` bytes of the returned plain text. +5. If the return code does not indicate application data, handle the return code as described in the handshaking section above. 6. The application calls `matrixSslProcessedData` to inform the library it is finished with the plaintext and checks to see if there are additional records in the buffer to process. -##3.6 Ending a Session + +## Ending a Session + When the application receives notice that the session is complete or has determined itself that the session is complete, it should notify the other side, close the socket and delete the session. Calling `matrixSslEncodeClosureAlert` and `matrixSslDeleteSession` will perform this step. A call to `matrixSslEncodeClosureAlert` is an optional step that will encode an alert message to pass along to the other side to inform them to close the session cleanly. The closure alert buffer is retrieved and sent using the same `matrixSslGetOutdata` then `matrixSslSentData` mechanism that all outgoing data uses. Since the connection is being closed, the application shouldn’t block indefinitely on sending the closure alert. -##3.7 Closing the Library -At application exit the MatrixSSL library should be un-initialized with a call to `matrixSslClose`. If the application has called `matrixSsNewKeys` as part of the initialization process and kept its keys in memory it should call `matrixSslDeleteKeys` before calling `matrixSslClose`. Also, any existing SSL sessions should be freed by calling `matrixSslDeleteSession` before calling `matrixSslClose`. -Example implementations of MatrixSSL client and server applications integration can be found in the apps subdirectory of the distribution package. +## Closing the Library -#4 CONFIGURABLE FEATURES -MatrixSSL contains a set of optional features that are configurable at compile time. This allows the user to remove unneeded functionality to reduce code size footprint and disable potentially insecure features. Each of these options are pre-processor defines that can be disabled by simply commenting out the #define in the header files or by using the -D compile flag during build. APIs with dependencies on optional features are highlighted in the Define Dependencies sub-section in the API documentation for that function. +At application exit the @matrixssl library should be un-initialized with a call to `matrixSslClose`. If the application has called `matrixSsNewKeys` as part of the initialization process and kept its keys in memory it should call `matrixSslDeleteKeys` before calling `matrixSslClose`. Also, any existing SSL sessions should be freed by calling `matrixSslDeleteSession` before calling `matrixSslClose`. + +Example implementations of @matrixssl client and server applications integration can be found in the apps subdirectory of the distribution package. + + +# CONFIGURABLE FEATURES + +@matrixssl contains a set of optional features that are configurable at compile time. This allows the user to remove unneeded functionality to reduce code size footprint and disable potentially insecure features. Each of these options are pre-processor defines that can be disabled by simply commenting out the #define in the header files or by using the -D compile flag during build. APIs with dependencies on optional features are highlighted in the Define Dependencies sub-section in the API documentation for that function. *Not all configurable options are listed below. See comments directly in configuration header files for more fine-tuning.* -##4.1 Protocol and Performance +## Protocol and Performance `USE_CLIENT_SIDE_SSL` : matrixsslConfig.h - Enables client side SSL support @@ -600,7 +680,7 @@ MatrixSSL contains a set of optional features that are configurable at compile t : matrixsslConfig.h - Enables two-way(mutual) authentication `USE_EXT_CERTIFICATE_VERIFY_SIGNING` -: matrixsslConfig.h - Enables client authentication using an external module. See the `MatrixSSL External Module Integration` manual for details. +: matrixsslConfig.h - Enables client authentication using an external module. See the *External Module Integration* document for details. `SERVER_CAN_SEND_EMPTY_CERT_REQUEST` : matrixsslConfig.h – A client authentication feature. Allows the server to send an empty CertificateRequest message if no CA files have been loaded @@ -628,7 +708,7 @@ MatrixSSL contains a set of optional features that are configurable at compile t : cryptoConfig.h - Enables the parsing of some additional certificate extensions, such as nameConstraints and authorityInfoAccess. `USE_CERT_GEN` -: cryptoConfig.h - _(MatrixSSL Commercial Edition only:)_ Enables X.509 certificate generation. +: cryptoConfig.h - _(@matrixssl Commercial Edition only:)_ Enables X.509 certificate generation. `ENABLE_MD5_SIGNED_CERTS` `ENABLE_SHA1_SIGNED_CERTS` @@ -645,10 +725,10 @@ MatrixSSL contains a set of optional features that are configurable at compile t `USE_FIPS_CRYPTO` `USE_CL_CRYPTO` -: cryptoConfig.h - _(MatrixSSL FIPS Edition only:)_ Enable using the FIPS 140-2 validated SafeZone CL/FIPSLib 1.1 as the cryptographic library in MatrixSSL. For more information on FIPS 140-2 specific configuration options, please consult the _MatrixSSL with CL Library_ document, included with the _MatrixSSL FIPS Edition_. +: cryptoConfig.h - _(@matrixssl FIPS Edition only:)_ Enable using the FIPS 140-2 validated SafeZone CL/FIPSLib 1.1 as the cryptographic library in @matrixssl. For more information on FIPS 140-2 specific configuration options, please consult the *@matrixssl with CL Library* document, included with the @matrixssl FIPS Edition. `USE_CMS` -: cryptoConfig.h - _(MatrixSSL Commercial Edition only:)_ Enable support for Cryptographic Messaging Syntax (CMS). +: cryptoConfig.h - _(@matrixssl Commercial Edition only:)_ Enable support for Cryptographic Messaging Syntax (CMS). `USE_RSA` `USE_ECC` @@ -656,12 +736,12 @@ MatrixSSL contains a set of optional features that are configurable at compile t : cryptoConfig.h - Enable RSA, ECC and DH support, respectively. `USE_DSA_VERIFY` -: cryptoConfig.h - _(MatrixSSL FIPS Edition only:)_ Enable verification of DSA signatures in certificate validation. +: cryptoConfig.h - _(@matrixssl FIPS Edition only:)_ Enable verification of DSA signatures in certificate validation. `MIN_RSA_SIZE` `MIN_DH_SIZE` `MIN_ECC_SIZE` -: cryptoConfig.h – The minimum size in bits that MatrixSSL will accept for key exchange for each algorithm. Prevents weak keys from being used or downgraded to. +: cryptoConfig.h – The minimum size in bits that @matrixssl will accept for key exchange for each algorithm. Prevents weak keys from being used or downgraded to. `USE_PRIVATE_KEY_PARSING` : cryptoConfig.h - Enables X.509 private key parsing @@ -682,7 +762,7 @@ MatrixSSL contains a set of optional features that are configurable at compile t : matrixsslConfig.h - Disabled by default. See code comments in file. `NO_ECC_EPHEMERAL_CACHE` -: matrixsslConfig.h - By default, MatrixSSL caches the ECDHE keys it generates and re-uses the cached keys for connections within a certain time frame and a certain usage count. This improves performance of ECDHE suites, and is in line with the configuration current web browsers. Enabling NO_ECC_EPHEMERAL_CACHE disables the key caching and forces new ECDHE keys to be created for every TLS connection. Note that caching ECDHE keys is against some standards such as NIST SP 800-56A, and disallowed in the FIPS 140-2 mode of operation. NO_ECC_EPHEMERAL_CACHE is disabled by default. +: matrixsslConfig.h - By default, @matrixssl caches the ECDHE keys it generates and re-uses the cached keys for connections within a certain time frame and a certain usage count. This improves performance of ECDHE suites, and is in line with the configuration current web browsers. Enabling NO_ECC_EPHEMERAL_CACHE disables the key caching and forces new ECDHE keys to be created for every TLS connection. Note that caching ECDHE keys is against some standards such as NIST SP 800-56A, and disallowed in the FIPS 140-2 mode of operation. NO_ECC_EPHEMERAL_CACHE is disabled by default. `ECC_EPHEMERAL_CACHE_SECONDS` `ECC_EPHEMERAL_CACHE_USAGE` @@ -704,9 +784,11 @@ MatrixSSL contains a set of optional features that are configurable at compile t : Determined automatically in core/osdep.h. Enables keys to be read from a filesystem, in addition to in-memory keys. `USE_MULTITHREADING` -: coreConfig.h: Enable if using MatrixSSL with a multithreading client or server, where session cache may be shared between threads simultaneously. +: coreConfig.h: Enable if using @matrixssl with a multithreading client or server, where session cache may be shared between threads simultaneously. + + +## Public Key Math Assembly Optimizations -##4.2 Public Key Math Assembly Optimizations Optimizing assembly code for low level math operations is available for many common processor architectures. The files _pstm_montgomery_reduce.c_, _pstm_mul_comba.c_, and _pstm_sqr_comba.c_ in the _crypto/math_ directory implement the available assembly optimizations. These following defines are set in the _osdep.h_ header file by detecting the platform. These should be set accordingly when porting to an unsupported platform. `PSTM_X86` @@ -727,8 +809,10 @@ Optimizing assembly code for low level math operations is available for many com *None of the above* : Standard C code implementation -##4.3 Debug Configuration -MatrixSSL contains a set of optional debug features that are configurable at compile time. Each of these options are pre-processor defines that can be disabled by simply commenting out the `#define` in the specified header files. + +## Debug Configuration + +@matrixssl contains a set of optional debug features that are configurable at compile time. Each of these options are pre-processor defines that can be disabled by simply commenting out the `#define` in the specified header files. `HALT_ON_PS_ERROR` : coreConfig.h - Enables the osdepBreak platform function whenever a psError trace function is called. Helpful in debug environments. @@ -753,8 +837,10 @@ MatrixSSL contains a set of optional debug features that are configurable at com `DTLS_SEND_RECORDS_INDIVIDUALLY` : matrixsslConfig.h - If enabled, each DTLS handshake message will be returned individually when matrixDtlsGetOutdata is called. When left disabled, the default behaviour of matrixDtlsGetOutdata is to return as much data as possible that fits within the maximum PMTU. -##4.4 Minimum Firmware Configuration -MatrixSSL can be built to a minimum size using TLS 1.2, PSK cipher with AES128 and SHA256. If interoperability with *OpenSSL* is desired, then a few changes are necessary, since the USE_TLS_PSK_WITH_AES_128_CBC_SHA256 ciphersuite is not implemented by OpenSSL (as of 1.0.2d). In this case, `USE_SHA1` and `USE_HMAC_SHA1` must also be defined and the cipher suite changed to + +## Minimum Firmware Configuration + +@matrixssl can be built to a minimum size using TLS 1.2, PSK cipher with AES128 and SHA256. If interoperability with *OpenSSL* is desired, then a few changes are necessary, since the USE_TLS_PSK_WITH_AES_128_CBC_SHA256 ciphersuite is not implemented by OpenSSL (as of 1.0.2d). In this case, `USE_SHA1` and `USE_HMAC_SHA1` must also be defined and the cipher suite changed to `USE_TLS_PSK_WITH_AES_256_CBC_SHA` or `USE_TLS_PSK_WITH_AES_128_CBC_SHA`. @@ -785,9 +871,10 @@ Optional: For *OpenSSL* compatibility, enable: :---:|:---: 24,108 B | 25,771 B -##4.5 Example configurations -MatrixSSL ships with a few example configurations, which are described here. _MatrixSSL FIPS edition_ contains additional example configurations; these are described in the _MatrixCrypto CL_ document included in that distribution. +## Example configurations + +@matrixssl ships with a few example configurations, which are described here. @matrixssl FIPS edition contains additional example configurations; these are described in the *MatrixCrypto CL* document included in that distribution. Configuration|Comment ---|--- @@ -797,14 +884,20 @@ noecc|Disables ECC support rsaonly|Disables ECC and DH support tls|The recommended configuration for TLS nonfips-psk|The minimal PSK configuration described in the last subsection, except that both server- and client side support are enabled. -These configurations can be applied with the commands _make all-nonfips_, _make all-noecc_, _make all-rsaonly_, _make all-tls_, _make all-nonfips-psk_ respectively. Applying a new configuration will override the existing _./core/coreConfig.h_, _./crypto/cryptoConfig.h_, and _./matrixssl/matrixsslConfig.h_ files. After applying the configuration, these files can be further adapted per specific needs and the MatrixSSL can be compiled as usual, via the make commands described in the _MatrixSSL Getting Started_ document. +These configurations can be applied with the commands _make all-nonfips_, _make all-noecc_, _make all-rsaonly_, _make all-tls_, _make all-nonfips-psk_ respectively. Applying a new configuration will override the existing _./core/coreConfig.h_, _./crypto/cryptoConfig.h_, and _./matrixssl/matrixsslConfig.h_ files. After applying the configuration, these files can be further adapted per specific needs and the @matrixssl can be compiled as usual, via the make commands described in the *Getting Started* document. + + +# SSL HANDSHAKING -#5 SSL HANDSHAKING The core of SSL security is the handshake protocol that allows two peers to authenticate and negotiate symmetric encryption keys. A handshake is defined by the specific sequence of SSL messages that are exchanged between the client and server. A collection of messages being sent from one peer to another is called a flight. -##5.1 Standard Handshake + +## Standard Handshake + The standard handshake is the most common and allows a client to authenticate a server. There are four flights in the standard handshake. -```sequence + +``` +sequence Participant Client as c Participant Server as s Title: Standard TLS Handshake @@ -825,11 +918,17 @@ Note over c,s: APP_DATA Note over s,c: s-c: CLOSURE_ALERT ``` -**Client Notes** -The client is the first to send and the last to receive. Therefore, a MatrixSSL implementation of a client must be testing for the `MATRIXSSL_HANDSHAKE_COMPLETE` return code from `matrixSslReceivedData` to determine when application data is ready to be encrypted and sent to the server. When a client wishes to begin a standard handshake, `matrixSslNewClientSession` will be called with an empty sessionId. -##5.2 Client Authentication Handshake + +**Client Notes** + +The client is the first to send and the last to receive. Therefore, a @matrixssl implementation of a client must be testing for the `MATRIXSSL_HANDSHAKE_COMPLETE` return code from `matrixSslReceivedData` to determine when application data is ready to be encrypted and sent to the server. When a client wishes to begin a standard handshake, `matrixSslNewClientSession` will be called with an empty sessionId. + + +## Client Authentication Handshake + The client authentication handshake allows a two-way authentication. There are four flights in the client authentication handshake. + ```sequence Participant Client as c Participant Server as s @@ -852,17 +951,24 @@ Note over s,c: Note over c,s: APP_DATA Note over s,c: s-c: CLOSURE_ALERT + ``` -**Client Notes** -The client is the first to send and the last to receive. Therefore, a MatrixSSL implementation of a client must be testing for the `MATRIXSSL_HANDSHAKE_COMPLETE` return code from `matrixSslReceivedData` to determine when application data is ready to be encrypted and sent to the server. +**Client Notes**: + +The client is the first to send and the last to receive. Therefore, a @matrixssl implementation of a client must be testing for the `MATRIXSSL_HANDSHAKE_COMPLETE` return code from `matrixSslReceivedData` to determine when application data is ready to be encrypted and sent to the server. In order to participate in a client authentication handshake, the client must have loaded a Certificate Authority file during the call to `matrixSslLoadRsaKeys`. -**Server Notes** + +**Server Notes**: + To prepare for a client authentication handshake the server must nominate a certificate and private key during the call to `matrixSslLoadRsaKeys`. The actual determination of whether or not to perform a client authentication handshake is made when nominating a certificate callback parameter when invoking `matrixSslNewServerSession`. If the callback is provided, a client authentication handshake will be requested. -  -##5.3 Session Resumption Handshake + + +## Session Resumption Handshake + Session resumption enables a previously connected client to quickly resume a session with a server. Session resumption is much faster than other handshake types because public key authentication is not performed (authentication is implicit since both sides will be using secret information from the previous connection). This handshake types has three flights. + ```sequence Participant Client as c Participant Server as s @@ -880,107 +986,120 @@ Note over c,s: APP_DATA Note over s,c: s-c: CLOSURE_ALERT ``` -**Client Notes** -The client is the first and the last to send data. Therefore, a MatrixSSL implementation of a client must be testing for the `MATRIXSSL_HANDSHAKE_COMPLETE` return code from `matrixSslSentData` to determine when application data is ready to be encrypted and sent to the server. + +**Client Notes:** +The client is the first and the last to send data. Therefore, a @matrixssl implementation of a client must be testing for the `MATRIXSSL_HANDSHAKE_COMPLETE` return code from `matrixSslSentData` to determine when application data is ready to be encrypted and sent to the server. The client initiates a session resumption handshake by reusing the same `sessionId_t` structure from a previously connected session when calling `matrixSslNewClientSession`. -**Server Notes** -The MatrixSSL server will cache a `SSL_SESSION_TABLE_SIZE` number of session IDs for resumption. The length of time a session ID will remain in the case is determined by `SSL_SESSION_ENTRY_LIFE`. Also, the server sends the `FINISHED` message first in this case, which is different from the standard handshake. +**Server Notes:** +The @matrixssl server will cache a `SSL_SESSION_TABLE_SIZE` number of session IDs for resumption. The length of time a session ID will remain in the case is determined by `SSL_SESSION_ENTRY_LIFE`. Also, the server sends the `FINISHED` message first in this case, which is different from the standard handshake. + + +## Other Handshakes -##5.4 Other Handshakes Other cipher suites can require variations on the handshake flights. PSK cipher suites do not use any key exchange. DSA cipher suites do not use certificates, and DH/DHE/ECDH/ECDHE cipher suites may or may not use certificates for authentication. -##5.5 Re-Handshakes + +## Re-Handshakes + A re-handshake is a handshake over a currently connected SSL session. A re-handshake may take the form of a standard handshake, a client authentication handshake, or a resumed handshake. Either the client or server may initiate a re-handshake. ->Re-handshaking is not often used and can be the source of cross protocol attacks and implementation bugs. MatrixSSL by default disables the `USE_REHANDSHAKING` option at compile time to reduce code size and complexity. +>Re-handshaking is not often used and can be the source of cross protocol attacks and implementation bugs. @matrixssl by default disables the `USE_REHANDSHAKING` option at compile time to reduce code size and complexity. The `matrixSslEncodeRehandshake` API is used to initiate a re-handshake. The three most common reasons for initiating re-handshakes are: -1. *Re-key the symmetric cryptographic material* +1. *Re-key the symmetric cryptographic material* Re-keying the symmetric keys adds an extra level of security for applications that require the connection be open for long periods of time or transferring large amounts of data. Periodic changes to the keys can discourage hackers who are mounting timing attacks on a connection. -2. *Perform a client authentication handshake* + +2. *Perform a client authentication handshake* A scenario may arise in which the server requires that the data being exchanged is only allowed for a client whose certificate has been authenticated, but the original negotiation took place without client authentication. In order to do a client authenticated re-handshake the server must call matrixSslEncodeRehandshake with a certificate callback parameter. -3. *Change cipher spec* + +3. *Change cipher spec* The cipher suite may be changed on a connected session using a re-handshake if needed. The client must call matrixSslEncodeRehandshake with the new cipherSpec. -###5.5.1 Disable Re-Handshaking At Runtime + +### Disable Re-Handshaking At Runtime + Global disabling of re-handshakes can be controlled at compile time using the `USE_REHANDSHAKING` define but sometimes a per-session control of the feature is required. In these cases, the `matrixSslDisableRehandshakes` and `matrixSslReEnableRehandshakes` APIs are used. -###5.5.2 The Re-Handshake Credit Mechanism -The re-handshake feature has been used at the entry point in a couple TLS attacks. In an effort to combat these attacks, MatrixSSL has incorporated a mechanism that prevents a peer from continually re-handshaking. This “re-handshake credit” mechanism is simply a count of how often the MatrixSSL-enabled application will allow a peer to request a re-handshake before sending the `NO_RENEGOTIATION` alert. The default number of credits is set using the `DEFAULT_RH_CREDITS` define in _matrixssllib.h_. The shipped default is 1. + +### The Re-Handshake Credit Mechanism + +The re-handshake feature has been used at the entry point in a couple TLS attacks. In an effort to combat these attacks, @matrixssl has incorporated a mechanism that prevents a peer from continually re-handshaking. This “re-handshake credit” mechanism is simply a count of how often the @matrixssl enabled application will allow a peer to request a re-handshake before sending the `NO_RENEGOTIATION` alert. The default number of credits is set using the `DEFAULT_RH_CREDITS` define in _matrixssllib.h_. The shipped default is 1. In order to allow real-life conditions of re-handshakes, a single credit will be added after transmitting a given number of application data bytes. The default count of bytes that have to be sent before gaining a credit is set using the `BYTES_BEFORE_RH_CREDIT` define in _matrixssllib.h_. The shipped default is 20MB. -#6 OPTIONAL FEATURES + +# OPTIONAL FEATURES + This section describes some of the optional SSL handshake features. Additional details can be found in the API documentation for the specific functions that are referenced here. -##6.1 Stateless Session Ticket Resumption + +## Stateless Session Ticket Resumption + [RFC 5077](https://tools.ietf.org/html/rfc5077) defines an alternative method to the standard server-cached session ID mechanism. The stateless ticket mechanism allows the server to send an encrypted session ticket to the client that the client can use in a later connection to speed up the handshake process. The server does not have to store a large number of session ID entries when this stateless mechanism is used. -**Servers and Clients** -The feature is made available with the USE_STATELESS_SESSION_TICKETS define in _matrixsslConfig.h_. +**Servers and Clients**: The feature is made available with the USE_STATELESS_SESSION_TICKETS define in _matrixsslConfig.h_. -**Clients** -Clients that wish to use the stateless session resumption mechanism must set the ticketResumption member of the `sslSessOpts_t` structure to 1 when calling `matrixSslNewClientSession`. +**Clients**: Clients that wish to use the stateless session resumption mechanism must set the ticketResumption member of the `sslSessOpts_t` structure to 1 when calling `matrixSslNewClientSession`. With that session option set, the client only has to use the standard session resumption API, `matrixSslNewSessionId`, to complete the use of the feature. If a server does not support stateless session tickets, the standard resumption mechanism will still work. -**Servers** -The server must load at least one session ticket key using `matrixSslLoadSessionTicketKeys` to enable the feature. A user callback can optionally be registered that will be called each time a session ticket is received from a client. The callback will indicate to the user whether or not the server already has the correct ticket key cached. The callback can be used to locate a ticket key or to void the ticket and revert to a full handshake. The `matrixSslSetSessionTicketCallback` API is used to register this function. -The MatrixSSL implementation for resumption does not renew the session ticket as described in section [3.1 of the RFC](https://tools.ietf.org/html/rfc5077#section-3.1) (Figure 2). If the ticket is valid, the server progresses with the standard resumed handshake without a `NewSessionTicket` handshake message. If the server is unable to decrypt the session ticket, a full handshake will take place and a new session ticket will be issued. The MatrixSSL library also handles the expiration of a session ticket based on the value of the `SSL_SESSION_ENTRY_LIFE` in _matrixsslConfig.h_. +**Servers**: The server must load at least one session ticket key using `matrixSslLoadSessionTicketKeys` to enable the feature. A user callback can optionally be registered that will be called each time a session ticket is received from a client. The callback will indicate to the user whether or not the server already has the correct ticket key cached. The callback can be used to locate a ticket key or to void the ticket and revert to a full handshake. The `matrixSslSetSessionTicketCallback` API is used to register this function. + +The @matrixssl implementation for resumption does not renew the session ticket as described in section [3.1 of the RFC](https://tools.ietf.org/html/rfc5077#section-3.1) (Figure 2). If the ticket is valid, the server progresses with the standard resumed handshake without a `NewSessionTicket` handshake message. If the server is unable to decrypt the session ticket, a full handshake will take place and a new session ticket will be issued. The @matrixssl library also handles the expiration of a session ticket based on the value of the `SSL_SESSION_ENTRY_LIFE` in _matrixsslConfig.h_. + + +## Server Name Indication Extension -##6.2 Server Name Indication Extension [RFC 6066](https://tools.ietf.org/html/rfc6066) defines a TLS hello extension to allow the client to send the name of the server it is trying to securely connect to. This allows “virtual” servers to locate the correct server with the expected key material to complete the connection. -**Servers** -Server applications should register the SNI callback using `matrixSslRegisterSNICallback`. This function must be called immediately after `matrixSslNewServerSession` before the first incoming flight from the client is processed. The callback will be invoked during the processing of the `CLIENT_HELLO` message if the client has included the SNI extension. The callback will use the incoming hostname to locate the correct key material and return them in the `sslKeys_t` structure format. +**Servers**: Server applications should register the SNI callback using `matrixSslRegisterSNICallback`. This function must be called immediately after `matrixSslNewServerSession` before the first incoming flight from the client is processed. The callback will be invoked during the processing of the `CLIENT_HELLO` message if the client has included the SNI extension. The callback will use the incoming hostname to locate the correct key material and return them in the `sslKeys_t` structure format. -**Clients** -Clients must include the SNI extension in the `CLIENT_HELLO` message. The utility function `matrixSslCreateSNIext` is provided to help format the extension given a hostname and hostname length. Once the extension format has been created it will be loaded into the `tlsExtension_t` structure with the `matrixSslLoadHelloExtension` API (`matrixSslNewHelloExtension` must first be called). The `tlsExtension_t` type is then passed to `matrixSslNewClientSession` to complete the client side SNI integration. +**Clients**: Clients must include the SNI extension in the `CLIENT_HELLO` message. The utility function `matrixSslCreateSNIext` is provided to help format the extension given a hostname and hostname length. Once the extension format has been created it will be loaded into the `tlsExtension_t` structure with the `matrixSslLoadHelloExtension` API (`matrixSslNewHelloExtension` must first be called). The `tlsExtension_t` type is then passed to `matrixSslNewClientSession` to complete the client side SNI integration. + + +## Extended Master Secret -##6.3 Extended Master Secret The “extended master secret” as specified in [RFC 7627](https://tools.ietf.org/html/rfc7627) is an important security feature for TLS implementations that use session resumption. The extended master secret feature associates the internal TLS master secret directly to the connection context to prevent man-in-the-middle attacks during session resumption. One such attack is a synchronizing triple handshake as described in [Triple Handshakes and Cookie Cutters: Breaking and Fixing Authentication over TLS](https://mitls.org/pages/attacks/3SHAKE). -This feature is always enabled by default in both MatrixSSL clients and servers. The peer agreement mechanism is the `CLIENT_HELLO` and `SERVER_HELLO` `extended_master_secret` extension. +This feature is always enabled by default in both @matrixssl clients and servers. The peer agreement mechanism is the `CLIENT_HELLO` and `SERVER_HELLO` `extended_master_secret` extension. -**Clients** -A client will always include the `extended_master_secret` extension when creating the `CLIENT_HELLO` message. If the server replies with an `extended_master_secret`, the upgraded master secret generation will be used. If the server does not reply with an `extended_master_secret`, the standard master secret generation will be used for the connection. +**Clients**: A client will always include the `extended_master_secret` extension when creating the `CLIENT_HELLO` message. If the server replies with an `extended_master_secret`, the upgraded master secret generation will be used. If the server does not reply with an `extended_master_secret`, the standard master secret generation will be used for the connection. A client may REQUIRE that a server support the `extended_master_secret` feature by setting the `extendedMasterSecret` member of `sslSessOpts_t` to 1. The `sslSessOpts_t` structure is passed to `matrixSslNewClientSession` when starting a TLS session. If `extendedMasterSecret` is set, the client will send a fatal `handshake_failure` alert to the server if the `extended_master_secret` extension is not included in the `SERVER_HELLO`. -**Servers** -A server will always reply with the `extended_master_secret` extension if the client includes it in the `CLIENT_HELLO` message. +**Servers**: A server will always reply with the `extended_master_secret` extension if the client includes it in the `CLIENT_HELLO` message. A server may **require** that a client support the `extended_master_secret` feature by setting the `extendedMasterSecret` member of `sslSessOpts_t` to 1. The `sslSessOpts_t` structure is passed to `matrixSslNewServerSession` when starting a TLS session. If `extendedMasterSecret` is set, the server will send a fatal `handshake_failure` alert to the client if the `extended_master_secret` extension is not included in the `CLIENT_HELLO`. When creating the session resumption information (either the standard session table or the stateless session ticket) the server will flag whether the extended master secret was used for the initial connection. When a client attempts session resumption, the `CLIENT_HELLO` must include the `extended_master_secret` extension if it was used in the initial connection. Likewise, if the initial connection did not use the `extended_master_secret` the session resumption `CLIENT_HELLO` must also exclude that extension. If there is a mismatch, the server will not allow the session resumption and a full handshake will occur instead. -##6.4 Maximum Fragment Length + +## Maximum Fragment Length + [RFC 6066](https://tools.ietf.org/html/rfc6066) defines a TLS extension for negotiating a smaller maximum message size. The default maximum is 16KB (and can't be set larger). The only allowed sizes that may be negotiated are 512, 1024, 2048, or 4096 bytes. The client requests the feature in a `CLIENT_HELLO` extension and if the server agrees to the new maximum fragment length it will acknowledge that in the `SERVER_HELLO` reply. -**Clients** -To request a smaller maximum fragment length the user sets the maxFragLen member of the `sslSessOpts_t * ` options parameter to 512, 1024, 2048, or 4096 when calling `matrixSslNewClientSession`. The server is free to deny the request. +**Clients**: To request a smaller maximum fragment length the user sets the maxFragLen member of the `sslSessOpts_t * ` options parameter to 512, 1024, 2048, or 4096 when calling `matrixSslNewClientSession`. The server is free to deny the request. -**Servers** -Servers will agree to the maximum fragment length request by default. To disable the feature for a session, the user may set the `maxFragLen` member of the `sslSessOpts_t * ` options parameter to -1 when calling `matrixSslNewServerSession`. +**Servers**: Servers will agree to the maximum fragment length request by default. To disable the feature for a session, the user may set the `maxFragLen` member of the `sslSessOpts_t * ` options parameter to -1 when calling `matrixSslNewServerSession`. + + +## Truncated HMAC -##6.5 Truncated HMAC [RFC 6066](https://tools.ietf.org/html/rfc6066) defines a TLS extension for negotiating an HMAC length of 10 bytes. The client requests the feature in a `CLIENT_HELLO` extension and if the server agrees to the truncation it will acknowledge that in the `SERVER_HELLO` reply. -**Clients** -To request a truncated HMAC session the user sets the `truncHmac` member of the `sslSessOpts_t * `options parameter to PS_TRUE when calling `matrixSslNewClientSession`. The server is free to deny the request. +**Clients**: To request a truncated HMAC session the user sets the `truncHmac` member of the `sslSessOpts_t * `options parameter to PS_TRUE when calling `matrixSslNewClientSession`. The server is free to deny the request. -**Servers** -Servers will agree to HMAC truncation by default. To disable the feature for a session, the user may set the `truncHmac` member of the `sslSessOpts_t * ` options parameter to -1 when calling `matrixSslNewServerSession`. +**Servers**: Servers will agree to HMAC truncation by default. To disable the feature for a session, the user may set the `truncHmac` member of the `sslSessOpts_t * ` options parameter to -1 when calling `matrixSslNewServerSession`. -##6.6 Application Layer Protocol Negotiation Extension -[RFC 7301](https://tools.ietf.org/html/rfc7301) defines a TLS hello extension that enables servers and client to agree on the protocol that will be used after the TLS handshake is complete. The idea is to embed the negotiation in the TLS handshake to save any round trips that might be needed to negotiate the protocol after the handshake. The extension works the same as any extension by the client sending a list of protocols it wishes to use in the `CLIENT_HELLO` and the server replying with an extension in the `SERVER_HELLO`. The trade-off for negotiating the protocol during the handshake is that both MatrixSSL servers and clients must be prepared to intervene in the middle of the handshake process via registered callback functions. -**Servers and Clients** -The ALPN extension APIs will be available only if the `USE_ALPN` define in _matrixsslConfig.h_ is enabled at compile-time. The define `MAX_PROTO_EXT` is the maximum number of protocols that can be expected in the list of protocols. The default is 8 and can be found in _matrixssllib.h_. +## Application Layer Protocol Negotiation Extension -**Servers** -Servers that wish to process ALPN extensions sent from a client must call the `matrixSslRegisterALPNCallback` function immediately after the session is created with `matrixSslNewServerSession`. The timing of the registration is important so that the callback can be associated with the proper session context before the first handshake message from the client is passed to `matrixSslReceivedData`. +[RFC 7301](https://tools.ietf.org/html/rfc7301) defines a TLS hello extension that enables servers and client to agree on the protocol that will be used after the TLS handshake is complete. The idea is to embed the negotiation in the TLS handshake to save any round trips that might be needed to negotiate the protocol after the handshake. The extension works the same as any extension by the client sending a list of protocols it wishes to use in the `CLIENT_HELLO` and the server replying with an extension in the `SERVER_HELLO`. The trade-off for negotiating the protocol during the handshake is that both @matrixssl servers and clients must be prepared to intervene in the middle of the handshake process via registered callback functions. + +**Servers and Clients**: The ALPN extension APIs will be available only if the `USE_ALPN` define in _matrixsslConfig.h_ is enabled at compile-time. The define `MAX_PROTO_EXT` is the maximum number of protocols that can be expected in the list of protocols. The default is 8 and can be found in _matrixssllib.h_. + +**Servers**: Servers that wish to process ALPN extensions sent from a client must call the `matrixSslRegisterALPNCallback` function immediately after the session is created with `matrixSslNewServerSession`. The timing of the registration is important so that the callback can be associated with the proper session context before the first handshake message from the client is passed to `matrixSslReceivedData`. The server ALPN callback that is registered with `matrixSslRegisterALPNCallback` must have a prototype of: ```C @@ -1002,8 +1121,7 @@ void ALPN_callback(void *ssl, short protoCount, char *proto[MAX_PROTO_EXT], int3 - A negative value assigned to index indicates the server is not willing to communicate using any of the protocols. A fatal “`no_application_protocol`” alert will be sent to the client and the handshake will terminate. - If the callback does not assign any value to the outgoing parameter, the server will not take any action. That is, neither a reply ALPN extension nor an alert will be sent to the client and the handshake will continue normally. -**Clients** -To support this feature, clients must be able to generate the ALPN extension and also receive the server reply. +**Clients**: To support this feature, clients must be able to generate the ALPN extension and also receive the server reply. To generate the ALPN extension, the API `matrixSslCreateALPNext` is used in conjunction with the `matrixSslNewHelloExtension` or `matrixSslLoadHelloExtension` framework. @@ -1032,11 +1150,15 @@ matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers, certCb, g_ip, ex matrixSslDeleteHelloExtension(extension); ``` -To receive the server reply to the ALPN extension the client must register an extension callback routine using the `extCb` parameter when calling `matrixSslNewClientSession`. The callback will be invoked with the ALPN extension ID of `EXT_ALPN` (16) with a format of a single byte length followed by the protocol string value the server has agreed to. -See the example in _apps/ssl/client.c_ for full implementation details. +To receive the server reply to the ALPN extension the client must register an extension callback routine using the `extCb` parameter when calling `matrixSslNewClientSession`. The callback will be invoked with the ALPN extension ID of `EXT_ALPN` (16) with a format of a single byte length followed by the protocol string value the server has agreed to. + +See the example in `apps/ssl/client.c` for full implementation details. + + +## TLS Fallback SCSV + +[RFC 7507](https://tools.ietf.org/html/rfc7507) defines a method to prevent protocol downgrade attacks. Such an attack is illustrated below: -##6.7 TLS Fallback SCSV -[RFC 7507](https://tools.ietf.org/html/rfc7507) defines a method to prevent protocol downgrade attacks. Such an attack is illustrated below: ```sequence Participant Client as c Participant Attacker as a @@ -1057,7 +1179,8 @@ c-s: CLIENT_HELLO (SSL 3.0) s-c: SERVER_HELLO (SSL 3.0) Note over s,c: Attacker exploits SSL3.0 Vulnerabilities ``` -MatrixSSL does not automatically do such version fallback, but client software using MatrixSSL may choose to do this for compatibility with unknown servers. In this case, the `TLS_FALLBACK_SCSV` option flag MUST be set for each connection attempt at a lower protocol version. This will mitigate the attack as follows: + +@matrixssl does not automatically do such version fallback, but client software using @matrixssl may choose to do this for compatibility with unknown servers. In this case, the `TLS_FALLBACK_SCSV` option flag MUST be set for each connection attempt at a lower protocol version. This will mitigate the attack as follows: ```sequence Participant Client as c Participant Attacker as a @@ -1084,10 +1207,11 @@ If the client connection is being made at a lower protocol level because the ser Servers will evaluate the FALLBACK_SCSV indication automatically as per RFC: > If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest protocol version supported by the server is higher than the version indicated in ClientHello.client_version, the server MUST respond with a fatal inappropriate_fallback alert -##6.8 OCSP -The Online Certificate Status Protocol (OCSP) is an alternative to the Certificate Revocation List (CRL) mechanism for performing certificate revocation tests on server keys. TLS integrates with OCSP in a mechanism known as _OCSP stapling_. This feature allows the client to request that the server provide a time-stamped OCSP response when presenting the X.509 certificate during the TLS handshake. The primary goal for this method is to allow resource constrained clients to perform certificate revocation tests without having to communicate with an OCSP Responder themselves. The general process is illustrated below. The MatrixSSL also -supports OCSP request generation, to do revocation tests on certificates without -TLS server supporting OCSP stapling. + +## Online Certificate Status Protocol (OCSP) + +The Online Certificate Status Protocol (OCSP) is an alternative to the Certificate Revocation List (CRL) mechanism for performing certificate revocation tests on server keys. TLS integrates with OCSP in a mechanism known as _OCSP stapling_. This feature allows the client to request that the server provide a time-stamped OCSP response when presenting the X.509 certificate during the TLS handshake. The primary goal for this method is to allow resource constrained clients to perform certificate revocation tests without having to communicate with an OCSP Responder themselves. The general process is illustrated below. The @matrixssl also +supports OCSP request generation, to do revocation tests on certificates without TLS server supporting OCSP stapling. OCSP stapling is specified in Section 8 (Certificate Status Request) of the TLS Extensions [RFC 6066](https://tools.ietf.org/html/rfc6066#section-8). The `USE_OCSP` define in cryptoConfig.h must be enabled for these features to be available. @@ -1111,17 +1235,18 @@ Note over s,c: ... **Clients** A client application can request OCSP stapling by setting the OCSPstapling member of the `sslSessOpts_t` structure when invoking `matrixSslNewClientSession`. This flag will trigger the creation of the Certificate Status Request extension in the `CLIENT_HELLO` message. The resulting `status_request` extension will not specify any responder identification hints or request extensions. This indicates that the server is free to provide whatever OCSP response is relevant to its identity certificate. -In order to validate the signature of provided OCSP response, the client will have to verify the Certificate Authority of the OCSP responder. There are two places the MatrixSSL library will search for this CA file. The first place the library will look is in the CA material that is loaded in the standard `matrixSslLoadRsaKeys` (or `matrixSslLoadEcKeys`) API. If the CA file is not located in this pre-loaded key material, the library will next look to the server’s certificate chain. In practice, many TLS servers that implement OCSP stapling will create a certificate chain in which the parent certificate of the primary identity certificate also acts as the OCSP responder. At the time of the OCSP validation test, the `CERTIFICATE` message will have already been processed and validated. If the client has confirmed the server to have a valid chain of trust, it is appropriate to trust that same certificate chain to provide the OSCP response. If the client is unable to locate the CA file for the public key of the OCSP responder, the handshake will fail. +In order to validate the signature of provided OCSP response, the client will have to verify the Certificate Authority of the OCSP responder. There are two places the @matrixssl library will search for this CA file. The first place the library will look is in the CA material that is loaded in the standard `matrixSslLoadRsaKeys` (or `matrixSslLoadEcKeys`) API. If the CA file is not located in this pre-loaded key material, the library will next look to the server’s certificate chain. In practice, many TLS servers that implement OCSP stapling will create a certificate chain in which the parent certificate of the primary identity certificate also acts as the OCSP responder. At the time of the OCSP validation test, the `CERTIFICATE` message will have already been processed and validated. If the client has confirmed the server to have a valid chain of trust, it is appropriate to trust that same certificate chain to provide the OSCP response. If the client is unable to locate the CA file for the public key of the OCSP responder, the handshake will fail. In order to validate the time stamp of the OCSP response the client library will invoke the `checkOCSPtimestamp` function in _crypto/keyformat/x509.c_. The default time window for accepting an OCSP response is 1 week and can be changed using the `OCSP_VALID_TIME_WINDOW` define in _cryptolib.h_. The OCSP stapling specification does not have guidance on how a client should behave if a server does not provide a `CERTIFICATE_STATUS` message when requested. The `USE_OCSP_MUST_STAPLE` define in _matrixsslConfig.h_ is included to allow the client application to require that the server provide the message. If `USE_OCSP_MUST_STAPLE` is enabled and the client has requested `CERTIFICATE_STATUS`, the handshake will abort if the server does not provide one. **Servers** -A server application wishing to support OCSP stapling must communicate out of band with an OCSP responder to periodically update the signed OCSP response, as defined in [RFC 6960](https://tools.ietf.org/html/rfc6960). The response is loaded into MatrixSSL by calling `matrixSslLoadOCSPResponse`. This function takes a fully formed `OCSPResponse` ASN.1 buffer as defined in [RFC6960 section 4.2](https://tools.ietf.org/html/rfc6960#section-4.2) and loads it into the provided `sslKeys_t` structure. Whenever the server application gets a new OCSP response, the same `matrixSslLoadOCSPResponse` API can be called to update the `sslKeys_t` structure. +A server application wishing to support OCSP stapling must communicate out of band with an OCSP responder to periodically update the signed OCSP response, as defined in [RFC 6960](https://tools.ietf.org/html/rfc6960). The response is loaded into @matrixssl by calling `matrixSslLoadOCSPResponse`. This function takes a fully formed `OCSPResponse` ASN.1 buffer as defined in [RFC6960 section 4.2](https://tools.ietf.org/html/rfc6960#section-4.2) and loads it into the provided `sslKeys_t` structure. Whenever the server application gets a new OCSP response, the same `matrixSslLoadOCSPResponse` API can be called to update the `sslKeys_t` structure. When a client sends the `status_request` extension the server will look to see if an OCSP response is available in the `sslKeys_t` structure and reply with a `status_request` extension and the `CERTIFICATE_STATUS` message that holds the OCSP response for the client to validate. + ### Configuring OCSP Feature for Use The OCSP functionality depends on definitions in `cryptoConfig.h`. Full read/write functionality and server features requires following defines: @@ -1134,21 +1259,22 @@ The OCSP functionality depends on definitions in `cryptoConfig.h`. Full read/wri #define USE_OCSP_MUST_STAPLE ``` -The standard configurations like `default` on *MatrixSSL* FIPS and Commercial releases have already neccessary features enabled. +The standard configurations like `default` on *@matrixssl* FIPS and Commercial releases have already neccessary features enabled. + ### Invoking OCSP Manually #### OCSP Example Application -OCSP use has example application `ocsp.c` in `apps/crypto` subdirectory of *MatrixSSL*. The compiled application will be known as `matrixOCSP`. +OCSP use has example application `ocsp.c` in `apps/crypto` subdirectory of *@matrixssl*. The compiled application will be known as `matrixOCSP`. This application can be used to create OCSP requests and get responses. The easiest way to study OCSP functionality is to use and examine this application. The application provides usage instructions when invoked without parameters. Some of most interesting options include `-request`and `-reply` which allow storing requests and responses for examination with various other tools supporting OCSP and/or ASN.1 DER/BER. -The most MatrixSSL supported functions are used by this program. +The most @matrixssl supported functions are used by this program. The most of functionality of `ocsp.c` program is found in `OCSPRequestAndResponseTest()` function, and this function is most useful to study for creating OCSP requests and validating OCSP responses. #### Creating OCSP request data -In MatrixSSL, function `matrixSslWriteOCSPRequestExt()` is used to create OCSP requests. +In @matrixssl, function `matrixSslWriteOCSPRequestExt()` is used to create OCSP requests. The function is invoked as follows: ``` {.c} @@ -1168,18 +1294,21 @@ The memory pool is usually passed in as NULL. The certificates `subject` (cert `info` is used to provide options for OCSP request. These options are discussed below. The memory allocated for OCSP request shall be freed after the request is no longer needed. + ##### Providing Nonce Extension -The *MatrixSSL* provides nonce for OCSP nonce extension via `info.flags` flag `MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_NONCE`. The OCSP nonce extension provide unique nonce value, which can be used to the request is replied with a new (rather than cached) OCSP response. +*@matrixssl* provides nonce for OCSP nonce extension via `info.flags` flag `MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_NONCE`. The OCSP nonce extension provide unique nonce value, which can be used to the request is replied with a new (rather than cached) OCSP response. + ##### Providing name for requestor (requestorName) -The MatrixSSL allows providing name for OCSP requestor. The name is represented +The @matrixssl allows providing name for OCSP requestor. The name is represented using X.509 GeneralName. matrixSslWriteOCSPRequestInfoSetRequestorId() function is provided to help encoding the OCSP requestor name in suitable format for OCSP request. Note: This option is relatively rarely used and some OCSP Responders will reject requests with RequestorName. + ##### Providing list of requests (requestList) If `matrixSslWriteOCSPRequestInfo_t` flag `MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_CERT_LIST` is specified, @@ -1189,9 +1318,10 @@ traffic when working with the certificates from the same issuer. Note: Some OCSP responders only support single request, and will reject requests concerning multiple certificates. + #### Interacting with OCSP server -The most OCSP servers use **HTTP** protocol. The *MatrixSSL* provides `psUrlInteract()` function, to create HTTP request and get HTTP response. When OCSP is used in SSL/TLS context, the most commonly `subject` certificate will contain AuthorityInfoAccess information regarding what server will provide OCSP information. It is accessed via `authorityInfoAccess` field of the Certificate structure `psX509Cert_t`. +The most OCSP servers use **HTTP** protocol. *@matrixssl* provides `psUrlInteract()` function, to create HTTP request and get HTTP response. When OCSP is used in SSL/TLS context, the most commonly `subject` certificate will contain AuthorityInfoAccess information regarding what server will provide OCSP information. It is accessed via `authorityInfoAccess` field of the Certificate structure `psX509Cert_t`. You can see `getOCSPResponse()` function in `ocsp.c` for a concrete example on how to interact with the server. @@ -1221,6 +1351,7 @@ static char *getAuthorityInfoOCSP_URI(const psX509Cert_t *subject) The interaction will result in getting an HTTP error code or OCSP response. The OCSP response can be analyzed and verified using the functions described in the next chapter. + #### Working with OCSP response Working with OCSP response actually consists of four phases: @@ -1232,6 +1363,7 @@ Working with OCSP response actually consists of four phases: The functions support both OCSP responses just retrieved as response to a constructed OCSP request and cached OCSP requests. One type of cache OCSP response often used in SSL/TLS is the ones used in OCSP stapling. + #### Obtaining and checking issuer certificate To validate OCSP response, an issuer certificate is used. Many organizations use the same certificates to sign OCSP responses than are used to validate certificates themselves. In this case, the issuer certificate has been obtained and validated already as part of X.509 certificate validation. In case, OCSP responses have been signed with other keys designated for that purpose, then they shall be validated just like any other X.509 intermediate certificate, e.g. using `psX509ParseCert()` and `psX509AuthenticateCert()`. @@ -1250,10 +1382,12 @@ if ((ext->keyUsageFlags & KEY_USAGE_DIGITAL_SIGNATURE) > 0) ``` Only if both key usage and extended key usage flags are found in the certificate, the key can be considered to be marked for OCSP usage. However, many of the keys used for OCSP do not have this purpose marked in their certificate, and the most important validity check for OCSP signers remains ensuring that they have been signed by (one of) the CA root(s). + #### Parsing OCSP response OCSP response can be parsed using function `parseOCSPResponse()`. Parsing does not validate the response for correctness, but translates the response to internal form (`mOCSPResponse_t`), which allows easier working with the response. + #### Checking time-stamps The times in OCSP response are validated with `checkOCSPResponseDates()` function. The function will check the times in the OCSP response with respect to the current time and provide `struct tm` field representing various times (*ProducedAt*, *thisUpdate*, *nextUpdate*) within OCSP response. If OCSP response has timed out the function will return `PS_TIMEOUT_FAIL`. @@ -1262,11 +1396,13 @@ The time validation function allows some clock skew between server and client. T If OCSP response is found to be no longer valid or there is another issue in timestamps, then the application should not accept the OCSP response or process it further. + #### Validating OCSP response The purpose of OCSP is to check if a certificate is revoked. `validateOCSPResponse_ex()` function is (finally) provided for this purpose. The function supports many different arguments. The options are used to pass in optional arguments. -``` {.c} +``` +{.c} opts.knownFlag = &known; opts.revocationFlag = &revocated; opts.nonceMatch = &nonceOk; @@ -1290,44 +1426,62 @@ In the simplest usage of this function, only the return code is checked. The *PS `opts` is used to provide options for OCSP response parsing. These options will provide more information regarding successful and unsuccessful invocation of `validateOCSPResponse_ex()`. The options are discussed below. + ##### Revocation status and reason + Flag pointed by `opts.knownFlag` will be set to *true* (1) if OCSP response contained information regarding this certificate (`subject`). Responses not containing information regarding the certificate should be dismissed. If certificate has been revoked, flag pointed by `opts.revocationFlag` will be set to *true* (1). If available, variables pointed by `opts.revocationReason` and `opts.revocationTime` and will be set to indicate the revocation reason and time respectively. In OCSP protocol, revocation reasons are indicated by numbers between 1 and 10, the same codes used by CRL. (See function `mapRevocationReason()` in `ocsp.c` for mapping the numbers to various reasons). + ##### Nonce validation For validating OCSP nonce, it is necessary to provide the OCSP request as pointer and length pair to `validateOCSPResponse_ex()` function, using `opts.request` and `opts.requestLen`. If the same nonce is found in OCSP request and response, that is considered a match and flag pointed to by `opts.nonceMatch` is set to *true* (1). Currently, OCSP nonce is not supported by many of the OCSP servers deployed in practice, and therefore, it is recommended to not rely on OCSP nonce feature to be provided by third party OCSP servers. -##6.9 MatrixSSL Statistics Framework + +## @matrixssl Statistics Framework + Implementations that wish to capture counts of SSL events can tap into the `MATRIXSSL_STATS` framework by enabling `USE_MATRIXSSL_STATS` during the compile. The mechanism is a very simple callback that can be registered to record whatever specific SSL event the user wants. The default set of events capture the following: - `CLIENT_HELLO` count (sent for clients and received for servers) + - `SERVER_HELLO` count (sent for servers and received for clients) + - Alerts sent + - Resumed handshake count + - Failed resumed handshake count + - Number of application data bytes received + - Number of application data bytes sent To add an event to the framework the user must: -1. Add a unique ID to the list of existing stats in matrixsslApi.h -2. Add the call to `matrixsslUpdateStat` in the appropriate place in the MatrixSSL library +1. Add a unique ID to the list of existing stats in matrixsslApi.h +2. Add the call to `matrixsslUpdateStat` in the appropriate place in the @matrixssl library -##6.10 Client Authentication using an External Security Token -MatrixSSL allows the TLS client to authenticate itself using an external security token. The external client authentication feature allows the client-side private key operation (i.e. the signing of the handshake_messages hash in the CertificateVerify handshake message) to be offloaded from MatrixSSL to an external module. Please consult the `External Client Authentication` section in MatrixSSL External Module Integration manual for details on how to use this feature. +## Client Authentication using an External Security Token + +@matrixssl allows the TLS client to authenticate itself using an external security token. The external client authentication feature allows the client-side private key operation (i.e. the signing of the handshake_messages hash in the CertificateVerify handshake message) to be offloaded from @matrixssl to an external module. Please consult the `External Client Authentication` section in @matrixssl External Module Integration manual for details on how to use this feature. + + +# Deprecated Features -#7 Deprecated Features The features in this section are minimally supported and should only be used in cases where they are explicitly required for compatibility. Please be aware of any security implications of these features before enabling them. -##7.1 EAP_FAST Mode -[EAP-FAST](https://tools.ietf.org/html/rfc4851) is an aging, proprietary EAP method that uses TLS to bootstrap a higher level EAP authentication method. It is supported by MatrixSSL for the client (EAP Supplicant) side only. Unlike EAP-TLS or EAP-TTLS, EAP-FAST requires modifications to the TLS protocol and therefore must be explicitly enabled with both a compile time define `USE_EAP_FAST` and a client side API `matrixSslSetSessionIdEapFast` in _matrixssllib.h_. + + +## EAP_FAST Mode + +[EAP-FAST](https://tools.ietf.org/html/rfc4851) is an aging, proprietary EAP method that uses TLS to bootstrap a higher level EAP authentication method. It is supported by @matrixssl for the client (EAP Supplicant) side only. Unlike EAP-TLS or EAP-TTLS, EAP-FAST requires modifications to the TLS protocol and therefore must be explicitly enabled with both a compile time define `USE_EAP_FAST` and a client side API `matrixSslSetSessionIdEapFast` in _matrixssllib.h_. EAP-FAST requires a _Protected Access Credential (PAC)_ to be provisioned between the peers out-of-band (see [RFC5422](https://tools.ietf.org/html/rfc5422) _Dynamic Provisioning Using Flexible Authentication via Secure Tunneling Extensible Authentication Protocol (EAP-FAST)_. Like the `TLS_PSK` cipher suites, this _PAC_ consists of a secret key (pac-key) and a unique id associated with the key, both shared between the peers. However, the `TLS_PSK` ciphers are not used for this mechanism directly. The _PAC_ is exchanged between the peers by the client sending the [Stateless Session Ticket Resumption](#61-stateless-session-ticket-resumption) specification: the `CLIENT_HELLO SessionTicket Extension`. However, a _PAC_ explicitly cannot be received by a client in the corresponding `NewSessionTicket` handshake message from the server, and must be provisioned out-of-band. Unfortunately this requires alteration of the standard TLS state machine logic. + ```C sslSessionId_t *sid; ssl_t *ssl; @@ -1343,8 +1497,10 @@ matrixSslDeleteSession(ssl); matrixSslDeleteSessionId(sid); ``` -##7.2 ZLIB Compression -The TLS specification specifies a mechanism for peers to agree on an algorithm to compress data before being encrypted. Although the feature is not widely adopted and is deprecated due to the ‘CRIME’ attack, there is limited support in MatrixSSL for zlib compression for implementations that are sensitive to throughput. + +## ZLIB Compression + +The TLS specification specifies a mechanism for peers to agree on an algorithm to compress data before being encrypted. Although the feature is not widely adopted and is deprecated due to the ‘CRIME’ attack, there is limited support in @matrixssl for zlib compression for implementations that are sensitive to throughput. To enable the feature, enable `USE_ZLIB_COMPRESSION` in _matrixssllib.h_. It will also be necessary to edit the development environment to link with a zlib library. For a standard *GCC* *POSIX* environment this should simply mean including `–lz` in the linker flags. diff --git a/makefiles/libsodium_support.mk b/makefiles/libsodium_support.mk new file mode 100644 index 0000000..2305d18 --- /dev/null +++ b/makefiles/libsodium_support.mk @@ -0,0 +1,65 @@ +## +# Optional libsodium inclusion. +# @version $Format:%h%d$ +# Copyright (c) 2017 INSIDE Secure Corporation. All Rights Reserved. +# +#------------------------------------------------------------------------------- + +# MatrixSSL supports importing some cryptographic algorithms from libsodium. +# TODO: Allow more control over libsodium unpacking process. +# Currently only control options are LIBSODIUM_CONFIGURE_ENVIRONMENT and +# LIBSODIUM_CONFIGURE_ARGUMENTS to set environment variables and configuration +# for compilation. + +THIRDPARTY_DIRECTORY=$(COMMON_MK_PATH)/thirdparty + +ifneq "$(wildcard $(THIRDPARTY_DIRECTORY)/libsodium-1.0.8.tar.gz)" "" +# Has libsodium 1.0.8. +ifeq "$(wildcard $(THIRDPARTY_DIRECTORY)/libsodium-1.0.8)" "" +ifeq (,$(filter clean clobber parse-config,$(MAKECMDGOALS))) +# libsodium is not unpacked. +$(warning automatically unpacking, configuring and compiling thirdparty/libsodium-1.0.8) +UNPACK_AND_COMPILE:=$(shell cd $(THIRDPARTY_DIRECTORY);tar zxf libsodium-1.0.8.tar.gz && cd libsodium-1.0.8 && $(LIBSODIUM_CONFIGURE_ENVIRONMENT) ./configure $(LIBSODIUM_CONFIGURE_ARGUMENTS) && make) +endif +endif +endif + +ifneq "$(wildcard $(THIRDPARTY_DIRECTORY)/libsodium-1.0.8)" "" +USE_LIBSODIUM_CRYPTO:=1 +LIBSODIUM_ROOT=$(THIRDPARTY_DIRECTORY)/libsodium-1.0.8/src/libsodium +endif + +ifneq "$(wildcard $(THIRDPARTY_DIRECTORY)/libsodium-1.0.12.tar.gz)" "" +# Has libsodium 1.0.12. +ifeq "$(wildcard $(THIRDPARTY_DIRECTORY)/libsodium-1.0.12)" "" +ifeq (,$(filter clean clobber parse-config rebuild,$(MAKECMDGOALS))) +# libsodium is not unpacked. +$(warning automatically unpacking, configuring and compiling thirdparty/libsodium-1.0.12) +UNPACK_AND_COMPILE:=$(shell cd $(THIRDPARTY_DIRECTORY);tar zxf libsodium-1.0.12.tar.gz && cd libsodium-1.0.12 && $(LIBSODIUM_CONFIGURE_ENVIRONMENT) ./configure $(LIBSODIUM_CONFIGURE_ARGUMENTS) && make) +endif +endif +endif + +ifneq "$(wildcard $(THIRDPARTY_DIRECTORY)/libsodium-1.0.12)" "" +USE_LIBSODIUM_CRYPTO:=1 +LIBSODIUM_ROOT=$(THIRDPARTY_DIRECTORY)/libsodium-1.0.12/src/libsodium +endif + +ifeq (,$(filter rebuild,$(MAKECMDGOALS))) + ifdef USE_LIBSODIUM_CRYPTO + ifdef LIBSODIUM_ROOT + # Statically link against a given libsodium + CFLAGS_LIBSODIUM=-DUSE_LIBSODIUM_CRYPTO -I$(LIBSODIUM_ROOT)/include + LDFLAGS_LIBSODIUM=$(LIBSODIUM_ROOT)/.libs/libsodium.a + STROPTS_LIBSODIUM=", USE_LIBSODIUM_CRYPTO" + STROPTS+=$(STROPTS_LIBSODIUM) + CFLAGS_MAKEFILES+=$(CFLAGS_LIBSODIUM) + LDFLAGS_MAKEFILES+=$(LDFLAGS_LIBSODIUM) + PS_LIBSODIUM:=1 + endif + ifndef LIBSODIUM_ROOT + # No library path defined regardless of USE_LIBSODIUM_CRYPTO being defined. + $(error Please define LIBSODIUM_ROOT) + endif + endif +endif diff --git a/makefiles/prepkg.mk b/makefiles/prepkg.mk new file mode 100644 index 0000000..e9c7e90 --- /dev/null +++ b/makefiles/prepkg.mk @@ -0,0 +1,59 @@ +# +# Construct header files from keys and other cryptographic properties. +# The constructed files can be built during packaging. +# +# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved. +# + +# Check if prepkg has already been done +ifneq '$(FORCE_PREPKG)' '1' +-include prepkg_done.mk +endif + +# Empty list of generated PEM headers +DATA_HEADERS = + +ifneq '$(PREPKG_DONE)' '1' + +# Add search paths for locating pem files +vpath %.pem data:$(MATRIXSSL_ROOT)/testkeys:$(MATRIXSSL_ROOT)/sampleCerts +vpath %.txt data +vpath %.bin data + +# Helper rule for building temporary working directory + +build-temp: + mkdir -p build-temp + +# Rules for constructing header files containing data + +define VERBATIM_HEADER_TEMPLATE +data/$(2).h : $(1) build-temp + cp $$< build-temp/$(2); mkdir -p data; (cd build-temp;xxd -i $(2)) >$$@ +DATA_HEADERS += data/$(2).h +endef +$(foreach key_file,$(VERBATIM_FILES),$(eval $(call VERBATIM_HEADER_TEMPLATE,$(key_file),$(subst /,_,$(key_file:%.pem=%))))) + +define PEM_HEADER_TEMPLATE +data/$(2).h : $(1) build-temp + openssl base64 -d -in $$< -out build-temp/$(2); mkdir -p data; (cd build-temp;xxd -i $(2)) >$$@ +DATA_HEADERS += data/$(2).h +endef +$(foreach key_file,$(PEM_FILES),$(eval $(call PEM_HEADER_TEMPLATE,$(key_file),$(subst /,_,$(key_file:%.pem=%))))) + +define ECC_PEM_HEADER_TEMPLATE +data/$(2).h : $(1) build-temp + openssl ec -in $$< -out build-temp/$(2) -outform DER; mkdir -p data; (cd build-temp;xxd -i $(2)) >$$@ +DATA_HEADERS += data/$(2).h +endef +$(foreach key_file,$(ECC_PEM_FILES),$(eval $(call ECC_PEM_HEADER_TEMPLATE,$(key_file),$(subst /,_,$(key_file:%.pem=%))))) + +prepkg: $(PEM_HEADERS) +clean-prepkg: clean + rm -f $(PEM_HEADERS) + rm -rf build-temp + +endif + +# Extra cleaning commands +EXTRA_CLEAN_CMDS += && rm -rf build-temp diff --git a/makefiles/rules.mk b/makefiles/rules.mk new file mode 100644 index 0000000..4da236f --- /dev/null +++ b/makefiles/rules.mk @@ -0,0 +1,38 @@ +# +# Skeleton of build file with generic rules +# +# Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved. +# + +# Generate list of generated executables (currently supports test) +TEST_EXE = $(foreach name,$(TEST_PROGRAMS),$(name)$(E)) + +# Generally, our default target is all: + +all: compile + +compile: $(OBJS) $(TEST_EXE) + +define FILELIST_AND_LINK_TEMPLATE +$(1): $(2) $$(STATICS) $(LOCAL_LDADD) + $$(CC_LD) -o $$@ $$^ $$(LDFLAGS) $(STATICS) $(LOCAL_LDADD) +OBJS += $(2) +endef + +$(foreach program,$(TEST_PROGRAMS),$(eval $(call FILELIST_AND_LINK_TEMPLATE,$(program),$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(call $(program)_SOURCES)))))) + +# Additional Dependencies for objects +$(OBJS): $(MAKEFILE_LIST) $(LOCAL_HEADERS) $(DATA_HEADERS) + +# Generic build suffix rules +%.o : %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_CFLAGS) -c -o $@ $< + +%.o : %.cc + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_CXXFLAGS) -c -o $@ $< + +# +# Clean up all generated files +# +clean: + rm -f $(TEST_EXE) $(OBJS) $(TEMP_FILES) $(EXTRA_CLEAN_CMDS) diff --git a/makefiles/testsupp.mk b/makefiles/testsupp.mk new file mode 100644 index 0000000..e8c2a2c --- /dev/null +++ b/makefiles/testsupp.mk @@ -0,0 +1,16 @@ +# +# Build test executable(s) using testsupp and catch.hpp +# +# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved. +# + +# Include test materials to path +CPPFLAGS += -I$(MATRIXSSL_ROOT)/../testsupp + +# Building with testsupp requires C++: define additional rules allowing +# compilation of C++ files inheriting options from C files compilation. +CXXFLAGS=$(CFLAGS) +OBJS += $(SRC_CC:.cc=.o) + +# Override compiler used in linking rules +CC_LD=$(CXX) diff --git a/matrixssl/cipherSuite.c b/matrixssl/cipherSuite.c index b8e378d..0842f8e 100644 --- a/matrixssl/cipherSuite.c +++ b/matrixssl/cipherSuite.c @@ -2818,6 +2818,12 @@ const sslCipherSpec_t *sslGetCipherSpec(const ssl_t *ssl, uint16_t id) #ifdef VALIDATE_KEY_MATERIAL if (ssl->keys != NULL) { + if ((ssl->flags & SSL_FLAGS_SERVER) == 0) + { + /* Client: Just accept the cipher suite, because we do not + know of server public key yet. */ + return &supportedCiphers[i]; + } if (haveKeyMaterial(ssl, supportedCiphers[i].type, 0) == PS_SUCCESS) { diff --git a/matrixssl/hsDecode.c b/matrixssl/hsDecode.c index 71a38fd..0545339 100644 --- a/matrixssl/hsDecode.c +++ b/matrixssl/hsDecode.c @@ -1599,6 +1599,15 @@ int32 parseServerHello(ssl_t *ssl, int32 hsLen, unsigned char **cp, /* See if the protocol is being downgraded */ if (ssl->reqMinVer != ssl->minVer) { + if (ssl->clientRejectVersionDowngrade) + { + ssl->err = SSL_ALERT_PROTOCOL_VERSION; + psTraceInfo("Error: version downgrade attempt by server "); + psTraceInfo(" rejected: ServerHello.server_version <"); + psTraceInfo(" ClientHello.client_version\n"); + return MATRIXSSL_ERROR; + } + if (ssl->reqMinVer == SSL3_MIN_VER && ssl->minVer >= TLS_MIN_VER) { # ifdef DISABLE_SSLV3 diff --git a/matrixssl/matrixssl.c b/matrixssl/matrixssl.c index 8551565..ed2e3e0 100644 --- a/matrixssl/matrixssl.c +++ b/matrixssl/matrixssl.c @@ -531,6 +531,97 @@ int32 matrixSslLoadEcKeys(sslKeys_t *keys, const char *certFile, # endif /* USE_ECC */ # if defined(USE_RSA) || defined(USE_ECC) +int32_t matrixSslLoadKeysMem(sslKeys_t *keys, + const unsigned char *certBuf, int32 certLen, + const unsigned char *privBuf, int32 privLen, + const unsigned char *CAbuf, int32 CAlen, + matrixSslLoadKeysOpts_t *opts) +{ + psPubKey_t tmp_privkey; + int32_t keytype = 0; + + if (opts) + keytype = opts->key_type; + + if (privBuf == NULL) + keytype = 1; + + if (privBuf != NULL && keytype == 0) + { + /* + Caller did not tell us the type of privkey to expect, so try + to find it out.*/ + memset(&tmp_privkey, 0, sizeof(psPubKey_t)); + keytype = psParseUnknownPrivKeyMem(NULL, + (unsigned char*)privBuf, privLen, + NULL, &tmp_privkey); + if (keytype < 0) + { + psTraceInfo("Could not load private key from file\n"); + return keytype; + } + psClearPubKey(&tmp_privkey); + } + + switch (keytype) + { + case 1: /* RSA */ + return matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, + privBuf, privLen, CAbuf, CAlen, PS_RSA); + break; + case 2: /* ECC */ + return matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, + privBuf, privLen, CAbuf, CAlen, PS_ECC); + break; + } + + return PS_FAILURE; +} + +int32_t matrixSslLoadKeys(sslKeys_t *keys, const char *certFile, + const char *privFile, const char *privPass, const char *CAfile, + matrixSslLoadKeysOpts_t *opts) +{ + psPubKey_t tmp_privkey; + int32_t keytype = 0; + + if (opts) + keytype = opts->key_type; + + if (privFile == NULL) + keytype = 1; + + if (keytype == 0) + { + /* + Caller did not tell us the type of privkey to expect, so try + to find it out.*/ + memset(&tmp_privkey, 0, sizeof(psPubKey_t)); + keytype = psParseUnknownPrivKey(NULL, 1, privFile, privPass, + &tmp_privkey); + if (keytype < 0) + { + psTraceInfo("Could not load private key from file\n"); + return keytype; + } + psClearPubKey(&tmp_privkey); + } + + switch (keytype) + { + case 1: /* RSA */ + return matrixSslLoadKeyMaterial(keys, certFile, privFile, privPass, + CAfile, PS_RSA); + break; + case 2: /* ECC */ + return matrixSslLoadKeyMaterial(keys, certFile, privFile, privPass, + CAfile, PS_ECC); + break; + } + + return PS_FAILURE; +} + static int32 matrixSslLoadKeyMaterial(sslKeys_t *keys, const char *certFile, const char *privFile, const char *privPass, const char *CAfile, int32 privKeyType) @@ -662,9 +753,24 @@ static int32 matrixSslLoadKeyMaterial(sslKeys_t *keys, const char *certFile, { return PS_UNSUPPORTED_FAIL; } +#ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE + flags |= CERT_ALLOW_BUNDLE_PARTIAL_PARSE; +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ err = psX509ParseCertFile(pool, (char *) CAfile, &keys->CAcerts, flags); if (err >= 0) { +#ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE + if (err == 0) + { + psTraceInfo("Failed to load any CA certs.\n"); + err = PS_PARSE_FAIL; + goto ca_load_failed; + } + else + { + psTraceIntInfo("Loaded %d CA certs\n", err); + } +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ if (keys->CAcerts->authFailFlags) { /* This should be the only no err, FailFlags case currently */ @@ -677,6 +783,11 @@ static int32 matrixSslLoadKeyMaterial(sslKeys_t *keys, const char *certFile, # endif } } + +#ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE +ca_load_failed: +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + if (err < 0) { # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH) @@ -819,6 +930,11 @@ static int32 matrixSslLoadKeyMaterialMem(sslKeys_t *keys, psPool_t *pool; int32 err, flags = 0; + if (certBuf == NULL && privBuf == NULL && CAbuf == NULL) + { + return PS_ARG_FAIL; + } + if (keys == NULL) { return PS_ARG_FAIL; @@ -933,22 +1049,46 @@ static int32 matrixSslLoadKeyMaterialMem(sslKeys_t *keys, { return PS_UNSUPPORTED_FAIL; } - if ((err = psX509ParseCert(pool, (unsigned char *) CAbuf, (uint32) CAlen, - &keys->CAcerts, flags)) < 0) +#ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE + flags |= CERT_ALLOW_BUNDLE_PARTIAL_PARSE; +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + err = psX509ParseCert(pool, (unsigned char *) CAbuf, (uint32) CAlen, + &keys->CAcerts, flags); + if (err < 0) { -# if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH) - psClearPubKey(&keys->privKey); - psX509FreeCert(keys->cert); - psX509FreeCert(keys->CAcerts); - keys->cert = keys->CAcerts = NULL; -# endif - return err; +#ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE + if (err == 0) + { + psTraceInfo("Failed to load any CA certs.\n"); + err = PS_PARSE_FAIL; + goto ca_load_failed; + } + else + { + psTraceIntInfo("Loaded %d CA certs\n", err); + } +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ } # else psTraceInfo("Ignoring CAbuf in matrixSslReadKeysMem\n"); # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */ } +#ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE +ca_load_failed: +#endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + +# if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH) + if (err < 0) + { + psClearPubKey(&keys->privKey); + psX509FreeCert(keys->cert); + psX509FreeCert(keys->CAcerts); + keys->cert = keys->CAcerts = NULL; + return err; + } +# endif + return PS_SUCCESS; } #endif /* USE_RSA || USE_ECC */ @@ -1295,6 +1435,9 @@ int32 matrixSslNewSession(ssl_t **ssl, const sslKeys_t *keys, options->validateCertsOpts.max_verify_depth; } + if (options->userDataPtr != NULL) + lssl->userDataPtr = options->userDataPtr; + #ifdef USE_ECC /* If user specified EC curves they support, let's check that against the key material they provided so there are no conflicts. Don't diff --git a/matrixssl/matrixsslApi.c b/matrixssl/matrixsslApi.c index 66956fb..dc1bab7 100644 --- a/matrixssl/matrixsslApi.c +++ b/matrixssl/matrixsslApi.c @@ -140,6 +140,11 @@ int32_t matrixSslNewClientSession(ssl_t **ssl, const sslKeys_t *keys, } lssl->userPtr = options->userPtr; + if (options->clientRejectVersionDowngrade) + { + lssl->clientRejectVersionDowngrade = 1; + } + # ifndef USE_ONLY_PSK_CIPHER_SUITE if (expectedName) { diff --git a/matrixssl/matrixsslApi.h b/matrixssl/matrixsslApi.h index 35556b1..28c672f 100644 --- a/matrixssl/matrixsslApi.h +++ b/matrixssl/matrixsslApi.h @@ -99,6 +99,20 @@ PSPUBLIC void matrixSslClose(void); */ PSPUBLIC int32 matrixSslNewKeys(sslKeys_t **keys, void *poolUserPtr); PSPUBLIC void matrixSslDeleteKeys(sslKeys_t *keys); +# if defined(USE_RSA) || defined(USE_ECC) +typedef struct { + uint32_t flags; + int32_t key_type; +} matrixSslLoadKeysOpts_t; +int32_t matrixSslLoadKeys(sslKeys_t *keys, const char *certFile, + const char *privFile, const char *privPass, const char *CAfile, + matrixSslLoadKeysOpts_t *opts); +int32_t matrixSslLoadKeysMem(sslKeys_t *keys, + const unsigned char *certBuf, int32 certLen, + const unsigned char *privBuf, int32 privLen, + const unsigned char *CAbuf, int32 CAlen, + matrixSslLoadKeysOpts_t *opts); +# endif /* USE_RSA || USE_ECC */ # ifdef USE_RSA PSPUBLIC int32 matrixSslLoadRsaKeys(sslKeys_t *keys, const char *certFile, const char *privFile, const char *privPass, diff --git a/matrixssl/matrixssllib.h b/matrixssl/matrixssllib.h index b7134ac..f98504b 100644 --- a/matrixssl/matrixssllib.h +++ b/matrixssl/matrixssllib.h @@ -955,6 +955,12 @@ typedef struct CertificateVerify externally. */ # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ int32 versionFlag; /* The SSL_FLAGS_TLS_ version (+ DTLS flag here) */ +#ifdef USE_CLIENT_SIDE_SSL + uint8_t clientRejectVersionDowngrade; /* Send SSL_ALERT_PROTOCOL_VERSION if server proposes + a lower version than what the client sent in the + ClientHello. Effectively, this ensures that only + the version in versionFlag can be negotiated. */ +#endif /* USE_CLIENT_SIDE_SSL */ void *userPtr; /* Initial value of ssl->userPtr during NewSession */ void *memAllocPtr; /* Will be passed to psOpenPool for each call related to this session */ @@ -964,6 +970,7 @@ typedef struct is deleted */ matrixValidateCertsOptions_t validateCertsOpts; /* Certificate validation options. */ + void *userDataPtr; /* Initial value of ssl->userDataPtr during NewSession. */ } sslSessOpts_t; typedef struct @@ -1343,6 +1350,9 @@ struct ssl uint8_t reqMinVer; uint8_t majVer; uint8_t minVer; +#ifdef USE_CLIENT_SIDE_SSL + uint8_t clientRejectVersionDowngrade; +#endif /* USE_CLIENT_SIDE_SSL */ uint8_t outRecType; # ifdef ENABLE_SECURE_REHANDSHAKES @@ -1483,6 +1493,7 @@ struct ssl void *memAllocPtr; /* Will be passed to psOpenPool for each call related to this session */ void *userPtr; + void *userDataPtr; }; typedef struct ssl ssl_t; diff --git a/matrixssl/version.h b/matrixssl/version.h index 8dd9b6b..202d604 100644 --- a/matrixssl/version.h +++ b/matrixssl/version.h @@ -8,10 +8,10 @@ extern "C" { #endif -#define MATRIXSSL_VERSION "3.9.1-OPEN" +#define MATRIXSSL_VERSION "3.9.3-OPEN" #define MATRIXSSL_VERSION_MAJOR 3 #define MATRIXSSL_VERSION_MINOR 9 -#define MATRIXSSL_VERSION_PATCH 1 +#define MATRIXSSL_VERSION_PATCH 3 #define MATRIXSSL_VERSION_CODE "OPEN" #ifdef __cplusplus diff --git a/release_notes-3-9-1-open.html b/release_notes-3-9-1-open.html deleted file mode 100644 index 93dfddf..0000000 --- a/release_notes-3-9-1-open.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - -

    MatrixSSL 3.9 changelog

    -

    Changes between 3.9.0 and 3.9.1

    -
      -
    • Disabled support for SHA-1 signed certificates by default. SHA-1 can no longer be considered secure for this purpose (see https://shattered.it/static/shattered.pdf). We decided to disable SHA-1 signed certificates by default to ensure that MatrixSSL customers consider the security implications before enabling them. Support for SHA-1 signed certificates can be restored by defining ENABLE_SHA1_SIGNED_CERTS in cryptoConfig.h.

    • -
    • Regenerated all test certificates. Many of the old ones had exceeded their validity period. The new test certificates have some minor changes, such as the addition of some missing basicConstraints and authorityKeyIdentifier extensions. Note that the test certificates should never be used in production, but only for initial testing during development.

    • -
    • Fixed bug that caused a segfault when ALLOW_VERSION_1_ROOT_CERT_PARSE was enabled and the peer sent a version 1 certificate. Correct behaviour is to just produce an internal certificate validation failure in this case, as the above define only allows parsing of locally stored trusted root certificates. This bug is minor as ALLOW_VERSION_1_ROOT_CERT_PARSE is disabled by default, and rarely used by MatrixSSL customers.

    • -
    • Introduced new function setSocketTlsCertAuthCb for setting certificate authentication callback when using MatrixSSL via psSocket_t interface. Previously constant function name ssl_cert_auth was used for authentication callback.

    • -
    - - diff --git a/release_notes-3-9-3-open.html b/release_notes-3-9-3-open.html new file mode 100644 index 0000000..9ab7dfe --- /dev/null +++ b/release_notes-3-9-3-open.html @@ -0,0 +1,49 @@ + + + + + + + + + + +

    MatrixSSL 3.9 changelog

    +

    Changes between 3.9.2 and 3.9.3 [June 2017]

    +

    Fix serious buffer handling vulnerabilities along with other smaller bug fixes.

    +
      +
    • Fixed buffer overflow vulnerability in parsePolicyMappings and buffer underflow in parseGeneralNames. Vulnerabilities discovered by Aleksandar Nikolic of Cisco Talos.

    • +
    • psX509ParseCert modified not to call parse_single_cert when there are only a few bytes remaining.

    • +
    • Fix compilation when USE_PKCS8 is not defined.

    • +
    • Added common makefiles directory for reusable makefile components.

    • +
    • Added new result code PS_SELFTEST_FAILED for detecting psCryptoOpen() failure due to self-test failure of underlying cryptographic primitivers.

    • +
    • Debugging build log output can be redirected to a file using PSCORE_DEBUG_FILE/PSCORE_DEBUG_FILE_APPEND/FLPS_DEBUG_FILE/ FLPS_DEBUG_FILE_APPEND environment variables.

    • +
    • New example configuration for use of libopenssl-compat. This configuration enables TLS 1.0, which is common to use with libopenssl-compat.

    • +
    • Add client side option for rejecting version downgrade during TLS handshake.

    • +
    • ECDSA cipher suites were errorneously rejected by client using CAs with only RSA certificates.

    • +
    • Small improvements to psBuf and psDynBuf functions.

    • +
    • CMS library improvements, support for multiple recipients with authenticated encrypted data.

    • +
    • CMS library improvements, support for zero or multiple signers for signed data.

    • +
    • Signed data can now contain X.509 CRLs.

    • +
    • Fixed handling of OCSP responses using OCSP responderName.

    • +
    • Fixed memory leak in freeing of OCSP requestor id.

    • +
    • MatrixSSL client sometimes prevented ECDSA cipher suites from being used due to flaw in key material compatibility test. The test has been removed.

    • +
    +

    Changes between 3.9.1 and 3.9.2

    +

    3.9.2. only released as a part of SafeZone FIPS SW SDK.

    +
      +
    • Added support for OCSP response with SHA-512 signature.

    • +
    • psPkcs8ParsePrivBin() function now supports any SafeZone CL library supported PKCS #8 key formats, in addition to PKCS #8 keys ordinarily supported by MatrixSSL. (Only applicable to MatrixSSL FIPS Edition.)

    • +
    • Added matrixSslLoadKeys and matrixSslLoadKeysMem. This key loading function can be used in situations where the type of private key (RSA or EC) to load is unknown.

    • +
    • Added support for loading CA bundles containing both supported and unsupported certificates. Previously, the loading of a CA bundle failed if any of the certificates could not be fully parsed by MatrixSSL, due to e.g. disabled v1 certificate support. The new feature can be enabled by defining ALLOW_CA_BUNDLE_PARTIAL_PARSE in matrixsslConfig.h. Also the crypto-level psX509ParseCert and psX509ParseCertFile functions support the same feature when passed the CERT_ALLOW_BUNDLE_PARTIAL_PARSE flag.

    • +
    • Added support for RSA-SHA224 and ECDSA-SHA224 signatures in CSR generation, CSR parsing and certificate generation. Expanded X.509 Generation API test.

    • +
    +

    Changes between 3.9.0 and 3.9.1

    +
      +
    • Disabled support for SHA-1 signed certificates by default. SHA-1 can no longer be considered secure for this purpose (see https://shattered.it/static/shattered.pdf). We decided to disable SHA-1 signed certificates by default to ensure that MatrixSSL customers consider the security implications before enabling them. Support for SHA-1 signed certificates can be restored by defining ENABLE_SHA1_SIGNED_CERTS in cryptoConfig.h.

    • +
    • Regenerated all test certificates. Many of the old ones had exceeded their validity period. The new test certificates have some minor changes, such as the addition of some missing basicConstraints and authorityKeyIdentifier extensions. Note that the test certificates should never be used in production, but only for initial testing during development.

    • +
    • Fixed bug that caused a segfault when ALLOW_VERSION_1_ROOT_CERT_PARSE was enabled and the peer sent a version 1 certificate. Correct behaviour is to just produce an internal certificate validation failure in this case, as the above define only allows parsing of locally stored trusted root certificates. This bug is minor as ALLOW_VERSION_1_ROOT_CERT_PARSE is disabled by default, and rarely used by MatrixSSL customers.

    • +
    • Introduced new function setSocketTlsCertAuthCb for setting certificate authentication callback when using MatrixSSL via psSocket_t interface. Previously constant function name ssl_cert_auth was used for authentication callback.

    • +
    + + diff --git a/testkeys/DSA/DSA_KEY_1024_160.pem b/testkeys/DSA/DSA_KEY_1024_160.pem new file mode 100644 index 0000000..5617303 --- /dev/null +++ b/testkeys/DSA/DSA_KEY_1024_160.pem @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBvAIBAAKBgQDyiNlP6JTzl+dt7+cH0917sSSamKXA4ySFpym38GCIA9mrYahH +19YVFQz3F1G5lViCvKmcwxUaJu5sm7ltmucj+skDRzksyP6a7OOi0ijO+am4B9eM +OulKSZ7lrWKOKLpUlz2cr56DWkg2DVSQzDfN/UuJ7ukMY4NkC8tIWwJRcwIVAMrr +1HDSoqitgRvVFhVfuH4+qzsxAoGAMnYoRyaLhpqwhB9hePDdpYMlMc2D0ptYCoX/ +wTY+ptb7hX8w0qSvKQIHLnpBGK2TWdThWU1I5IGtEqA6tUuG2oEVnMNbF+SMyw79 +m8s2Tg7eESQpe+9WhGcpEgJf6KEZdhSgJ166a+V6NUcfRITkTSWUTHQVrhV+Dewg +oe+vhLkCgYEAyJz4qErFt6QVTVySsAraH4bRXezqdpoVf06/yvTqVAEuoO8bYP6n +j6oIgUS8D3gBIJ/R4ggVfscNQrLqo4y+AQc6FO/a7JonKLf91X2aFPkhl5THTzvV +i+PjCZsIUV9R0v+BAy+uNZ8jFhRxWPXZgCiXxx1qyila/xJPcIQ4LCQCFQCderMQ +7Ms3n03ekrRaXqjBdSw+yg== +-----END DSA PRIVATE KEY----- diff --git a/testkeys/DSA/DSA_KEY_2048_160.pem b/testkeys/DSA/DSA_KEY_2048_160.pem new file mode 100644 index 0000000..a36ddaf --- /dev/null +++ b/testkeys/DSA/DSA_KEY_2048_160.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDPQIBAAKCAQEAkhyi667AqE8KwUP+kYd4qdqYDPnsfx4ybByOUV7gM8x9bA1o +l1yZcJqCTO+4tIqYSyj5citSlLYg1b0+CWlRdzz0/ZVI5qtuBXPvmK2H6Ue3xb04 +qU23XtFy/X/Uz0FSAWtzS7szSVXYGnlcjtcqoA90bZm7t46Lc/5JQlxkiGY5yJrk +SHiFAL0DMg2yx+UH7Nu6EA0SPa4zeWCcRFpfRqnUo+V1YY5H/Hjii3ZHKrSenX4A +SkWggaB1bMMokdYzyzMwzhPM/d1e3Cuh5zXH+wTcubpq67tupbV1Ne+dLJJqZC4w +VDyiCjshLdf2oKqC9o63pOGGzeUKbeCq9O0wCQIVAMJ5dHVPS9lrSdIFGgBZ2bqA +0O0nAoIBAC5ka+oHDQUphpYdc/2qnIrqgK6rK/b8Zxdnbc9kiu84sqBbsVdUqZQr +deBN1qUgJIx3Z4TcJOdmkFnmFuPpnTMebdPf4CcuK+JgMgguICoejRB/9bjVyiVB +/aAMxjjI0A0AV2sfTf3SETKu9YITQ4DdnST1y3OV41w7AkcE1F5nEXGOb+GdyBgb +9ytkvAGaT1Haxaym7OFjuSmMZm6AI3cYGb+pPjOgah8iLxFMTBuAG4bfo8e6GBrm +n9RXcDvjpNJY1uFezKdtZSECG7RI91MmFP4pGYrk1nnzNpy4yjQFvZ/eccoBO8Cs +Gxxrzj1SkpoVhac2cZs+CHTTpBbYlLoCggEAMf+hzPHAp3LFsYdliUsde1wVyy8D +XA0ArR6uPdOrFo8E1CCRdwVe/Ktbz1NoVV7AfygKyp9dZFHM09Tg5SQ+fJSoe3+C +tSdj3zThoYAsUWjd4/XcibE8iw2GV61aSCBUwtAdio4m/Aw2SXgMC0j5DxKdYoFT +nBHAKtuMXs12ORZ8DgvajhyFEM093nQ3HXJXO1TxoHHckrPPtUL1Lbf1HWzPKooC +BivgAWAoWDv1Kxyth0PaBnlK8uP2r4lGdO4FHPSX8f87+hY6QnWE/VbUr8t7JTsT +wAK7pyYsDWSNKC4GKPlEPhfBKUXtk6jLneHEs51qAVN1ALC7J92oQd91ewIULJuu +DyHKDUf15sCpo9qleNqxZ90= +-----END DSA PRIVATE KEY----- diff --git a/testkeys/DSA/DSA_KEY_2048_224.pem b/testkeys/DSA/DSA_KEY_2048_224.pem new file mode 100644 index 0000000..0fbfd38 --- /dev/null +++ b/testkeys/DSA/DSA_KEY_2048_224.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDTgIBAAKCAQEArRB+HpEjqdDWYPqnlVnFH6INZOVoO5/RtUsVl7YdCnXm+hQd ++VpW26+aPEB7od8V6z1oijCcGA4d5rhaEnSgpm0/gVKtasISkDfJ7e/aTfjZHo/v +Vbc5S3rVt9C2wSIHyfmNEe002/bGugssi7wnvmoA4KC5xJcIs7+KMXCRiDaBKGEw +vImF2xYC5xRBXZMwJ4Jzx94x79xzEPcSH9WgdBWYfZrcCkhtzfk6zEQyg4cxXXXh +mMZBpIDNhqG55YfovmDmnMkosrnFIXLkEwQumyPxCw4W55djybU9z0uoCinj+3PB +a451uX7zY+L/ox9xz53lOE5xuBwKxN/+DBDmTwIdAIAcDTTFjZP+mXF3EB+AU1pH +OM68vziambNjcesCggEBAKxAMu9PLZrjnfMLXI/9rFBs3r57iZmMr3SGagjP5P/j +poJKThC5pvDdkh8BpwxK+qtznXcAwp9SxX2xfGIKhlK+XpABqNZq18F2aRAZmQJK +9NAnJ1rBNIu4p2LQUhvJiuJHFQQi6h7UCZOdVNp0YM219sayUHF8vvGA6zQRjpjR +GVKaRdb4NFZuMCXjFqMw77t3qG8MGrFbBRrj1CjI+Ky3CoE3FQuO6xDhg+3RmWPd +2eJj5HcFie9qoh5/Xy/zgbU5zONAnRPNVmr7tI1sAZGB4bz+lLMCae3+cv6baqS9 +e1oPHHHP/0wZxBjh9uwBeYG8CH8qcGWzhLiQ0xkfK/oCggEABlZmAaDnaS4v+8eS +gfjFVzlqU6nExvsdLxx9/TWwr4CS88s92c+9tRTIGRvUUgEu2OvZYiFntGyvN0Qo +kdIUwnd2BB/ZqLyGTCm4FHxYf/mKHbNFgS209Mosi3Y2OG7MDqiHCg/D0/RPucmC +WQomj4pp+lsJPJxz7zSb4rSdGDSQV7RolcYbuoTwM1L0ZV/jbGnsX/ujmswm8k8L +dNqfsgHnRGPz60Qif+TZ8+sXVd/lfU4inPdjAupOPHePFEgDPUSx87VLsbzvoPC0 +PpheSVoa5XYY2uDRJCV0TJhSFHg5e4zebHj4ZbyGr59PFUinODQBb5nwYlrCkZpO +GI4jvwIcMhO61uKmtxGNWLeyXA0XnCx4ehl78Q4rEL2B1g== +-----END DSA PRIVATE KEY----- diff --git a/testkeys/DSA/DSA_KEY_2048_256.der b/testkeys/DSA/DSA_KEY_2048_256.der new file mode 100644 index 0000000..b51e3fe Binary files /dev/null and b/testkeys/DSA/DSA_KEY_2048_256.der differ diff --git a/testkeys/DSA/DSA_KEY_2048_256.p8 b/testkeys/DSA/DSA_KEY_2048_256.p8 new file mode 100644 index 0000000..49f4151 Binary files /dev/null and b/testkeys/DSA/DSA_KEY_2048_256.p8 differ diff --git a/testkeys/DSA/DSA_KEY_2048_256.pem b/testkeys/DSA/DSA_KEY_2048_256.pem new file mode 100644 index 0000000..78644f5 --- /dev/null +++ b/testkeys/DSA/DSA_KEY_2048_256.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDVQIBAAKCAQEAh6jmHbS2Zjz/u9GcZRlZmYzu9ghmDdDyXSzu1ENeOwDgDfjx +1hlX1Pr330VhsqowFsPZETQJb6o79Cltgw6afCCeDGSXUXq9WoqdMGvPZ+2R+eZy +W0dYwCLgse9Cdb97bFv8EdRfkIi5QfVOseWbuLw5oL8SMH9cT9twxYGyP3a2Osrh +yqa3kC1SUmc1SIoO8TxtmlG/pKs62DR3llJNjvahZ7WkGCXZZ+FE5RQFZCUcysuD +5rSG9rPKP3lxUGAmwLhX9omWKFbe1AEKvQvmIcOjlgpU5xDDdfJjddcBQQOktUMw +wZivEmEW0iduEXFfaTh3+tfvCcrbCUrpHhoVlwIhAIz4NkKnCaCXtEeZdkASnaKZ +saR9HrN1C6MIsP5k9fvTAoIBAD+zLJtzE00LLndQZmDtvUhMp7GPIe8gVAf0eToa +C6ElENvBUHe+Rj//T+1KrAu1Vb46bBsMa0exvDdzv36Mb2KQEij4woy7GKVa4xNB +AAplAZb5Mcd6V/Ld9GPl6ewUS3d95iqquKhiisN20oLW7Thk5nmCQo68gx0UNI9v +L5GTtQRa8nZxZOHfyWfB+z8uVaS9G//oO5yA0FK5hdGC6grbKjtzE9P+FMhISx4F +JYi5t9K70t8BYZns0G4VV80JFbM1O7tk4Ow3f9AoNw35K1LHiRQozcZ+thhLUj0d +skbDL2MHhJDwDvjWR9FI1HlUUV4jJ8/vmMWCZktMD2zEFlkCggEAHoh9b9HKle+G +syyPk3+GktXx6GsT3hJDk3p56Ih53r1bRRy44HQJj4ShSGROSev12lwADgtUBZLY +9r9BBF29u1v/xOytdOu0ctXPEUwvJbrmRXxOpmjUa8cfVjfdnSXTYIblelDnuxPS +EbUtXKOUDD9eEzjVfUI7+KSWyQqAX7snHfvoImc9B92kAu23OCgrXLkXA64+4mpo +oXqDDsOBQP1UTaLCOWuSsvPQDCV6RvmH2+978odiFsD5re0v8whaczKkiiDi/O0K +Fv94LZ6qQjSDTJAYJVJGaybL3slMa0HR2/GvvqW81fqTyBHe5WbIjpkEoe0K69Tz +vwcMP+R43QIgAkXLMP9mEqLX2iybwursAnm/taa8zTEM62TvXU2lOWw= +-----END DSA PRIVATE KEY----- diff --git a/testkeys/DSA/DSA_PARAMETERS_1024_160.pem b/testkeys/DSA/DSA_PARAMETERS_1024_160.pem new file mode 100644 index 0000000..b2fed3c --- /dev/null +++ b/testkeys/DSA/DSA_PARAMETERS_1024_160.pem @@ -0,0 +1,9 @@ +-----BEGIN DSA PARAMETERS----- +MIIBHgKBgQDyiNlP6JTzl+dt7+cH0917sSSamKXA4ySFpym38GCIA9mrYahH19YV +FQz3F1G5lViCvKmcwxUaJu5sm7ltmucj+skDRzksyP6a7OOi0ijO+am4B9eMOulK +SZ7lrWKOKLpUlz2cr56DWkg2DVSQzDfN/UuJ7ukMY4NkC8tIWwJRcwIVAMrr1HDS +oqitgRvVFhVfuH4+qzsxAoGAMnYoRyaLhpqwhB9hePDdpYMlMc2D0ptYCoX/wTY+ +ptb7hX8w0qSvKQIHLnpBGK2TWdThWU1I5IGtEqA6tUuG2oEVnMNbF+SMyw79m8s2 +Tg7eESQpe+9WhGcpEgJf6KEZdhSgJ166a+V6NUcfRITkTSWUTHQVrhV+Dewgoe+v +hLk= +-----END DSA PARAMETERS----- diff --git a/testkeys/DSA/DSA_PARAMETERS_2048_160.pem b/testkeys/DSA/DSA_PARAMETERS_2048_160.pem new file mode 100644 index 0000000..03ed593 --- /dev/null +++ b/testkeys/DSA/DSA_PARAMETERS_2048_160.pem @@ -0,0 +1,14 @@ +-----BEGIN DSA PARAMETERS----- +MIICIAKCAQEAkhyi667AqE8KwUP+kYd4qdqYDPnsfx4ybByOUV7gM8x9bA1ol1yZ +cJqCTO+4tIqYSyj5citSlLYg1b0+CWlRdzz0/ZVI5qtuBXPvmK2H6Ue3xb04qU23 +XtFy/X/Uz0FSAWtzS7szSVXYGnlcjtcqoA90bZm7t46Lc/5JQlxkiGY5yJrkSHiF +AL0DMg2yx+UH7Nu6EA0SPa4zeWCcRFpfRqnUo+V1YY5H/Hjii3ZHKrSenX4ASkWg +gaB1bMMokdYzyzMwzhPM/d1e3Cuh5zXH+wTcubpq67tupbV1Ne+dLJJqZC4wVDyi +CjshLdf2oKqC9o63pOGGzeUKbeCq9O0wCQIVAMJ5dHVPS9lrSdIFGgBZ2bqA0O0n +AoIBAC5ka+oHDQUphpYdc/2qnIrqgK6rK/b8Zxdnbc9kiu84sqBbsVdUqZQrdeBN +1qUgJIx3Z4TcJOdmkFnmFuPpnTMebdPf4CcuK+JgMgguICoejRB/9bjVyiVB/aAM +xjjI0A0AV2sfTf3SETKu9YITQ4DdnST1y3OV41w7AkcE1F5nEXGOb+GdyBgb9ytk +vAGaT1Haxaym7OFjuSmMZm6AI3cYGb+pPjOgah8iLxFMTBuAG4bfo8e6GBrmn9RX +cDvjpNJY1uFezKdtZSECG7RI91MmFP4pGYrk1nnzNpy4yjQFvZ/eccoBO8CsGxxr +zj1SkpoVhac2cZs+CHTTpBbYlLo= +-----END DSA PARAMETERS----- diff --git a/testkeys/DSA/DSA_PUB_1024_160.pem b/testkeys/DSA/DSA_PUB_1024_160.pem new file mode 100644 index 0000000..0c93cf6 --- /dev/null +++ b/testkeys/DSA/DSA_PUB_1024_160.pem @@ -0,0 +1,12 @@ +-----BEGIN PUBLIC KEY----- +MIIBtzCCASsGByqGSM44BAEwggEeAoGBAPKI2U/olPOX523v5wfT3XuxJJqYpcDj +JIWnKbfwYIgD2athqEfX1hUVDPcXUbmVWIK8qZzDFRom7mybuW2a5yP6yQNHOSzI +/prs46LSKM75qbgH14w66UpJnuWtYo4oulSXPZyvnoNaSDYNVJDMN839S4nu6Qxj +g2QLy0hbAlFzAhUAyuvUcNKiqK2BG9UWFV+4fj6rOzECgYAydihHJouGmrCEH2F4 +8N2lgyUxzYPSm1gKhf/BNj6m1vuFfzDSpK8pAgcuekEYrZNZ1OFZTUjkga0SoDq1 +S4bagRWcw1sX5IzLDv2byzZODt4RJCl771aEZykSAl/ooRl2FKAnXrpr5Xo1Rx9E +hORNJZRMdBWuFX4N7CCh76+EuQOBhQACgYEAyJz4qErFt6QVTVySsAraH4bRXezq +dpoVf06/yvTqVAEuoO8bYP6nj6oIgUS8D3gBIJ/R4ggVfscNQrLqo4y+AQc6FO/a +7JonKLf91X2aFPkhl5THTzvVi+PjCZsIUV9R0v+BAy+uNZ8jFhRxWPXZgCiXxx1q +yila/xJPcIQ4LCQ= +-----END PUBLIC KEY----- diff --git a/testkeys/DSA/DSA_PUB_2048_160.pem b/testkeys/DSA/DSA_PUB_2048_160.pem new file mode 100644 index 0000000..c0eec43 --- /dev/null +++ b/testkeys/DSA/DSA_PUB_2048_160.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQCSHKLrrsCoTwrBQ/6Rh3ip2pgM+ex/ +HjJsHI5RXuAzzH1sDWiXXJlwmoJM77i0iphLKPlyK1KUtiDVvT4JaVF3PPT9lUjm +q24Fc++YrYfpR7fFvTipTbde0XL9f9TPQVIBa3NLuzNJVdgaeVyO1yqgD3Rtmbu3 +jotz/klCXGSIZjnImuRIeIUAvQMyDbLH5Qfs27oQDRI9rjN5YJxEWl9GqdSj5XVh +jkf8eOKLdkcqtJ6dfgBKRaCBoHVswyiR1jPLMzDOE8z93V7cK6HnNcf7BNy5umrr +u26ltXU1750skmpkLjBUPKIKOyEt1/agqoL2jrek4YbN5Qpt4Kr07TAJAhUAwnl0 +dU9L2WtJ0gUaAFnZuoDQ7ScCggEALmRr6gcNBSmGlh1z/aqciuqArqsr9vxnF2dt +z2SK7ziyoFuxV1SplCt14E3WpSAkjHdnhNwk52aQWeYW4+mdMx5t09/gJy4r4mAy +CC4gKh6NEH/1uNXKJUH9oAzGOMjQDQBXax9N/dIRMq71ghNDgN2dJPXLc5XjXDsC +RwTUXmcRcY5v4Z3IGBv3K2S8AZpPUdrFrKbs4WO5KYxmboAjdxgZv6k+M6BqHyIv +EUxMG4Abht+jx7oYGuaf1FdwO+Ok0ljW4V7Mp21lIQIbtEj3UyYU/ikZiuTWefM2 +nLjKNAW9n95xygE7wKwbHGvOPVKSmhWFpzZxmz4IdNOkFtiUugOCAQUAAoIBADH/ +oczxwKdyxbGHZYlLHXtcFcsvA1wNAK0erj3TqxaPBNQgkXcFXvyrW89TaFVewH8o +CsqfXWRRzNPU4OUkPnyUqHt/grUnY9804aGALFFo3eP13ImxPIsNhletWkggVMLQ +HYqOJvwMNkl4DAtI+Q8SnWKBU5wRwCrbjF7NdjkWfA4L2o4chRDNPd50Nx1yVztU +8aBx3JKzz7VC9S239R1szyqKAgYr4AFgKFg79SscrYdD2gZ5SvLj9q+JRnTuBRz0 +l/H/O/oWOkJ1hP1W1K/LeyU7E8ACu6cmLA1kjSguBij5RD4XwSlF7ZOoy53hxLOd +agFTdQCwuyfdqEHfdXs= +-----END PUBLIC KEY----- diff --git a/testkeys/DSA/DSA_PUB_2048_224.pem b/testkeys/DSA/DSA_PUB_2048_224.pem new file mode 100644 index 0000000..a6478d1 --- /dev/null +++ b/testkeys/DSA/DSA_PUB_2048_224.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDQzCCAjYGByqGSM44BAEwggIpAoIBAQCtEH4ekSOp0NZg+qeVWcUfog1k5Wg7 +n9G1SxWXth0Kdeb6FB35Wlbbr5o8QHuh3xXrPWiKMJwYDh3muFoSdKCmbT+BUq1q +whKQN8nt79pN+Nkej+9VtzlLetW30LbBIgfJ+Y0R7TTb9sa6CyyLvCe+agDgoLnE +lwizv4oxcJGINoEoYTC8iYXbFgLnFEFdkzAngnPH3jHv3HMQ9xIf1aB0FZh9mtwK +SG3N+TrMRDKDhzFddeGYxkGkgM2Gobnlh+i+YOacySiyucUhcuQTBC6bI/ELDhbn +l2PJtT3PS6gKKeP7c8FrjnW5fvNj4v+jH3HPneU4TnG4HArE3/4MEOZPAh0AgBwN +NMWNk/6ZcXcQH4BTWkc4zry/OJqZs2Nx6wKCAQEArEAy708tmuOd8wtcj/2sUGze +vnuJmYyvdIZqCM/k/+OmgkpOELmm8N2SHwGnDEr6q3OddwDCn1LFfbF8YgqGUr5e +kAGo1mrXwXZpEBmZAkr00CcnWsE0i7inYtBSG8mK4kcVBCLqHtQJk51U2nRgzbX2 +xrJQcXy+8YDrNBGOmNEZUppF1vg0Vm4wJeMWozDvu3eobwwasVsFGuPUKMj4rLcK +gTcVC47rEOGD7dGZY93Z4mPkdwWJ72qiHn9fL/OBtTnM40CdE81Wavu0jWwBkYHh +vP6UswJp7f5y/ptqpL17Wg8ccc//TBnEGOH27AF5gbwIfypwZbOEuJDTGR8r+gOC +AQUAAoIBAAZWZgGg52kuL/vHkoH4xVc5alOpxMb7HS8cff01sK+AkvPLPdnPvbUU +yBkb1FIBLtjr2WIhZ7RsrzdEKJHSFMJ3dgQf2ai8hkwpuBR8WH/5ih2zRYEttPTK +LIt2NjhuzA6ohwoPw9P0T7nJglkKJo+KafpbCTycc+80m+K0nRg0kFe0aJXGG7qE +8DNS9GVf42xp7F/7o5rMJvJPC3Tan7IB50Rj8+tEIn/k2fPrF1Xf5X1OIpz3YwLq +Tjx3jxRIAz1EsfO1S7G876DwtD6YXklaGuV2GNrg0SQldEyYUhR4OXuM3mx4+GW8 +hq+fTxVIpzg0AW+Z8GJawpGaThiOI78= +-----END PUBLIC KEY----- diff --git a/testkeys/DSA/DSA_PUB_2048_256.pem b/testkeys/DSA/DSA_PUB_2048_256.pem new file mode 100644 index 0000000..219d2b1 --- /dev/null +++ b/testkeys/DSA/DSA_PUB_2048_256.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDRjCCAjkGByqGSM44BAEwggIsAoIBAQCHqOYdtLZmPP+70ZxlGVmZjO72CGYN +0PJdLO7UQ147AOAN+PHWGVfU+vffRWGyqjAWw9kRNAlvqjv0KW2DDpp8IJ4MZJdR +er1aip0wa89n7ZH55nJbR1jAIuCx70J1v3tsW/wR1F+QiLlB9U6x5Zu4vDmgvxIw +f1xP23DFgbI/drY6yuHKpreQLVJSZzVIig7xPG2aUb+kqzrYNHeWUk2O9qFntaQY +Jdln4UTlFAVkJRzKy4PmtIb2s8o/eXFQYCbAuFf2iZYoVt7UAQq9C+Yhw6OWClTn +EMN18mN11wFBA6S1QzDBmK8SYRbSJ24RcV9pOHf61+8JytsJSukeGhWXAiEAjPg2 +QqcJoJe0R5l2QBKdopmxpH0es3ULowiw/mT1+9MCggEAP7Msm3MTTQsud1BmYO29 +SEynsY8h7yBUB/R5OhoLoSUQ28FQd75GP/9P7UqsC7VVvjpsGwxrR7G8N3O/foxv +YpASKPjCjLsYpVrjE0EACmUBlvkxx3pX8t30Y+Xp7BRLd33mKqq4qGKKw3bSgtbt +OGTmeYJCjryDHRQ0j28vkZO1BFrydnFk4d/JZ8H7Py5VpL0b/+g7nIDQUrmF0YLq +CtsqO3MT0/4UyEhLHgUliLm30rvS3wFhmezQbhVXzQkVszU7u2Tg7Dd/0Cg3Dfkr +UseJFCjNxn62GEtSPR2yRsMvYweEkPAO+NZH0UjUeVRRXiMnz++YxYJmS0wPbMQW +WQOCAQUAAoIBAB6IfW/RypXvhrMsj5N/hpLV8ehrE94SQ5N6eeiIed69W0UcuOB0 +CY+EoUhkTknr9dpcAA4LVAWS2Pa/QQRdvbtb/8TsrXTrtHLVzxFMLyW65kV8TqZo +1GvHH1Y33Z0l02CG5XpQ57sT0hG1LVyjlAw/XhM41X1CO/iklskKgF+7Jx376CJn +PQfdpALttzgoK1y5FwOuPuJqaKF6gw7DgUD9VE2iwjlrkrLz0Awlekb5h9vve/KH +YhbA+a3tL/MIWnMypIog4vztChb/eC2eqkI0g0yQGCVSRmsmy97JTGtB0dvxr76l +vNX6k8gR3uVmyI6ZBKHtCuvU878HDD/keN0= +-----END PUBLIC KEY----- diff --git a/testkeys/DSA/DSA_SIGN_abc_1024_160.h b/testkeys/DSA/DSA_SIGN_abc_1024_160.h new file mode 100644 index 0000000..ae48885 --- /dev/null +++ b/testkeys/DSA/DSA_SIGN_abc_1024_160.h @@ -0,0 +1,7 @@ +unsigned char DSA_SIGN_abc_1024_160[] = { + 0x30, 0x2d, 0x02, 0x14, 0x4b, 0x63, 0xd3, 0xdf, 0x88, 0x78, 0x48, 0x86, + 0xfc, 0x36, 0xa8, 0x0c, 0xf4, 0xed, 0x68, 0xaa, 0xe2, 0x16, 0xc8, 0x37, + 0x02, 0x15, 0x00, 0x88, 0x65, 0xbf, 0xf0, 0x9f, 0x64, 0x42, 0x28, 0xc9, + 0xca, 0x54, 0x08, 0xba, 0x52, 0x3a, 0xee, 0xf6, 0xad, 0x19, 0xea +}; +unsigned int DSA_SIGN_abc_1024_160_len = 47; diff --git a/testkeys/DSA/DSA_SIGN_abc_2048_160.h b/testkeys/DSA/DSA_SIGN_abc_2048_160.h new file mode 100644 index 0000000..65641c1 --- /dev/null +++ b/testkeys/DSA/DSA_SIGN_abc_2048_160.h @@ -0,0 +1,7 @@ +unsigned char DSA_SIGN_abc_2048_160[] = { + 0x30, 0x2e, 0x02, 0x15, 0x00, 0xa6, 0xe5, 0x90, 0x7d, 0xe5, 0xf7, 0xc0, + 0xb7, 0x21, 0xc7, 0x26, 0x2d, 0xae, 0x8e, 0x50, 0xf3, 0x12, 0x49, 0x32, + 0xa4, 0x02, 0x15, 0x00, 0xae, 0x68, 0x00, 0x7a, 0xa0, 0x83, 0x22, 0x5f, + 0x48, 0x66, 0xe5, 0x6e, 0xcf, 0x3e, 0x14, 0x6f, 0x17, 0x23, 0x13, 0xcd +}; +unsigned int DSA_SIGN_abc_2048_160_len = 48; diff --git a/testkeys/DSA/DSA_SIGN_abc_2048_224.h b/testkeys/DSA/DSA_SIGN_abc_2048_224.h new file mode 100644 index 0000000..ea0fefb --- /dev/null +++ b/testkeys/DSA/DSA_SIGN_abc_2048_224.h @@ -0,0 +1,9 @@ +unsigned char DSA_SIGN_abc_2048_224[] = { + 0x30, 0x3c, 0x02, 0x1c, 0x0c, 0x56, 0x81, 0x4c, 0x00, 0xce, 0x92, 0xee, + 0xe4, 0x53, 0xd1, 0x1a, 0xc5, 0x8e, 0xdc, 0x1d, 0x2b, 0x99, 0x8c, 0xda, + 0xc0, 0x2f, 0x1f, 0xb2, 0x0e, 0xd6, 0xd0, 0x9d, 0x02, 0x1c, 0x2c, 0x1b, + 0x24, 0x9a, 0xe0, 0x52, 0x90, 0x8e, 0x7a, 0x13, 0x85, 0x5a, 0x3f, 0x2e, + 0x8a, 0x3a, 0xee, 0x49, 0x56, 0x52, 0xd6, 0x01, 0xe3, 0xb1, 0x66, 0x0e, + 0x15, 0x77 +}; +unsigned int DSA_SIGN_abc_2048_224_len = 62; diff --git a/testkeys/DSA/DSA_SIGN_abc_2048_256.h b/testkeys/DSA/DSA_SIGN_abc_2048_256.h new file mode 100644 index 0000000..5401646 --- /dev/null +++ b/testkeys/DSA/DSA_SIGN_abc_2048_256.h @@ -0,0 +1,9 @@ +unsigned char DSA_SIGN_abc_2048_256[] = { + 0x30, 0x44, 0x02, 0x20, 0x38, 0x36, 0x1e, 0x1f, 0x7e, 0xa7, 0x99, 0x50, + 0x75, 0x77, 0xd9, 0x0f, 0x2a, 0x2a, 0x88, 0xd0, 0x07, 0x4b, 0x37, 0x58, + 0xb8, 0x4e, 0xc3, 0xb6, 0x7b, 0xf4, 0xf6, 0x54, 0xfb, 0x68, 0xfa, 0xe5, + 0x02, 0x20, 0x0f, 0x44, 0xe0, 0x22, 0x34, 0x4c, 0x6d, 0xcc, 0x43, 0xfd, + 0x11, 0xb5, 0x0f, 0x67, 0xb5, 0x6d, 0x80, 0xfb, 0xa8, 0x30, 0x37, 0x7a, + 0xe8, 0xd9, 0x39, 0xd5, 0xc0, 0x06, 0x14, 0xb1, 0x1f, 0x59 +}; +unsigned int DSA_SIGN_abc_2048_256_len = 70; diff --git a/testkeys/RSA/2048_RSA_KEY.p8 b/testkeys/RSA/2048_RSA_KEY.p8 new file mode 100644 index 0000000..9efed98 Binary files /dev/null and b/testkeys/RSA/2048_RSA_KEY.p8 differ diff --git a/thirdparty/README b/thirdparty/README new file mode 100644 index 0000000..8be2f4c --- /dev/null +++ b/thirdparty/README @@ -0,0 +1,5 @@ +This directory is for additional third party software which MatrixSSL may use. + +The packages which may be in this directory can be found from: + * https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.8.tar.gz + * https://download.libsodium.org/libsodium/releases/libsodium-1.0.12.tar.gz diff --git a/xcode/client.xcodeproj/project.pbxproj b/xcode/client.xcodeproj/project.pbxproj index a079098..67dbffd 100644 --- a/xcode/client.xcodeproj/project.pbxproj +++ b/xcode/client.xcodeproj/project.pbxproj @@ -193,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -229,7 +229,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/core.xcodeproj/project.pbxproj b/xcode/core.xcodeproj/project.pbxproj index 5b64a95..f3237e6 100644 --- a/xcode/core.xcodeproj/project.pbxproj +++ b/xcode/core.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ DD1144231B8D2BCB00721CD4 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../core/Makefile; sourceTree = ""; }; DD1144241B8D2BCB00721CD4 /* memset_s.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memset_s.c; path = ../core/memset_s.c; sourceTree = ""; }; DD1144251B8D2BCB00721CD4 /* osdep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = osdep.h; path = ../core/osdep.h; sourceTree = ""; }; + DD1144271B8D2BCB00721CD4 /* psmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = psmalloc.c; path = ../core/psmalloc.c; sourceTree = ""; }; DD1144281B8D2BCB00721CD4 /* psmalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = psmalloc.h; path = ../core/psmalloc.h; sourceTree = ""; }; DD7AB3B51B979F6F0047DE55 /* osdep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = osdep.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -38,6 +39,7 @@ DD1144241B8D2BCB00721CD4 /* memset_s.c */, DD1144221B8D2BCB00721CD4 /* list.h */, DD1144281B8D2BCB00721CD4 /* psmalloc.h */, + DD1144271B8D2BCB00721CD4 /* psmalloc.c */, DD1144251B8D2BCB00721CD4 /* osdep.h */, DD7AB3B41B979F6F0047DE55 /* POSIX */, ); @@ -127,7 +129,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -163,7 +165,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/crypto.xcodeproj/project.pbxproj b/xcode/crypto.xcodeproj/project.pbxproj index f1d03c9..6c577db 100644 --- a/xcode/crypto.xcodeproj/project.pbxproj +++ b/xcode/crypto.xcodeproj/project.pbxproj @@ -11,15 +11,13 @@ DD1144351B8D2DE200721CD4 /* cryptoConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cryptoConfig.h; path = ../crypto/cryptoConfig.h; sourceTree = ""; }; DD1144361B8D2DE200721CD4 /* cryptolib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cryptolib.h; path = ../crypto/cryptolib.h; sourceTree = ""; }; DD11443E1B8D2E4E00721CD4 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../crypto/Makefile; sourceTree = ""; }; - DD376E461CC55C8C008AD651 /* cryptoCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cryptoCheck.h; path = ../crypto/cryptoCheck.h; sourceTree = ""; }; - DD4E16F81C3B16350064B760 /* digest_libsodium.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = digest_libsodium.c; sourceTree = ""; }; - DD4E16F91C3B16350064B760 /* digest_libsodium.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digest_libsodium.h; sourceTree = ""; }; - DD4E16FA1C3B16540064B760 /* symmetric_libsodium.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = symmetric_libsodium.c; sourceTree = ""; }; - DD4E16FB1C3B16540064B760 /* symmetric_libsodium.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symmetric_libsodium.h; sourceTree = ""; }; + DD7AB33F1B979E3B0047DE55 /* cmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmac.c; sourceTree = ""; }; DD7AB3411B979E3B0047DE55 /* digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digest.h; sourceTree = ""; }; + DD7AB3421B979E3B0047DE55 /* digest_fips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digest_fips.h; sourceTree = ""; }; DD7AB3431B979E3B0047DE55 /* digest_matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digest_matrix.h; sourceTree = ""; }; DD7AB3441B979E3B0047DE55 /* digest_openssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = digest_openssl.c; sourceTree = ""; }; DD7AB3451B979E3B0047DE55 /* digest_openssl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digest_openssl.h; sourceTree = ""; }; + DD7AB3461B979E3B0047DE55 /* digest_pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = digest_pkcs11.h; sourceTree = ""; }; DD7AB3471B979E3B0047DE55 /* hmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hmac.c; sourceTree = ""; }; DD7AB3491B979E3B0047DE55 /* md2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md2.c; sourceTree = ""; }; DD7AB34B1B979E3B0047DE55 /* md4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md4.c; sourceTree = ""; }; @@ -30,35 +28,48 @@ DD7AB3551B979E3B0047DE55 /* sha512.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha512.c; sourceTree = ""; }; DD7AB35B1B979E3B0047DE55 /* asn1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asn1.c; sourceTree = ""; }; DD7AB35C1B979E3B0047DE55 /* asn1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asn1.h; sourceTree = ""; }; + DD7AB35E1B979E3B0047DE55 /* asn1enc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asn1enc.c; sourceTree = ""; }; DD7AB3601B979E3B0047DE55 /* base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = base64.c; sourceTree = ""; }; - 87EA02501CF4ED69001F4ECA /* crl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crl.c; sourceTree = ""; }; DD7AB3621B979E3B0047DE55 /* pkcs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs.c; sourceTree = ""; }; DD7AB3641B979E3B0047DE55 /* x509.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x509.c; sourceTree = ""; }; DD7AB3651B979E3B0047DE55 /* x509.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x509.h; sourceTree = ""; }; + DD7AB3671B979E3B0047DE55 /* x509enc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x509enc.c; sourceTree = ""; }; + DD7AB3691B979E3B0047DE55 /* x509req.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x509req.c; sourceTree = ""; }; + DD7AB36C1B979E3B0047DE55 /* fips.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fips.c; sourceTree = ""; }; DD7AB36D1B979E3B0047DE55 /* layer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layer.h; sourceTree = ""; }; DD7AB36E1B979E3B0047DE55 /* matrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix.c; sourceTree = ""; }; + DD7AB3701B979E3B0047DE55 /* pkcs11.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs11.c; sourceTree = ""; }; DD7AB3731B979E3B0047DE55 /* pstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pstm.c; sourceTree = ""; }; DD7AB3741B979E3B0047DE55 /* pstm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pstm.h; sourceTree = ""; }; DD7AB3761B979E3B0047DE55 /* pstm_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pstm_montgomery_reduce.c; sourceTree = ""; }; DD7AB3781B979E3B0047DE55 /* pstm_mul_comba.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pstm_mul_comba.c; sourceTree = ""; }; DD7AB37A1B979E3B0047DE55 /* pstm_sqr_comba.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pstm_sqr_comba.c; sourceTree = ""; }; + DD7AB37D1B979E3B0047DE55 /* fortuna.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fortuna.c; sourceTree = ""; }; DD7AB37F1B979E3B0047DE55 /* prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prng.c; sourceTree = ""; }; DD7AB3801B979E3B0047DE55 /* prng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prng.h; sourceTree = ""; }; DD7AB3821B979E3B0047DE55 /* yarrow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yarrow.c; sourceTree = ""; }; DD7AB3851B979E3B0047DE55 /* dh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dh.c; sourceTree = ""; }; DD7AB3871B979E3B0047DE55 /* ecc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ecc.c; sourceTree = ""; }; + DD7AB3891B979E3B0047DE55 /* eccPkcs11.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = eccPkcs11.c; sourceTree = ""; }; DD7AB38C1B979E3B0047DE55 /* pubkey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pubkey.c; sourceTree = ""; }; DD7AB38D1B979E3B0047DE55 /* pubkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pubkey.h; sourceTree = ""; }; + DD7AB38F1B979E3B0047DE55 /* pubkey_fips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pubkey_fips.h; sourceTree = ""; }; DD7AB3901B979E3B0047DE55 /* pubkey_matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pubkey_matrix.h; sourceTree = ""; }; DD7AB3911B979E3B0047DE55 /* pubkey_openssl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pubkey_openssl.h; sourceTree = ""; }; + DD7AB3921B979E3B0047DE55 /* pubkey_pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pubkey_pkcs11.h; sourceTree = ""; }; + DD7AB3931B979E3B0047DE55 /* pubkey_tilera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pubkey_tilera.h; sourceTree = ""; }; DD7AB3941B979E3B0047DE55 /* rsa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa.c; sourceTree = ""; }; DD7AB3961B979E3B0047DE55 /* rsa_openssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_openssl.c; sourceTree = ""; }; + DD7AB3971B979E3B0047DE55 /* rsaFips.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsaFips.c; sourceTree = ""; }; DD7AB3991B979E3B0047DE55 /* aes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aes.c; sourceTree = ""; }; DD7AB39B1B979E3B0047DE55 /* aes_aesni.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aes_aesni.c; sourceTree = ""; }; DD7AB39C1B979E3B0047DE55 /* aes_aesni.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes_aesni.h; sourceTree = ""; }; DD7AB39E1B979E3B0047DE55 /* aes_matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes_matrix.h; sourceTree = ""; }; DD7AB39F1B979E3B0047DE55 /* aesCBC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aesCBC.c; sourceTree = ""; }; + DD7AB3A11B979E3B0047DE55 /* aesCFB.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aesCFB.c; sourceTree = ""; }; + DD7AB3A21B979E3B0047DE55 /* aesCTR.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aesCTR.c; sourceTree = ""; }; DD7AB3A31B979E3B0047DE55 /* aesGCM.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aesGCM.c; sourceTree = ""; }; + DD7AB3A51B979E3B0047DE55 /* aesWrap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aesWrap.c; sourceTree = ""; }; DD7AB3A71B979E3B0047DE55 /* arc4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arc4.c; sourceTree = ""; }; DD7AB3A91B979E3B0047DE55 /* des3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = des3.c; sourceTree = ""; }; DD7AB3AB1B979E3B0047DE55 /* idea.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = idea.c; sourceTree = ""; }; @@ -75,7 +86,6 @@ children = ( DD11443E1B8D2E4E00721CD4 /* Makefile */, DD1144351B8D2DE200721CD4 /* cryptoConfig.h */, - DD376E461CC55C8C008AD651 /* cryptoCheck.h */, DD1144341B8D2DE200721CD4 /* cryptoApi.h */, DD1144361B8D2DE200721CD4 /* cryptolib.h */, DD7AB33E1B979E3B0047DE55 /* digest */, @@ -93,9 +103,10 @@ children = ( DD7AB3411B979E3B0047DE55 /* digest.h */, DD7AB3431B979E3B0047DE55 /* digest_matrix.h */, - DD4E16F91C3B16350064B760 /* digest_libsodium.h */, + DD7AB3421B979E3B0047DE55 /* digest_fips.h */, DD7AB3451B979E3B0047DE55 /* digest_openssl.h */, - DD4E16F81C3B16350064B760 /* digest_libsodium.c */, + DD7AB3461B979E3B0047DE55 /* digest_pkcs11.h */, + DD7AB33F1B979E3B0047DE55 /* cmac.c */, DD7AB3441B979E3B0047DE55 /* digest_openssl.c */, DD7AB3471B979E3B0047DE55 /* hmac.c */, DD7AB3491B979E3B0047DE55 /* md2.c */, @@ -115,11 +126,13 @@ children = ( DD7AB35C1B979E3B0047DE55 /* asn1.h */, DD7AB35B1B979E3B0047DE55 /* asn1.c */, + DD7AB35E1B979E3B0047DE55 /* asn1enc.c */, DD7AB3601B979E3B0047DE55 /* base64.c */, - 87EA02501CF4ED69001F4ECA /* crl.c */, DD7AB3621B979E3B0047DE55 /* pkcs.c */, DD7AB3651B979E3B0047DE55 /* x509.h */, DD7AB3641B979E3B0047DE55 /* x509.c */, + DD7AB3671B979E3B0047DE55 /* x509enc.c */, + DD7AB3691B979E3B0047DE55 /* x509req.c */, ); name = keyformat; path = ../crypto/keyformat; @@ -129,7 +142,9 @@ isa = PBXGroup; children = ( DD7AB36D1B979E3B0047DE55 /* layer.h */, + DD7AB36C1B979E3B0047DE55 /* fips.c */, DD7AB36E1B979E3B0047DE55 /* matrix.c */, + DD7AB3701B979E3B0047DE55 /* pkcs11.c */, ); name = layer; path = ../crypto/layer; @@ -153,6 +168,7 @@ children = ( DD7AB3801B979E3B0047DE55 /* prng.h */, DD7AB37F1B979E3B0047DE55 /* prng.c */, + DD7AB37D1B979E3B0047DE55 /* fortuna.c */, DD7AB3821B979E3B0047DE55 /* yarrow.c */, ); name = prng; @@ -168,8 +184,13 @@ DD7AB3851B979E3B0047DE55 /* dh.c */, DD7AB3871B979E3B0047DE55 /* ecc.c */, DD7AB3941B979E3B0047DE55 /* rsa.c */, + DD7AB3921B979E3B0047DE55 /* pubkey_pkcs11.h */, + DD7AB3891B979E3B0047DE55 /* eccPkcs11.c */, DD7AB3911B979E3B0047DE55 /* pubkey_openssl.h */, DD7AB3961B979E3B0047DE55 /* rsa_openssl.c */, + DD7AB38F1B979E3B0047DE55 /* pubkey_fips.h */, + DD7AB3971B979E3B0047DE55 /* rsaFips.c */, + DD7AB3931B979E3B0047DE55 /* pubkey_tilera.h */, ); name = pubkey; path = ../crypto/pubkey; @@ -180,19 +201,20 @@ children = ( DD7AB3B11B979E3B0047DE55 /* symmetric.h */, DD7AB39E1B979E3B0047DE55 /* aes_matrix.h */, - DD7AB39C1B979E3B0047DE55 /* aes_aesni.h */, - DD4E16FB1C3B16540064B760 /* symmetric_libsodium.h */, - DD7AB3B31B979E3B0047DE55 /* symmetric_openssl.h */, DD7AB3991B979E3B0047DE55 /* aes.c */, DD7AB39F1B979E3B0047DE55 /* aesCBC.c */, + DD7AB3A11B979E3B0047DE55 /* aesCFB.c */, + DD7AB3A21B979E3B0047DE55 /* aesCTR.c */, DD7AB3A31B979E3B0047DE55 /* aesGCM.c */, + DD7AB3A51B979E3B0047DE55 /* aesWrap.c */, + DD7AB39C1B979E3B0047DE55 /* aes_aesni.h */, DD7AB39B1B979E3B0047DE55 /* aes_aesni.c */, DD7AB3A71B979E3B0047DE55 /* arc4.c */, DD7AB3A91B979E3B0047DE55 /* des3.c */, DD7AB3AB1B979E3B0047DE55 /* idea.c */, DD7AB3AD1B979E3B0047DE55 /* rc2.c */, DD7AB3AF1B979E3B0047DE55 /* seed.c */, - DD4E16FA1C3B16540064B760 /* symmetric_libsodium.c */, + DD7AB3B31B979E3B0047DE55 /* symmetric_openssl.h */, DD7AB3B21B979E3B0047DE55 /* symmetric_openssl.c */, ); name = symmetric; @@ -283,7 +305,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -319,7 +341,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/dtlsClient.xcodeproj/project.pbxproj b/xcode/dtlsClient.xcodeproj/project.pbxproj index 332efac..3fe48bc 100644 --- a/xcode/dtlsClient.xcodeproj/project.pbxproj +++ b/xcode/dtlsClient.xcodeproj/project.pbxproj @@ -193,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -229,7 +229,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/dtlsServer.xcodeproj/project.pbxproj b/xcode/dtlsServer.xcodeproj/project.pbxproj index 53d7739..4873df8 100644 --- a/xcode/dtlsServer.xcodeproj/project.pbxproj +++ b/xcode/dtlsServer.xcodeproj/project.pbxproj @@ -194,7 +194,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -230,7 +230,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/matrixssl.xcodeproj/project.pbxproj b/xcode/matrixssl.xcodeproj/project.pbxproj index 0a75213..e31b6ff 100644 --- a/xcode/matrixssl.xcodeproj/project.pbxproj +++ b/xcode/matrixssl.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ DD1144541B8D2F7A00721CD4 /* matrixssllib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = matrixssllib.h; path = ../matrixssl/matrixssllib.h; sourceTree = ""; }; DD1144551B8D2F7A00721CD4 /* prf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prf.c; path = ../matrixssl/prf.c; sourceTree = ""; }; DD1144561B8D2F7A00721CD4 /* psk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = psk.c; path = ../matrixssl/psk.c; sourceTree = ""; }; + DD1144571B8D2F7A00721CD4 /* resumption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = resumption.c; path = ../matrixssl/resumption.c; sourceTree = ""; }; DD1144581B8D2F7A00721CD4 /* sslDecode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sslDecode.c; path = ../matrixssl/sslDecode.c; sourceTree = ""; }; DD1144591B8D2F7A00721CD4 /* sslEncode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sslEncode.c; path = ../matrixssl/sslEncode.c; sourceTree = ""; }; DD11445A1B8D2F7A00721CD4 /* sslv3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sslv3.c; path = ../matrixssl/sslv3.c; sourceTree = ""; }; @@ -32,9 +33,9 @@ DD11443F1B8D2EE600721CD4 = { isa = PBXGroup; children = ( + 877FACC11BF5470600BF8B70 /* matrixsslCheck.h */, DD11444F1B8D2F7A00721CD4 /* Makefile */, DD1144531B8D2F7A00721CD4 /* matrixsslConfig.h */, - 877FACC11BF5470600BF8B70 /* matrixsslCheck.h */, DD1144521B8D2F7A00721CD4 /* matrixsslApi.h */, DD1144541B8D2F7A00721CD4 /* matrixssllib.h */, DD11444A1B8D2F7A00721CD4 /* cipherSuite.c */, @@ -46,6 +47,7 @@ DD1144511B8D2F7A00721CD4 /* matrixsslApi.c */, DD1144551B8D2F7A00721CD4 /* prf.c */, DD1144561B8D2F7A00721CD4 /* psk.c */, + DD1144571B8D2F7A00721CD4 /* resumption.c */, DD1144581B8D2F7A00721CD4 /* sslDecode.c */, DD1144591B8D2F7A00721CD4 /* sslEncode.c */, DD11445A1B8D2F7A00721CD4 /* sslv3.c */, @@ -138,7 +140,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -174,7 +176,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/server.xcodeproj/project.pbxproj b/xcode/server.xcodeproj/project.pbxproj index c8c1d0b..34541b4 100644 --- a/xcode/server.xcodeproj/project.pbxproj +++ b/xcode/server.xcodeproj/project.pbxproj @@ -194,7 +194,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -230,7 +230,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/xcode/sshServer.xcodeproj/project.pbxproj b/xcode/sshServer.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ed05b7f --- /dev/null +++ b/xcode/sshServer.xcodeproj/project.pbxproj @@ -0,0 +1,298 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXContainerItemProxy section */ + DD7AB3D41B97A0800047DE55 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DD7AB3CF1B97A03B0047DE55 /* core.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = DD7EB84D1B8D2A83000F7458; + remoteInfo = core; + }; + DD7AB3D61B97A0800047DE55 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DD7AB3CB1B97A0360047DE55 /* crypto.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = DD11442E1B8D2D7D00721CD4; + remoteInfo = crypto; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 87CB70911C0CDC0000DDADA7 /* algo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = algo.c; path = ../matrixssh/algo.c; sourceTree = ""; }; + 87CB70921C0CDC0000DDADA7 /* algo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = algo.h; path = ../matrixssh/algo.h; sourceTree = ""; }; + 87CB70931C0CDC0000DDADA7 /* file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file.c; path = ../matrixssh/file.c; sourceTree = ""; }; + 87CB70941C0CDC0000DDADA7 /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = file.h; path = ../matrixssh/file.h; sourceTree = ""; }; + 87CB70951C0CDC0000DDADA7 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../matrixssh/Makefile; sourceTree = ""; }; + 87CB70961C0CDC0000DDADA7 /* matrixsshApi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = matrixsshApi.c; path = ../matrixssh/matrixsshApi.c; sourceTree = ""; }; + 87CB70971C0CDC0000DDADA7 /* matrixsshApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = matrixsshApi.h; path = ../matrixssh/matrixsshApi.h; sourceTree = ""; }; + 87CB70981C0CDC0000DDADA7 /* matrixsshConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = matrixsshConfig.h; path = ../matrixssh/matrixsshConfig.h; sourceTree = ""; }; + 87CB70991C0CDC0000DDADA7 /* matrixsshlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = matrixsshlib.h; path = ../matrixssh/matrixsshlib.h; sourceTree = ""; }; + 87CB709A1C0CDC0000DDADA7 /* posixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = posixSock.c; path = ../matrixssh/posixSock.c; sourceTree = ""; }; + 87CB709B1C0CDC0000DDADA7 /* posixSock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = posixSock.h; path = ../matrixssh/posixSock.h; sourceTree = ""; }; + 87CB709C1C0CDC0000DDADA7 /* scp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scp.c; path = ../matrixssh/scp.c; sourceTree = ""; }; + 87CB709D1C0CDC0000DDADA7 /* server.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = server.c; path = ../matrixssh/server.c; sourceTree = ""; }; + 87CB709E1C0CDC0000DDADA7 /* sftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sftp.c; path = ../matrixssh/sftp.c; sourceTree = ""; }; + 87CB709F1C0CDC0000DDADA7 /* sftp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sftp.h; path = ../matrixssh/sftp.h; sourceTree = ""; }; + 87CB70A01C0CDC0000DDADA7 /* ssh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ssh.h; path = ../matrixssh/ssh.h; sourceTree = ""; }; + 87CB70A11C0CDC0000DDADA7 /* sshAuth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sshAuth.c; path = ../matrixssh/sshAuth.c; sourceTree = ""; }; + 87CB70A21C0CDC0000DDADA7 /* sshChanSession.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sshChanSession.c; path = ../matrixssh/sshChanSession.c; sourceTree = ""; }; + 87CB70A31C0CDC0000DDADA7 /* sshDecode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sshDecode.c; path = ../matrixssh/sshDecode.c; sourceTree = ""; }; + 87CB70A41C0CDC0000DDADA7 /* sshEncode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sshEncode.c; path = ../matrixssh/sshEncode.c; sourceTree = ""; }; + 87CB70A51C0CDC0000DDADA7 /* sshKex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sshKex.c; path = ../matrixssh/sshKex.c; sourceTree = ""; }; + 87CB70A61C0CDC1E00DDADA7 /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = buffer.c; path = ../matrixssh/utils/buffer.c; sourceTree = ""; }; + 87CB70A71C0CDC1E00DDADA7 /* queue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = queue.c; path = ../matrixssh/utils/queue.c; sourceTree = ""; }; + 87CB70A81C0CDC1E00DDADA7 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utils.h; path = ../matrixssh/utils/utils.h; sourceTree = ""; }; + DD7AB3CB1B97A0360047DE55 /* crypto.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = crypto.xcodeproj; sourceTree = ""; }; + DD7AB3CF1B97A03B0047DE55 /* core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = core.xcodeproj; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + DD7AB3111B979AF40047DE55 = { + isa = PBXGroup; + children = ( + 87CB70A61C0CDC1E00DDADA7 /* buffer.c */, + 87CB70A71C0CDC1E00DDADA7 /* queue.c */, + 87CB70A81C0CDC1E00DDADA7 /* utils.h */, + 87CB70911C0CDC0000DDADA7 /* algo.c */, + 87CB70921C0CDC0000DDADA7 /* algo.h */, + 87CB70931C0CDC0000DDADA7 /* file.c */, + 87CB70941C0CDC0000DDADA7 /* file.h */, + 87CB70951C0CDC0000DDADA7 /* Makefile */, + 87CB70961C0CDC0000DDADA7 /* matrixsshApi.c */, + 87CB70971C0CDC0000DDADA7 /* matrixsshApi.h */, + 87CB70981C0CDC0000DDADA7 /* matrixsshConfig.h */, + 87CB70991C0CDC0000DDADA7 /* matrixsshlib.h */, + 87CB709A1C0CDC0000DDADA7 /* posixSock.c */, + 87CB709B1C0CDC0000DDADA7 /* posixSock.h */, + 87CB709C1C0CDC0000DDADA7 /* scp.c */, + 87CB709D1C0CDC0000DDADA7 /* server.c */, + 87CB709E1C0CDC0000DDADA7 /* sftp.c */, + 87CB709F1C0CDC0000DDADA7 /* sftp.h */, + 87CB70A01C0CDC0000DDADA7 /* ssh.h */, + 87CB70A11C0CDC0000DDADA7 /* sshAuth.c */, + 87CB70A21C0CDC0000DDADA7 /* sshChanSession.c */, + 87CB70A31C0CDC0000DDADA7 /* sshDecode.c */, + 87CB70A41C0CDC0000DDADA7 /* sshEncode.c */, + 87CB70A51C0CDC0000DDADA7 /* sshKex.c */, + DD7AB3CF1B97A03B0047DE55 /* core.xcodeproj */, + DD7AB3CB1B97A0360047DE55 /* crypto.xcodeproj */, + ); + sourceTree = ""; + }; + DD7AB3CC1B97A0360047DE55 /* Products */ = { + isa = PBXGroup; + children = ( + ); + name = Products; + sourceTree = ""; + }; + DD7AB3D01B97A03B0047DE55 /* Products */ = { + isa = PBXGroup; + children = ( + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + DD7AB3161B979AF40047DE55 /* sshServer */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = DD7AB3191B979AF40047DE55 /* Build configuration list for PBXLegacyTarget "sshServer" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = ../matrixssh; + dependencies = ( + DD7AB3D51B97A0800047DE55 /* PBXTargetDependency */, + DD7AB3D71B97A0800047DE55 /* PBXTargetDependency */, + ); + name = sshServer; + passBuildSettingsInEnvironment = 1; + productName = cmsTest; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + DD7AB3121B979AF40047DE55 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0710; + ORGANIZATIONNAME = "INSIDE Secure"; + TargetAttributes = { + DD7AB3161B979AF40047DE55 = { + CreatedOnToolsVersion = 6.4; + }; + }; + }; + buildConfigurationList = DD7AB3151B979AF40047DE55 /* Build configuration list for PBXProject "sshServer" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = DD7AB3111B979AF40047DE55; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = DD7AB3D01B97A03B0047DE55 /* Products */; + ProjectRef = DD7AB3CF1B97A03B0047DE55 /* core.xcodeproj */; + }, + { + ProductGroup = DD7AB3CC1B97A0360047DE55 /* Products */; + ProjectRef = DD7AB3CB1B97A0360047DE55 /* crypto.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + DD7AB3161B979AF40047DE55 /* sshServer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXTargetDependency section */ + DD7AB3D51B97A0800047DE55 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = core; + targetProxy = DD7AB3D41B97A0800047DE55 /* PBXContainerItemProxy */; + }; + DD7AB3D71B97A0800047DE55 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = crypto; + targetProxy = DD7AB3D61B97A0800047DE55 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + DD7AB3171B979AF40047DE55 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + DD7AB3181B979AF40047DE55 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + DD7AB31A1B979AF40047DE55 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUGGING_SYMBOLS = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DD7AB31B1B979AF40047DE55 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DD7AB3151B979AF40047DE55 /* Build configuration list for PBXProject "sshServer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD7AB3171B979AF40047DE55 /* Debug */, + DD7AB3181B979AF40047DE55 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DD7AB3191B979AF40047DE55 /* Build configuration list for PBXLegacyTarget "sshServer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD7AB31A1B979AF40047DE55 /* Debug */, + DD7AB31B1B979AF40047DE55 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DD7AB3121B979AF40047DE55 /* Project object */; +} diff --git a/xcode/sslTest.xcodeproj/project.pbxproj b/xcode/sslTest.xcodeproj/project.pbxproj index a34a49d..eb3a66e 100644 --- a/xcode/sslTest.xcodeproj/project.pbxproj +++ b/xcode/sslTest.xcodeproj/project.pbxproj @@ -188,7 +188,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -224,7 +224,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; };