From a9d502ef85144f7c57dd256fa8f42d099e13c42f Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 2 Jul 2020 21:15:15 +0200 Subject: [PATCH 01/53] Add `--enable-libest` option to configure.ac Refactoring and adding defines for functions --- configure.ac | 26 ++++++++++++++++++++++++++ src/ssl.c | 6 ++---- wolfssl/openssl/ssl.h | 3 +++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 45842cd3d..d7db9a933 100644 --- a/configure.ac +++ b/configure.ac @@ -702,6 +702,7 @@ AC_ARG_ENABLE([mcast], # signal (--enable-signal) # lighty (--enable-lighty) HAVE_LIGHTY # stunnel (--enable-stunnel) HAVE_STUNNEL +# libest (--enable-libest) # asio (--enable-asio) WOLFSSL_ASIO # libwebsockets (--enable-libwebsockets) WOLFSSL_LIBWEBSOCKETS # qt (--enable-qt) WOLFSSL_QT @@ -4240,6 +4241,31 @@ then ENABLED_PSK=yes fi +# libest Support +AC_ARG_ENABLE([libest], + [AS_HELP_STRING([--enable-libest],[Enable libest (default: disabled)])], + [ ENABLED_LIBEST=$enableval ], + [ ENABLED_LIBEST=no ] + ) + +if test "$ENABLED_LIBEST" = "yes" +then + # Requires opensslextra and opensslall + if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" + then + ENABLED_OPENSSLALL="yes" + ENABLED_OPENSSLEXTRA="yes" + AM_CFLAGS="-DOPENSSL_EXTRA -DOPENSSL_ALL $AM_CFLAGS" + fi + + # Requires OCSP make sure on + if test "x$ENABLED_OCSP" = "xno" + then + ENABLED_OCSP="yes" + AM_CFLAGS="$AM_CFLAGS -DHAVE_OCSP" + fi +fi + # MD4 AC_ARG_ENABLE([md4], [AS_HELP_STRING([--enable-md4],[Enable MD4 (default: disabled)])], diff --git a/src/ssl.c b/src/ssl.c index b2aa70d4c..81c747810 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18307,13 +18307,11 @@ int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x50 } /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_X509); + node = wolfSSL_sk_new_node(sk->heap); if (node == NULL) { WOLFSSL_MSG("Memory error"); return WOLFSSL_FAILURE; } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); /* push new x509 onto head of stack */ node->data.x509 = sk->data.x509; @@ -42313,7 +42311,7 @@ WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk if (node != NULL) { /* update sk and remove node from stack */ sk->data.info = node->data.info; sk->next = node->next; - XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL); + wolfSSL_sk_free_node(node); } else { /* last x509 in stack */ sk->data.info = NULL; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index d1e4dfbb8..e50bf42b9 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -357,10 +357,12 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define i2d_X509_bio wolfSSL_i2d_X509_bio #define d2i_X509_bio wolfSSL_d2i_X509_bio +#define d2i_X509_REQ_bio wolfSSL_d2i_X509_bio #define d2i_X509_fp wolfSSL_d2i_X509_fp #define i2d_X509 wolfSSL_i2d_X509 #define d2i_X509 wolfSSL_d2i_X509 #define PEM_read_bio_X509 wolfSSL_PEM_read_bio_X509 +#define PEM_read_bio_X509_REQ wolfSSL_PEM_read_bio_X509 #define PEM_read_bio_X509_CRL wolfSSL_PEM_read_bio_X509_CRL #define PEM_read_bio_X509_AUX wolfSSL_PEM_read_bio_X509_AUX #define PEM_read_X509 wolfSSL_PEM_read_X509 @@ -460,6 +462,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define sk_X509_INFO_pop wolfSSL_sk_X509_INFO_pop #define sk_X509_INFO_pop_free wolfSSL_sk_X509_INFO_pop_free #define sk_X509_INFO_free wolfSSL_sk_X509_INFO_free +#define sk_X509_INFO_shift wolfSSL_sk_X509_INFO_pop #define i2d_X509_NAME wolfSSL_i2d_X509_NAME #define d2i_X509_NAME wolfSSL_d2i_X509_NAME From 7bd0b2eb447fbaf92fc078f0b1559b2e0d08915b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 3 Jul 2020 15:43:42 +0200 Subject: [PATCH 02/53] Implement ASN1_get_object --- src/ssl.c | 66 ++++++++++++++++++++++++++++++++++++++++++ tests/api.c | 37 +++++++++++++++++++++++ wolfssl/openssl/asn1.h | 5 ++++ 3 files changed, 108 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 81c747810..82a5feb2d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -26006,6 +26006,72 @@ WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a) } #endif +/** + * Parse an ASN1 encoded input and output information about the parsed object + * @param in ASN1 encoded data. *in is moved to the value of the ASN1 object + * @param len Length of parsed ASN1 object + * @param tag Tag value of parsed ASN1 object + * @param class Class of parsed ASN1 object + * @param inLen Length of *in buffer + * @return int Depends on which bits are set in the returned int: + * 0x80 an error occured during parsing + * 0x20 parsed object is constructed + * 0x01 the parsed object length is infinite + */ +int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, + int *class, long inLen) +{ + word32 inOutIdx = 0; + int l; + byte t; + int ret = 0x80; + + WOLFSSL_ENTER("wolfSSL_ASN1_get_object"); + + if (!in || !*in || !len || !tag || !class || inLen == 0) { + WOLFSSL_MSG("Bad parameter"); + return ret; + } + + if (GetASNTag(*in, &inOutIdx, &t, inLen) != 0) { + WOLFSSL_MSG("GetASNTag error"); + return ret; + } + + if (GetLength(*in, &inOutIdx, &l, inLen) < 0) { + WOLFSSL_MSG("GetLength error"); + return ret; + } + + *tag = t & 0x1F; /* Tag number is 5 lsb */ + *class = t & 0xC0; /* Class is 2 msb */ + *len = l; + ret = t & ASN_CONSTRUCTED; + + if (l > inLen - inOutIdx) { + /* Still return other values but indicate error in msb */ + ret |= 0x80; + } + + *in += inOutIdx; + return ret; +} + +#ifndef NO_WOLFSSL_STUB +WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, + const unsigned char **pp, long len) +{ + (void)a; + (void)pp; + (void)len; + + WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT"); + WOLFSSL_STUB("c2i_ASN1_OBJECT"); + + return NULL; +} +#endif + #ifndef NO_BIO /* Return number of bytes written to BIO on success. 0 on failure. */ WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp, diff --git a/tests/api.c b/tests/api.c index 3f9a2f7a3..e6b5315ea 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38750,6 +38750,42 @@ static void test_wolfSSL_ASN1_STRING_print(void){ #endif /* !NO_BIO */ +static void test_wolfSSL_ASN1_get_object(void) +{ +#ifdef OPENSSL_EXTRA + const unsigned char* derBuf = cliecc_cert_der_256; + int len = sizeof_cliecc_cert_der_256; + long asnLen = 0; + int tag = 0, class = 0; + + printf(testingFmt, "wolfSSL_ASN1_get_object()"); + + /* Read a couple TLV triplets and make sure they match the expected values */ + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, len) & 0x80, 0); + AssertIntEQ(asnLen, 831); + AssertIntEQ(tag, 0x10); + AssertIntEQ(class, 0); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(asnLen, 741); + AssertIntEQ(tag, 0x10); + AssertIntEQ(class, 0); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(asnLen, 3); + AssertIntEQ(tag, 0); + AssertIntEQ(class, 0x80); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(asnLen, 1); + AssertIntEQ(tag, 0x2); + AssertIntEQ(class, 0); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + static void test_wolfSSL_RSA_verify() { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && \ @@ -39659,6 +39695,7 @@ void ApiTest(void) test_wolfSSL_RSA_print(); test_wolfSSL_ASN1_STRING_print(); #endif + test_wolfSSL_ASN1_get_object(); test_openssl_generate_key_and_cert(); test_wolfSSL_EC_get_builtin_curves(); diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index f9f806b89..f2a0c21e5 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -32,6 +32,8 @@ #define ASN1_STRING_set wolfSSL_ASN1_STRING_set #define ASN1_STRING_free wolfSSL_ASN1_STRING_free +#define ASN1_get_object wolfSSL_ASN1_get_object + #define V_ASN1_INTEGER 0x02 #define V_ASN1_OCTET_STRING 0x04 /* tag for ASN1_OCTET_STRING */ #define V_ASN1_NEG 0x100 @@ -83,6 +85,9 @@ WOLFSSL_API WOLFSSL_ASN1_INTEGER *wolfSSL_BN_to_ASN1_INTEGER( WOLFSSL_API void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value); +WOLFSSL_API int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, + int *class, long inLen); + #ifdef OPENSSL_ALL /* IMPLEMENT_ASN1_FUNCTIONS is strictly for external use only. Internally * we don't use this. Some projects use OpenSSL to implement ASN1 types and From 777bdb28bc3ad1688aaa1cf66356feec98d13c8d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 3 Jul 2020 17:30:16 +0200 Subject: [PATCH 03/53] Implement/stub the following: - `NID_pkcs9_challengePassword` - added - `wolfSSL_OPENSSL_cleanse` - implemented - `wolfSSL_X509_REQ_add1_attr_by_NID` - stubbed - `wolfSSL_c2i_ASN1_OBJECT` - stubbed --- configure.ac | 20 +++++++++++++++++++- src/ssl.c | 21 +++++++++++++++++++++ wolfssl/openssl/asn1.h | 6 ++++++ wolfssl/openssl/ssl.h | 4 ++++ wolfssl/openssl/x509.h | 1 + wolfssl/ssl.h | 5 +++++ wolfssl/wolfcrypt/asn.h | 1 + 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d7db9a933..aa380d78f 100644 --- a/configure.ac +++ b/configure.ac @@ -4258,12 +4258,30 @@ then AM_CFLAGS="-DOPENSSL_EXTRA -DOPENSSL_ALL $AM_CFLAGS" fi - # Requires OCSP make sure on + # Requires OCSP if test "x$ENABLED_OCSP" = "xno" then ENABLED_OCSP="yes" AM_CFLAGS="$AM_CFLAGS -DHAVE_OCSP" fi + + # Requires PKCS7 + if test "x$ENABLED_PKCS7" = "xno" + then + ENABLED_PKCS7="yes" + fi + + # Requires Certificate Generation and Request + if test "x$ENABLED_CERTGEN" = "xno" + then + ENABLED_CERTGEN="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_GEN" + fi + if test "x$ENABLED_CERTREQ" = "xno" + then + ENABLED_CERTREQ="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_REQ" + fi fi # MD4 diff --git a/src/ssl.c b/src/ssl.c index 82a5feb2d..2b6eafea4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -45326,6 +45326,12 @@ void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int return XMEMCPY(ret, data, siz); } +void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len) +{ + if (ptr) + ForceZero(ptr, len); +} + int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p, unsigned int p_len) { @@ -49247,6 +49253,21 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, (void)ext; return WOLFSSL_FATAL_ERROR; } + +int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, + int nid, int type, + const unsigned char *bytes, + int len) +{ + WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID"); + WOLFSSL_STUB("wolfSSL_X509_REQ_add1_attr_by_NID"); + (void)req; + (void)nid; + (void)type; + (void)bytes; + (void)len; + return WOLFSSL_FAILURE; +} #endif int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req, diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index f2a0c21e5..7c6a52824 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -33,6 +33,7 @@ #define ASN1_STRING_free wolfSSL_ASN1_STRING_free #define ASN1_get_object wolfSSL_ASN1_get_object +#define c2i_ASN1_OBJECT wolfSSL_c2i_ASN1_OBJECT #define V_ASN1_INTEGER 0x02 #define V_ASN1_OCTET_STRING 0x04 /* tag for ASN1_OCTET_STRING */ @@ -69,6 +70,8 @@ #define ASN1_TIME_set wolfSSL_ASN1_TIME_set #define V_ASN1_OBJECT 6 +#define V_ASN1_SEQUENCE 16 +#define V_ASN1_SET 17 #define V_ASN1_UTCTIME 23 #define V_ASN1_GENERALIZEDTIME 24 #define V_ASN1_PRINTABLESTRING 19 @@ -88,6 +91,9 @@ WOLFSSL_API void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *val WOLFSSL_API int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, int *class, long inLen); +WOLFSSL_API WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, + const unsigned char **pp, long len); + #ifdef OPENSSL_ALL /* IMPLEMENT_ASN1_FUNCTIONS is strictly for external use only. Internally * we don't use this. Some projects use OpenSSL to implement ASN1 types and diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index e50bf42b9..5384003a5 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -53,6 +53,8 @@ /* all NID_* values are in asn.h */ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -377,6 +379,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_free wolfSSL_X509_REQ_free #define X509_REQ_sign wolfSSL_X509_REQ_sign #define X509_REQ_add_extensions wolfSSL_X509_REQ_add_extensions +#define X509_REQ_add1_attr_by_NID wolfSSL_X509_REQ_add1_attr_by_NID #define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name #define X509_REQ_set_pubkey wolfSSL_X509_REQ_set_pubkey #define PEM_write_bio_X509_REQ wolfSSL_PEM_write_bio_X509_REQ @@ -1182,6 +1185,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define OPENSSL_config wolfSSL_OPENSSL_config #define OPENSSL_memdup wolfSSL_OPENSSL_memdup +#define OPENSSL_cleanse wolfSSL_OPENSSL_cleanse #define SSL_CTX_get_timeout wolfSSL_SSL_CTX_get_timeout #define SSL_CTX_set_tmp_ecdh wolfSSL_SSL_CTX_set_tmp_ecdh #define SSL_CTX_remove_session wolfSSL_SSL_CTX_remove_session diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index 77a8bca54..349dd089c 100644 --- a/wolfssl/openssl/x509.h +++ b/wolfssl/openssl/x509.h @@ -5,6 +5,7 @@ #include #include #include +#include /* wolfSSL_X509_print_ex flags */ #define X509_FLAG_COMPAT (0UL) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 1e6e6a31f..660c7b3f5 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3552,6 +3552,10 @@ WOLFSSL_API int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req, WOLFSSL_X509_NAME *name); WOLFSSL_API int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, + int nid, int type, + const unsigned char *bytes, + int len); #endif @@ -3775,6 +3779,7 @@ WOLFSSL_API int wolfSSL_set_alpn_protos(WOLFSSL* ssl, const unsigned char* protos, unsigned int protos_len); WOLFSSL_API void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int line); +WOLFSSL_API void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len); WOLFSSL_API void wolfSSL_ERR_load_BIO_strings(void); #endif diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 26eeee647..3210f9b19 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -202,6 +202,7 @@ enum NID_sha256 = 672, NID_sha384 = 673, NID_sha512 = 674, + NID_pkcs9_challengePassword = 54, NID_hw_name_oid = 73, NID_id_pkix_OCSP_basic = 74, NID_any_policy = 75, From 1e26238f49e5fd5128d7066901f27f4229ae94e0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 6 Jul 2020 21:08:58 +0200 Subject: [PATCH 04/53] Implement/stub the following functions: - X509_REQ_sign_ctx - X509_REQ_get_subject_name - X509_REQ_set_version - X509_NAME_print_ex_fp - X509_STORE_CTX_get0_parent_ctx - wolfSSL_PKCS7_encode_certs Add cms.h file to avoid including the OpenSSL version. --- src/ssl.c | 73 ++++++++++++++++++++++++++++++++++++++ tests/api.c | 10 ++++++ wolfssl/openssl/cms.h | 26 ++++++++++++++ wolfssl/openssl/include.am | 1 + wolfssl/openssl/pkcs7.h | 2 ++ wolfssl/openssl/ssl.h | 6 +++- wolfssl/ssl.h | 6 ++++ 7 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 wolfssl/openssl/cms.h diff --git a/src/ssl.c b/src/ssl.c index 2b6eafea4..0b5618263 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23340,6 +23340,15 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx) return wolfSSL_sk_dup(ref); } +#ifndef NO_WOLFSSL_STUB +WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx( + WOLFSSL_X509_STORE_CTX *ctx) +{ + (void)ctx; + WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_get0_parent_ctx"); + return NULL; +} +#endif int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) { @@ -42847,6 +42856,26 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, } #endif /* !NO_BIO */ +int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name, + int indent, unsigned long flags) +{ + WOLFSSL_BIO* bio; + int ret; + + WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp"); + + if (!(bio = wolfSSL_BIO_new_fp(file, BIO_NOCLOSE))) { + WOLFSSL_MSG("wolfSSL_BIO_new_fp error"); + return WOLFSSL_FAILURE; + } + + ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags); + + wolfSSL_BIO_free(bio); + + return ret; +} + #ifndef NO_WOLFSSL_STUB WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x) { @@ -48479,6 +48508,45 @@ int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, return WOLFSSL_SUCCESS; } +int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, + WOLFSSL_BIO* out) +{ + byte output[4096]; + int len; + PKCS7* p7; + + WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs"); + + if (!pkcs7 || !certs || !out) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + p7 = &((WOLFSSL_PKCS7*)pkcs7)->pkcs7; + + /* Add the certs to the PKCS7 struct */ + while (certs) { + if (wc_PKCS7_AddCertificate(p7, certs->data.x509->derCert->buffer, + certs->data.x509->derCert->length) != 0) { + WOLFSSL_MSG("wc_PKCS7_AddCertificate error"); + return WOLFSSL_FAILURE; + } + certs = certs->next; + } + + if ((len = wc_PKCS7_EncodeSignedData(p7, output, sizeof(output))) < 0) { + WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(out, output, len) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + #endif /* !NO_BIO */ WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs, @@ -49244,6 +49312,11 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, return WOLFSSL_SUCCESS; } +int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, + WOLFSSL_EVP_MD_CTX* md_ctx) +{ + return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(md_ctx)); +} #ifndef NO_WOLFSSL_STUB int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, diff --git a/tests/api.c b/tests/api.c index e6b5315ea..675251fb7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4903,6 +4903,8 @@ static void test_wolfSSL_X509_NAME_get_entry(void) AssertNotNull(bio = BIO_new(BIO_s_mem())); AssertIntEQ(X509_NAME_print_ex(bio, name, 4, (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)), WOLFSSL_SUCCESS); + AssertIntEQ(X509_NAME_print_ex_fp(stdout, name, 4, + (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)), WOLFSSL_SUCCESS); BIO_free(bio); #endif #endif @@ -36406,6 +36408,8 @@ static void test_X509_REQ(void) unsigned char* der = NULL; #endif #ifndef NO_RSA + EVP_MD_CTX *mctx = NULL; + EVP_PKEY_CTX *pkctx = NULL; #ifdef USE_CERT_BUFFERS_1024 const unsigned char* rsaPriv = (const unsigned char*)client_key_der_1024; const unsigned char* rsaPub = (unsigned char*)client_keypub_der_1024; @@ -36447,6 +36451,12 @@ static void test_X509_REQ(void) AssertIntEQ(i2d_X509_REQ(req, &der), 643); XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL); der = NULL; + + mctx = EVP_MD_CTX_new(); + AssertIntEQ(EVP_DigestSignInit(mctx, &pkctx, EVP_sha256(), NULL, priv), WOLFSSL_SUCCESS); + AssertIntEQ(X509_REQ_sign_ctx(req, mctx), WOLFSSL_SUCCESS); + + EVP_MD_CTX_free(mctx); X509_REQ_free(NULL); X509_REQ_free(req); EVP_PKEY_free(pub); diff --git a/wolfssl/openssl/cms.h b/wolfssl/openssl/cms.h new file mode 100644 index 000000000..d698c7bca --- /dev/null +++ b/wolfssl/openssl/cms.h @@ -0,0 +1,26 @@ +/* cms.h + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_OPENSSL_CMS_H_ +#define WOLFSSL_OPENSSL_CMS_H_ + + +#endif /* WOLFSSL_OPENSSL_CMS_H_ */ diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index c4ab3948f..f3b432df6 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -8,6 +8,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/bio.h \ wolfssl/openssl/bn.h \ wolfssl/openssl/buffer.h \ + wolfssl/openssl/cms.h \ wolfssl/openssl/conf.h \ wolfssl/openssl/crypto.h \ wolfssl/openssl/des.h \ diff --git a/wolfssl/openssl/pkcs7.h b/wolfssl/openssl/pkcs7.h index 94ddf2494..368cfb3d5 100644 --- a/wolfssl/openssl/pkcs7.h +++ b/wolfssl/openssl/pkcs7.h @@ -55,6 +55,8 @@ WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7); WOLFSSL_API int wolfSSL_PKCS7_verify(PKCS7* p7, WOLFSSL_STACK* certs, WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags); +WOLFSSL_API int wolfSSL_PKCS7_encode_certs(PKCS7* p7, WOLFSSL_STACK* certs, + WOLFSSL_BIO* out); WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* p7, WOLFSSL_STACK* certs, int flags); WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 5384003a5..344552b19 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -378,6 +378,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_new wolfSSL_X509_REQ_new #define X509_REQ_free wolfSSL_X509_REQ_free #define X509_REQ_sign wolfSSL_X509_REQ_sign +#define X509_REQ_sign_ctx wolfSSL_X509_REQ_sign_ctx #define X509_REQ_add_extensions wolfSSL_X509_REQ_add_extensions #define X509_REQ_add1_attr_by_NID wolfSSL_X509_REQ_add1_attr_by_NID #define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name @@ -397,7 +398,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_get_issuer_name wolfSSL_X509_get_issuer_name #define X509_issuer_name_hash wolfSSL_X509_issuer_name_hash #define X509_get_subject_name wolfSSL_X509_get_subject_name -#define X509_subject_name_hash wolfSSL_X509_subject_name_hash +#define X509_REQ_get_subject_name wolfSSL_X509_get_subject_name #define X509_get_pubkey wolfSSL_X509_get_pubkey #define X509_get0_pubkey wolfSSL_X509_get_pubkey #define X509_get_notBefore wolfSSL_X509_get_notBefore @@ -421,6 +422,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_set_notBefore wolfSSL_X509_set_notBefore #define X509_set_serialNumber wolfSSL_X509_set_serialNumber #define X509_set_version wolfSSL_X509_set_version +#define X509_REQ_set_version wolfSSL_X509_set_version #define X509_sign wolfSSL_X509_sign #define X509_print wolfSSL_X509_print #define X509_print_ex wolfSSL_X509_print_ex @@ -485,6 +487,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_NAME_oneline wolfSSL_X509_NAME_oneline #define X509_NAME_get_index_by_NID wolfSSL_X509_NAME_get_index_by_NID #define X509_NAME_print_ex wolfSSL_X509_NAME_print_ex +#define X509_NAME_print_ex_fp wolfSSL_X509_NAME_print_ex_fp #define X509_NAME_digest wolfSSL_X509_NAME_digest #define X509_cmp_current_time wolfSSL_X509_cmp_current_time #define X509_cmp_time wolfSSL_X509_cmp_time @@ -525,6 +528,7 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define X509_STORE_CTX_free wolfSSL_X509_STORE_CTX_free #define X509_STORE_CTX_get_chain wolfSSL_X509_STORE_CTX_get_chain #define X509_STORE_CTX_get1_chain wolfSSL_X509_STORE_CTX_get1_chain +#define X509_STORE_CTX_get0_parent_ctx wolfSSL_X509_STORE_CTX_get0_parent_ctx #define X509_STORE_CTX_get_error wolfSSL_X509_STORE_CTX_get_error #define X509_STORE_CTX_get_error_depth wolfSSL_X509_STORE_CTX_get_error_depth #define X509_STORE_CTX_init wolfSSL_X509_STORE_CTX_init diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 660c7b3f5..2bda06002 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1430,6 +1430,8 @@ WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain( WOLFSSL_X509_STORE_CTX* ctx); WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain( WOLFSSL_X509_STORE_CTX* ctx); +WOLFSSL_API WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx( + WOLFSSL_X509_STORE_CTX *ctx); WOLFSSL_API int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag); WOLFSSL_API int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE*); @@ -3546,6 +3548,8 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_REQ_new(void); WOLFSSL_API void wolfSSL_X509_REQ_free(WOLFSSL_X509* req); WOLFSSL_API int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md); +WOLFSSL_API int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, + WOLFSSL_EVP_MD_CTX* md_ctx); WOLFSSL_API int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext); WOLFSSL_API int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req, @@ -3636,6 +3640,8 @@ WOLFSSL_API int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJE WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int, unsigned long); +WOLFSSL_API int wolfSSL_X509_NAME_print_ex_fp(XFILE,WOLFSSL_X509_NAME*,int, + unsigned long); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || HAVE_LIGHTY */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) From 3721d80e84d8a67dff552e58f6824e1ca58351d6 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 7 Jul 2020 19:26:24 +0200 Subject: [PATCH 05/53] Implement wolfSSL_PKCS7_to_stack and wolfSSL_d2i_ASN1_OBJECT - I also implemented wolfSSL_c2i_ASN1_OBJECT which was previously a stub. - More configure.ac flags added to libest option --- configure.ac | 7 ++++ src/ssl.c | 83 +++++++++++++++++++++++++++++++++++------ wolfssl/openssl/asn1.h | 1 + wolfssl/openssl/pkcs7.h | 2 + wolfssl/ssl.h | 3 ++ 5 files changed, 85 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index aa380d78f..298b4be1b 100644 --- a/configure.ac +++ b/configure.ac @@ -4282,6 +4282,13 @@ then ENABLED_CERTREQ="yes" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_REQ" fi + + # Requires CRL + if test "x$ENABLED_CRL" = "xno" + then + ENABLED_CRL="yes" + AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL" + fi fi # MD4 diff --git a/src/ssl.c b/src/ssl.c index 0b5618263..549ffcff9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23454,9 +23454,6 @@ int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag) ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag); } - (void)store; - (void)flag; - return ret; } @@ -26015,6 +26012,41 @@ WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a) } #endif +WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, + const unsigned char **der, + long length) +{ + const unsigned char *d; + long len; + int tag, class; + WOLFSSL_ASN1_OBJECT* ret = NULL; + + WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT"); + + if (!der || !*der || length <= 0) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + d = *der; + + if (wolfSSL_ASN1_get_object(&d, &len, &tag, &class, length) & 0x80) { + WOLFSSL_MSG("wolfSSL_ASN1_get_object error"); + return NULL; + } + /* d now points to value */ + + if (tag != ASN_OBJECT_ID) { + WOLFSSL_MSG("Not an ASN object"); + return NULL; + } + + ret = wolfSSL_c2i_ASN1_OBJECT(a, &d, len); + if (ret) + *der = d; + return ret; +} + /** * Parse an ASN1 encoded input and output information about the parsed object * @param in ASN1 encoded data. *in is moved to the value of the ASN1 object @@ -26066,20 +26098,40 @@ int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, return ret; } -#ifndef NO_WOLFSSL_STUB WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, const unsigned char **pp, long len) { - (void)a; - (void)pp; - (void)len; + WOLFSSL_ASN1_OBJECT* ret = NULL; WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT"); - WOLFSSL_STUB("c2i_ASN1_OBJECT"); - return NULL; + if (!pp || !*pp || len <= 0) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + if (!(ret = wolfSSL_ASN1_OBJECT_new())) { + WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error"); + return NULL; + } + + ret->obj = (const unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1); + if (!ret->obj) { + WOLFSSL_MSG("error allocating asn data memory"); + wolfSSL_ASN1_OBJECT_free(ret); + return NULL; + } + + XMEMCPY((byte*)ret->obj, *pp, len); + ret->objSz = len; + ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; + + *pp += len; + + if (a) + *a = ret; + return ret; } -#endif #ifndef NO_BIO /* Return number of bytes written to BIO on success. 0 on failure. */ @@ -48362,8 +48414,10 @@ PKCS7* wolfSSL_PKCS7_new(void) ret = wc_PKCS7_Init(&pkcs7->pkcs7, NULL, INVALID_DEVID); } - if (ret != 0 && pkcs7 != NULL) + if (ret != 0 && pkcs7 != NULL) { XFREE(pkcs7, NULL, DYNAMIC_TYPE_PKCS7); + pkcs7 = NULL; + } return (PKCS7*)pkcs7; } @@ -48398,6 +48452,8 @@ void wolfSSL_PKCS7_free(PKCS7* pkcs7) if (p7->data != NULL) XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7); wc_PKCS7_Free(&p7->pkcs7); + if (p7->certs) + wolfSSL_sk_free(p7->certs); XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7); } } @@ -48549,6 +48605,11 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, #endif /* !NO_BIO */ +WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* p7) +{ + +} + WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs, int flags) { diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 7c6a52824..ea6f7e294 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -33,6 +33,7 @@ #define ASN1_STRING_free wolfSSL_ASN1_STRING_free #define ASN1_get_object wolfSSL_ASN1_get_object +#define d2i_ASN1_OBJECT wolfSSL_d2i_ASN1_OBJECT #define c2i_ASN1_OBJECT wolfSSL_c2i_ASN1_OBJECT #define V_ASN1_INTEGER 0x02 diff --git a/wolfssl/openssl/pkcs7.h b/wolfssl/openssl/pkcs7.h index 368cfb3d5..ad096858a 100644 --- a/wolfssl/openssl/pkcs7.h +++ b/wolfssl/openssl/pkcs7.h @@ -43,6 +43,7 @@ typedef struct WOLFSSL_PKCS7 PKCS7 pkcs7; unsigned char* data; int len; + WOLFSSL_STACK* certs; } WOLFSSL_PKCS7; @@ -57,6 +58,7 @@ WOLFSSL_API int wolfSSL_PKCS7_verify(PKCS7* p7, WOLFSSL_STACK* certs, WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags); WOLFSSL_API int wolfSSL_PKCS7_encode_certs(PKCS7* p7, WOLFSSL_STACK* certs, WOLFSSL_BIO* out); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* p7); WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* p7, WOLFSSL_STACK* certs, int flags); WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2bda06002..e66ff85bf 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3942,6 +3942,9 @@ WOLFSSL_API int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, con WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key); WOLFSSL_API int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key); WOLFSSL_API int i2t_ASN1_OBJECT(char *buf, int buf_len, WOLFSSL_ASN1_OBJECT *a); +WOLFSSL_API WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, + const unsigned char **der, + long length); WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp, WOLFSSL_ASN1_OBJECT *a); WOLFSSL_API int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp); WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength)); From b52e11d3d4c1a638787f03c80f5525f26554a536 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 8 Jul 2020 20:14:27 +0200 Subject: [PATCH 06/53] Implement/stub the following: - X509_get0_extensions - X509_to_X509_REQ - i2d_X509_REQ_bio - X509v3_get_ext_count - i2d_PKCS7_bio Additional changes: - Added a wc_PKCS7_VerifySignedData call to wolfSSL_d2i_PKCS7_bio to populate the PKCS7 struct with parsed values - wc_PKCS7_VerifySignedData_ex -> wc_PKCS7_VerifySignedData --- configure.ac | 2 + src/internal.c | 3 + src/ssl.c | 143 +++++++++++++++++++++++++++++++++------ wolfssl/internal.h | 1 + wolfssl/openssl/pkcs7.h | 4 +- wolfssl/openssl/ssl.h | 3 + wolfssl/openssl/x509v3.h | 7 +- wolfssl/ssl.h | 5 +- 8 files changed, 144 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 298b4be1b..53c62b0cb 100644 --- a/configure.ac +++ b/configure.ac @@ -4250,6 +4250,8 @@ AC_ARG_ENABLE([libest], if test "$ENABLED_LIBEST" = "yes" then + AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA" + # Requires opensslextra and opensslall if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" then diff --git a/src/internal.c b/src/internal.c index c600c7b9d..654080f5d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3432,6 +3432,9 @@ void FreeX509(WOLFSSL_X509* x509) if (x509->ext_sk != NULL) { wolfSSL_sk_X509_EXTENSION_free(x509->ext_sk); } + if (x509->ext_sk_full != NULL) { + wolfSSL_sk_X509_EXTENSION_free(x509->ext_sk_full); + } #endif /* OPENSSL_ALL || WOLFSSL_QT */ #ifdef OPENSSL_EXTRA /* Free serialNumber that was set by wolfSSL_X509_get_serialNumber */ diff --git a/src/ssl.c b/src/ssl.c index 549ffcff9..d20900388 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8224,6 +8224,44 @@ int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos, return WOLFSSL_SUCCESS; } +/** + * @param x Certificate to extract extensions from + * @return STACK_OF(X509_EXTENSION)* + */ +const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x) +{ + int numOfExt, i; + WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x; + WOLFSSL_STACK* tmp; + WOLFSSL_ENTER("wolfSSL_X509_get0_extensions"); + + if (!x509) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + numOfExt = wolfSSL_X509_get_ext_count(x509); + + if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) { + wolfSSL_sk_free(x509->ext_sk_full); + x509->ext_sk_full = NULL; + /* Save x509->ext_sk */ + tmp = x509->ext_sk; + x509->ext_sk = NULL; + + for (i = 0; i < numOfExt; i++) { + /* Build the extension stack */ + (void)wolfSSL_X509_set_ext(x509, i); + } + + /* Restore */ + x509->ext_sk_full = x509->ext_sk; + x509->ext_sk = tmp; + } + + return x509->ext_sk_full; +} + /* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509. * * x509 : The X509 structure to look for the extension. @@ -27513,7 +27551,7 @@ void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time) #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) -int wolfSSL_sk_num(WOLFSSL_STACK* sk) +int wolfSSL_sk_num(const WOLFSSL_STACK* sk) { WOLFSSL_ENTER("wolfSSL_sk_num"); if (sk == NULL) @@ -48467,6 +48505,8 @@ PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len) WOLFSSL_PKCS7* pkcs7 = NULL; word32 idx = 0; + WOLFSSL_ENTER("wolfSSL_d2i_PKCS7"); + if (in == NULL) return NULL; @@ -48498,6 +48538,8 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) { WOLFSSL_PKCS7* pkcs7; + WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_bio"); + if (bio == NULL) return NULL; @@ -48516,11 +48558,39 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) return NULL; } + if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len) != 0) { + return NULL; + } + if (p7 != NULL) *p7 = (PKCS7*)pkcs7; return (PKCS7*)pkcs7; } +int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) +{ + byte output[4096]; + int len; + WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio"); + + if (!bio || !p7) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if ((len = wc_PKCS7_EncodeSignedData(p7, output, sizeof(output))) < 0) { + WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(bio, output, len) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags) @@ -48530,6 +48600,8 @@ int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, int memSz = 0; WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7; + WOLFSSL_ENTER("wolfSSL_PKCS7_verify"); + if (pkcs7 == NULL) return WOLFSSL_FAILURE; @@ -48548,8 +48620,7 @@ int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, */ (void)store; - ret = wc_PKCS7_VerifySignedData_ex(&p7->pkcs7, NULL, 0, p7->data, p7->len, - NULL, 0); + ret = wc_PKCS7_VerifySignedData(&p7->pkcs7, p7->data, p7->len); if (ret != 0) return WOLFSSL_FAILURE; @@ -48567,8 +48638,6 @@ int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, WOLFSSL_BIO* out) { - byte output[4096]; - int len; PKCS7* p7; WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs"); @@ -48590,24 +48659,51 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, certs = certs->next; } - if ((len = wc_PKCS7_EncodeSignedData(p7, output, sizeof(output))) < 0) { - WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); - return WOLFSSL_FAILURE; - } - - if (wolfSSL_BIO_write(out, output, len) <= 0) { - WOLFSSL_MSG("wolfSSL_BIO_write error"); - return WOLFSSL_FAILURE; - } - - return WOLFSSL_SUCCESS; + return wolfSSL_i2d_PKCS7_bio(out, p7); } - #endif /* !NO_BIO */ -WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* p7) +WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) { + int i; + WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7; + WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL; + WOLFSSL_ENTER("wolfSSL_PKCS7_to_stack"); + + if (!p7) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + ret = wolfSSL_sk_X509_new(); + + for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) { + WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i], p7->pkcs7.certSz[i]); + if (x509) { + if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) { + wolfSSL_X509_free(x509); + WOLFSSL_MSG("wolfSSL_sk_X509_push error"); + goto error; + } + } + else { + WOLFSSL_MSG("wolfSSL_X509_d2i error"); + goto error; + } + } + + /* Save stack to free later */ + if (p7->certs) + wolfSSL_sk_free(p7->certs); + p7->certs = ret; + + return ret; +error: + if (ret) { + wolfSSL_sk_free(ret); + } + return NULL; } WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs, @@ -49385,7 +49481,7 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, { (void)req; (void)ext; - return WOLFSSL_FATAL_ERROR; + return WOLFSSL_FAILURE; } int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, @@ -49404,6 +49500,15 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, } #endif +WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, + WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md) +{ + WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ"); + (void)pkey; + (void)md; + return wolfSSL_X509_dup(x); +} + int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req, WOLFSSL_X509_NAME *name) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index aea8a6478..8d1bda9e4 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3685,6 +3685,7 @@ struct WOLFSSL_X509 { #endif /* (WOLFSSL_SEP || WOLFSSL_QT) && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) WOLFSSL_STACK* ext_sk; /* Store X509_EXTENSIONS from wolfSSL_X509_get_ext */ + WOLFSSL_STACK* ext_sk_full; /* Store X509_EXTENSIONS from wolfSSL_X509_get0_extensions */ WOLFSSL_STACK* ext_d2i;/* Store d2i extensions from wolfSSL_X509_get_ext_d2i */ #endif /* WOLFSSL_QT || OPENSSL_ALL */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) diff --git a/wolfssl/openssl/pkcs7.h b/wolfssl/openssl/pkcs7.h index ad096858a..ce444d51d 100644 --- a/wolfssl/openssl/pkcs7.h +++ b/wolfssl/openssl/pkcs7.h @@ -54,11 +54,12 @@ WOLFSSL_API void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7); WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len); WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7); +WOLFSSL_API int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7); WOLFSSL_API int wolfSSL_PKCS7_verify(PKCS7* p7, WOLFSSL_STACK* certs, WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags); WOLFSSL_API int wolfSSL_PKCS7_encode_certs(PKCS7* p7, WOLFSSL_STACK* certs, WOLFSSL_BIO* out); -WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* p7); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7); WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* p7, WOLFSSL_STACK* certs, int flags); WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7); @@ -69,6 +70,7 @@ WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7); #define PKCS7_SIGNED_free wolfSSL_PKCS7_SIGNED_free #define d2i_PKCS7 wolfSSL_d2i_PKCS7 #define d2i_PKCS7_bio wolfSSL_d2i_PKCS7_bio +#define i2d_PKCS7_bio wolfSSL_i2d_PKCS7_bio #define PKCS7_verify wolfSSL_PKCS7_verify #define PKCS7_get0_signers wolfSSL_PKCS7_get0_signers #define PEM_write_bio_PKCS7 wolfSSL_PEM_write_bio_PKCS7 diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 344552b19..35e148a30 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -358,6 +358,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define DSA_bits wolfSSL_DSA_bits #define i2d_X509_bio wolfSSL_i2d_X509_bio +#define i2d_X509_REQ_bio wolfSSL_i2d_X509_bio #define d2i_X509_bio wolfSSL_d2i_X509_bio #define d2i_X509_REQ_bio wolfSSL_d2i_X509_bio #define d2i_X509_fp wolfSSL_d2i_X509_fp @@ -381,6 +382,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_sign_ctx wolfSSL_X509_REQ_sign_ctx #define X509_REQ_add_extensions wolfSSL_X509_REQ_add_extensions #define X509_REQ_add1_attr_by_NID wolfSSL_X509_REQ_add1_attr_by_NID +#define X509_to_X509_REQ wolfSSL_X509_to_X509_REQ #define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name #define X509_REQ_set_pubkey wolfSSL_X509_REQ_set_pubkey #define PEM_write_bio_X509_REQ wolfSSL_PEM_write_bio_X509_REQ @@ -393,6 +395,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_get_ext_count wolfSSL_X509_get_ext_count #define X509_get_ext_d2i wolfSSL_X509_get_ext_d2i #define X509V3_EXT_i2d wolfSSL_X509V3_EXT_i2d +#define X509_get0_extensions wolfSSL_X509_get0_extensions #define X509_get_ext wolfSSL_X509_get_ext #define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID #define X509_get_issuer_name wolfSSL_X509_get_issuer_name diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index 65d8037e7..cf4691a4d 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -109,9 +109,10 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, #define X509V3_EXT_d2i wolfSSL_X509V3_EXT_d2i #define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING #define X509V3_EXT_print wolfSSL_X509V3_EXT_print -#define X509V3_EXT_conf_nid wolfSSL_X509V3_EXT_conf_nid -#define X509V3_set_ctx wolfSSL_X509V3_set_ctx -#define X509V3_set_ctx_nodb wolfSSL_X509V3_set_ctx_nodb +#define X509V3_EXT_conf_nid wolfSSL_X509V3_EXT_conf_nid +#define X509V3_set_ctx wolfSSL_X509V3_set_ctx +#define X509V3_set_ctx_nodb wolfSSL_X509V3_set_ctx_nodb +#define X509v3_get_ext_count wolfSSL_sk_num #ifdef __cplusplus } diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index e66ff85bf..fa13d15b4 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2082,7 +2082,7 @@ WOLFSSL_API int wolfSSL_ASN1_TIME_diff(int *pday, int *psec, WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t); #endif -WOLFSSL_API int wolfSSL_sk_num(WOLFSSL_STACK* sk); +WOLFSSL_API int wolfSSL_sk_num(const WOLFSSL_STACK* sk); WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i); #if (defined(HAVE_EX_DATA) || defined(FORTRESS)) && \ @@ -3398,6 +3398,7 @@ WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx, #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) WOLFSSL_API int wolfSSL_X509_cmp(const WOLFSSL_X509* a, const WOLFSSL_X509* b); +WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x, int loc); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x, int loc); WOLFSSL_API int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex); @@ -3560,6 +3561,8 @@ WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, int nid, int type, const unsigned char *bytes, int len); +WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, + WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md); #endif From 728f4ce892d66ffa6d0ad8a155410329df39d17c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 9 Jul 2020 17:09:24 +0200 Subject: [PATCH 07/53] Implement/stub: - wc_DhKeyCopy - SSL_CTX_set_srp_strength - SSL_get_srp_username - X509_REQ_get_attr_by_NID - X509_REQ_get_attr - X509_ATTRIBUTE - wolfSSL_DH_dup Add srp.h file with SRP_MINIMAL_N --- configure.ac | 6 ++++ src/ssl.c | 72 ++++++++++++++++++++++++++++++++++++-- wolfcrypt/src/dh.c | 14 ++++++++ wolfssl/openssl/asn1.h | 6 ++++ wolfssl/openssl/cms.h | 6 ++-- wolfssl/openssl/dh.h | 1 + wolfssl/openssl/include.am | 1 + wolfssl/openssl/srp.h | 29 +++++++++++++++ wolfssl/openssl/ssl.h | 10 ++++-- wolfssl/ssl.h | 41 ++++++++++++++-------- wolfssl/wolfcrypt/dh.h | 5 +++ 11 files changed, 170 insertions(+), 21 deletions(-) create mode 100644 wolfssl/openssl/srp.h diff --git a/configure.ac b/configure.ac index 53c62b0cb..8b51437d9 100644 --- a/configure.ac +++ b/configure.ac @@ -4291,6 +4291,12 @@ then ENABLED_CRL="yes" AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL" fi + + if test "x$ENABLED_SRP" = "xno" + then + ENABLED_SRP="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFCRYPT_HAVE_SRP" + fi fi # MD4 diff --git a/src/ssl.c b/src/ssl.c index d20900388..9bded32b5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15078,6 +15078,34 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } return WOLFSSL_SUCCESS; } + + /** + * The modulus passed to wc_SrpSetParams in ssl.c is constant so check + * that the requested strength is less than or equal to the size of the + * static modulus size. + * @param ctx Not used + * @param strength Minimum number of bits for the modulus + * @return 1 if strength is less than or equal to static modulus + * 0 if strength is greater than static modulus + */ + int wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength) + { + (void)ctx; + WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength"); + if (strength > (int)(sizeof(srp_N)*8)) { + WOLFSSL_MSG("Bad Parameter"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; + } + + char* wolfSSL_get_srp_username(WOLFSSL *ssl) + { + if (ssl && ssl->ctx && ssl->ctx->srp) { + return (char*) ssl->ctx->srp->user; + } + return NULL; + } #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */ /* keyblock size in bytes or -1 */ @@ -29559,7 +29587,7 @@ WOLFSSL_DH* wolfSSL_DH_new(void) WOLFSSL_DH* external; DhKey* key; - WOLFSSL_MSG("wolfSSL_DH_new"); + WOLFSSL_ENTER("wolfSSL_DH_new"); key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH); if (key == NULL) { @@ -29590,7 +29618,7 @@ WOLFSSL_DH* wolfSSL_DH_new(void) void wolfSSL_DH_free(WOLFSSL_DH* dh) { - WOLFSSL_MSG("wolfSSL_DH_free"); + WOLFSSL_ENTER("wolfSSL_DH_free"); if (dh) { if (dh->internal) { @@ -29609,6 +29637,25 @@ void wolfSSL_DH_free(WOLFSSL_DH* dh) } } +WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) +{ + WOLFSSL_DH* ret = NULL; + DhKey* key; + + WOLFSSL_ENTER("wolfSSL_DH_dup"); + + if (!dh) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + if (!(ret = wolfSSL_DH_new())) { + return NULL; + } + + return ret; +} + int SetDhInternal(WOLFSSL_DH* dh) { int ret = WOLFSSL_FATAL_ERROR; @@ -49498,6 +49545,27 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, (void)len; return WOLFSSL_FAILURE; } + +int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, + int nid, int lastpos) +{ + WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID"); + WOLFSSL_STUB("wolfSSL_X509_REQ_get_attr_by_NID"); + (void)req; + (void)nid; + (void)lastpos; + return WOLFSSL_FATAL_ERROR; +} + +WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( + const WOLFSSL_X509 *req, int loc) +{ + WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr"); + WOLFSSL_STUB("wolfSSL_X509_REQ_get_attr"); + (void)req; + (void)loc; + return NULL; +} #endif WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index e19d5a49b..654290b9e 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -2079,6 +2079,20 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, } #ifdef WOLFSSL_DH_EXTRA +WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst) +{ + if (!src || !dst || src == dst) { + WOLFSSL_MSG("Parameters not provided or are the same"); + return BAD_FUNC_ARG; + } + + if (mp_copy(, mpi) != MP_OKAY) { + WOLFSSL_MSG("mp_copy error"); + return WOLFSSL_FATAL_ERROR; + } + +} + /* Sets private and public key in DhKey if both are available, otherwise sets either private or public key, depending on which is available. */ int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz, diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index ea6f7e294..3f11e4f0c 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -70,13 +70,19 @@ #define ASN1_TIME_diff wolfSSL_ASN1_TIME_diff #define ASN1_TIME_set wolfSSL_ASN1_TIME_set +#define V_ASN1_EOC 0 #define V_ASN1_OBJECT 6 +#define V_ASN1_UTF8STRING 12 #define V_ASN1_SEQUENCE 16 #define V_ASN1_SET 17 +#define V_ASN1_IA5STRING 22 #define V_ASN1_UTCTIME 23 #define V_ASN1_GENERALIZEDTIME 24 #define V_ASN1_PRINTABLESTRING 19 + +#define V_ASN1_CONSTRUCTED 0x20 + #define ASN1_STRING_FLAG_BITS_LEFT 0x008 #define ASN1_STRING_FLAG_NDEF 0x010 #define ASN1_STRING_FLAG_CONT 0x020 diff --git a/wolfssl/openssl/cms.h b/wolfssl/openssl/cms.h index d698c7bca..e86a21f0a 100644 --- a/wolfssl/openssl/cms.h +++ b/wolfssl/openssl/cms.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifndef WOLFSSL_OPENSSL_CMS_H_ -#define WOLFSSL_OPENSSL_CMS_H_ +#ifndef WOLFSSL_CMS_H_ +#define WOLFSSL_CMS_H_ -#endif /* WOLFSSL_OPENSSL_CMS_H_ */ +#endif /* WOLFSSL_CMS_H_ */ diff --git a/wolfssl/openssl/dh.h b/wolfssl/openssl/dh.h index ff021ed8b..ac4d7e1a0 100644 --- a/wolfssl/openssl/dh.h +++ b/wolfssl/openssl/dh.h @@ -58,6 +58,7 @@ WOLFSSL_API WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, WOLFSSL_API int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out); WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_new(void); WOLFSSL_API void wolfSSL_DH_free(WOLFSSL_DH*); +WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh); WOLFSSL_API int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes); WOLFSSL_API int wolfSSL_DH_size(WOLFSSL_DH*); diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index f3b432df6..716b1d0ea 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -42,6 +42,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/rsa.h \ wolfssl/openssl/sha.h \ wolfssl/openssl/sha3.h \ + wolfssl/openssl/srp.h \ wolfssl/openssl/ssl23.h \ wolfssl/openssl/ssl.h \ wolfssl/openssl/stack.h \ diff --git a/wolfssl/openssl/srp.h b/wolfssl/openssl/srp.h new file mode 100644 index 000000000..7b5bd96b4 --- /dev/null +++ b/wolfssl/openssl/srp.h @@ -0,0 +1,29 @@ +/* srp.h + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_SRP_H_ +#define WOLFSSL_SRP_H_ + +#include + +#define SRP_MINIMAL_N SRP_MODULUS_MIN_BITS + +#endif /* WOLFSSL_SRP_H_ */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 35e148a30..8e3a08a3d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -106,6 +106,7 @@ typedef WOLFSSL_ASN1_INTEGER ASN1_INTEGER; typedef WOLFSSL_ASN1_OBJECT ASN1_OBJECT; typedef WOLFSSL_ASN1_STRING ASN1_STRING; typedef WOLFSSL_ASN1_TYPE ASN1_TYPE; +typedef WOLFSSL_X509_ATTRIBUTE X509_ATTRIBUTE; typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value; typedef WOLFSSL_BUF_MEM BUF_MEM; @@ -382,6 +383,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_sign_ctx wolfSSL_X509_REQ_sign_ctx #define X509_REQ_add_extensions wolfSSL_X509_REQ_add_extensions #define X509_REQ_add1_attr_by_NID wolfSSL_X509_REQ_add1_attr_by_NID +#define X509_REQ_get_attr_by_NID wolfSSL_X509_REQ_get_attr_by_NID +#define X509_REQ_get_attr wolfSSL_X509_REQ_get_attr #define X509_to_X509_REQ wolfSSL_X509_to_X509_REQ #define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name #define X509_REQ_set_pubkey wolfSSL_X509_REQ_set_pubkey @@ -404,6 +407,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_get_subject_name wolfSSL_X509_get_subject_name #define X509_get_pubkey wolfSSL_X509_get_pubkey #define X509_get0_pubkey wolfSSL_X509_get_pubkey +#define X509_REQ_get_pubkey wolfSSL_X509_get_pubkey #define X509_get_notBefore wolfSSL_X509_get_notBefore #define X509_get0_notBefore wolfSSL_X509_get_notBefore #define X509_get_notAfter wolfSSL_X509_get_notAfter @@ -431,6 +435,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_print_ex wolfSSL_X509_print_ex #define X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string #define X509_verify_cert wolfSSL_X509_verify_cert +#define X509_verify wolfSSL_X509_verify +#define X509_REQ_verify wolfSSL_X509_verify #define X509_check_private_key wolfSSL_X509_check_private_key #define X509_check_ca wolfSSL_X509_check_ca #define X509_check_host wolfSSL_X509_check_host @@ -952,8 +958,6 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ERR_LIB_SSL 20 #define SSL_R_SHORT_READ 10 #define ERR_R_PEM_LIB 9 -#define V_ASN1_IA5STRING 22 -#define V_ASN1_UTF8STRING 12 #define SSL_CTRL_MODE 33 #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 @@ -1227,8 +1231,10 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_add_client_CA wolfSSL_CTX_add_client_CA #define SSL_CTX_set_srp_password wolfSSL_CTX_set_srp_password #define SSL_CTX_set_srp_username wolfSSL_CTX_set_srp_username +#define SSL_CTX_set_srp_strength wolfSSL_CTX_set_srp_strength #define SSL_get_SSL_CTX wolfSSL_get_SSL_CTX #define SSL_get0_param wolfSSL_get0_param +#define SSL_get_srp_username wolfSSL_get_srp_username #define ERR_NUM_ERRORS 16 #define SN_pkcs9_emailAddress "Email" diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index fa13d15b4..570ffc1eb 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -102,6 +102,19 @@ extern "C" { #endif +/* for now LHASH is not implemented */ +typedef int WOLFSSL_LHASH; +#ifndef WOLF_LHASH_OF + #define WOLF_LHASH_OF(x) WOLFSSL_LHASH +#endif + +#ifndef WOLF_STACK_OF + #define WOLF_STACK_OF(x) WOLFSSL_STACK +#endif +#ifndef DECLARE_STACK_OF + #define DECLARE_STACK_OF(x) WOLF_STACK_OF(x); +#endif + #ifndef WOLFSSL_WOLFSSL_TYPE_DEFINED #define WOLFSSL_WOLFSSL_TYPE_DEFINED typedef struct WOLFSSL WOLFSSL; @@ -189,6 +202,7 @@ typedef struct WOLFSSL_DH WOLFSSL_DH; #endif typedef struct WOLFSSL_ASN1_BIT_STRING WOLFSSL_ASN1_BIT_STRING; typedef struct WOLFSSL_ASN1_TYPE WOLFSSL_ASN1_TYPE; +typedef struct WOLFSSL_X509_ATTRIBUTE WOLFSSL_X509_ATTRIBUTE; typedef struct WOLFSSL_GENERAL_NAME WOLFSSL_GENERAL_NAME; typedef struct WOLFSSL_AUTHORITY_KEYID WOLFSSL_AUTHORITY_KEYID; @@ -318,6 +332,11 @@ struct WOLFSSL_ASN1_TYPE { } value; }; +struct WOLFSSL_X509_ATTRIBUTE { + WOLFSSL_ASN1_OBJECT *object; + WOLF_STACK_OF(WOLFSSL_ASN1_TYPE) *set; +}; + struct WOLFSSL_EVP_PKEY { void* heap; int type; /* openssh dereference */ @@ -1088,20 +1107,6 @@ WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long); /* extras */ - -/* for now LHASH is not implemented */ -typedef int WOLFSSL_LHASH; -#ifndef WOLF_LHASH_OF - #define WOLF_LHASH_OF(x) WOLFSSL_LHASH -#endif - -#ifndef WOLF_STACK_OF - #define WOLF_STACK_OF(x) WOLFSSL_STACK -#endif -#ifndef DECLARE_STACK_OF - #define DECLARE_STACK_OF(x) WOLF_STACK_OF(x); -#endif - WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap); WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_sk_free_node(WOLFSSL_STACK* in); @@ -1600,6 +1605,9 @@ WOLFSSL_API long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg( WOLFSSL_API int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX*, WOLFSSL_X509*); WOLFSSL_API int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX*, char*); WOLFSSL_API int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX*, char*); +WOLFSSL_API int wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength); + +WOLFSSL_API char* wolfSSL_get_srp_username(WOLFSSL *ssl); WOLFSSL_API long wolfSSL_set_options(WOLFSSL *s, long op); WOLFSSL_API long wolfSSL_get_options(const WOLFSSL *s); @@ -3561,6 +3569,11 @@ WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, int nid, int type, const unsigned char *bytes, int len); +WOLFSSL_API int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, + int nid, int lastpos); +WOLFSSL_API WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( + const WOLFSSL_X509 *req, int loc); + WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md); #endif diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index a92d7b3ce..00b1c6267 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -123,6 +123,11 @@ WOLFSSL_API int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz, byte* pub, word32* pPubSz); #endif /* WOLFSSL_DH_EXTRA */ +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) +WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst); +WOLFSSL_LOCAL int wc_DhSetFullKeys(DhKey* key,const byte* priv_key,word32 privSz, + const byte* pub_key, word32 pubSz); +#endif WOLFSSL_API int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz, int trusted, WC_RNG* rng); From 85b1196b088f2480deeb0b0b60efe654080efd6f Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 10 Jul 2020 21:03:00 +0200 Subject: [PATCH 08/53] Implement/stub: - X509_REQ_print_fp - X509_print_fp - DHparams_dup --- configure.ac | 19 ++++++++++++++++ src/ssl.c | 52 ++++++++++++++++++++++++++++++++++++++++++- wolfcrypt/src/dh.c | 31 ++++++++++++++++++++++++-- wolfssl/openssl/ssl.h | 3 +++ wolfssl/ssl.h | 1 + 5 files changed, 103 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8b51437d9..19ffd6bd7 100644 --- a/configure.ac +++ b/configure.ac @@ -4284,6 +4284,11 @@ then ENABLED_CERTREQ="yes" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_REQ" fi + if test "x$ENABLED_CERTEXT" = "xno" + then + ENABLED_CERTEXT="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_EXT" + fi # Requires CRL if test "x$ENABLED_CRL" = "xno" @@ -4297,6 +4302,20 @@ then ENABLED_SRP="yes" AM_CFLAGS="$AM_CFLAGS -DWOLFCRYPT_HAVE_SRP" fi + + # Enable prereqs if not already enabled + if test "x$ENABLED_KEYGEN" = "xno" + then + ENABLED_KEYGEN="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KEY_GEN" + fi + + # Requires sessioncerts make sure on + if test "x$ENABLED_SESSIONCERTS" = "xno" + then + ENABLED_SESSIONCERTS="yes" + AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS" + fi fi # MD4 diff --git a/src/ssl.c b/src/ssl.c index 9bded32b5..65fe18772 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -21918,6 +21918,35 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return wolfSSL_X509_print_ex(bio, x509, 0, 0); } + int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509) + { + WOLFSSL_BIO* bio; + int ret; + + WOLFSSL_ENTER("wolfSSL_X509_print_fp"); + + if (!fp || !x509) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) { + WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_BIO_set_fp error"); + return WOLFSSL_FAILURE; + } + + ret = wolfSSL_X509_print(bio, x509); + + wolfSSL_BIO_free(bio); + + return ret; + } + #endif /* XSNPRINTF */ #endif /* !NO_BIO */ @@ -29640,7 +29669,6 @@ void wolfSSL_DH_free(WOLFSSL_DH* dh) WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) { WOLFSSL_DH* ret = NULL; - DhKey* key; WOLFSSL_ENTER("wolfSSL_DH_dup"); @@ -29649,7 +29677,26 @@ WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) return NULL; } + if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS){ + WOLFSSL_MSG("Bad DH set internal"); + return NULL; + } + if (!(ret = wolfSSL_DH_new())) { + WOLFSSL_MSG("wolfSSL_DH_new error"); + return NULL; + } + + if (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) != MP_OKAY) { + WOLFSSL_MSG("wc_DhKeyCopy error"); + wolfSSL_DH_free(ret); + return NULL; + } + ret->inSet = 1; + + if (SetDhExternal(ret) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetDhExternal error"); + wolfSSL_DH_free(ret); return NULL; } @@ -48723,6 +48770,9 @@ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) return WOLFSSL_FAILURE; } + if (p7->certs) + return p7->certs; + ret = wolfSSL_sk_X509_new(); for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) { diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 654290b9e..f5e89aa25 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -2081,16 +2081,43 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, #ifdef WOLFSSL_DH_EXTRA WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst) { + int ret; + if (!src || !dst || src == dst) { WOLFSSL_MSG("Parameters not provided or are the same"); return BAD_FUNC_ARG; } - if (mp_copy(, mpi) != MP_OKAY) { + if ((ret = mp_copy(&src->p, &dst->p)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); - return WOLFSSL_FATAL_ERROR; + return ret; } + if ((ret = mp_copy(&src->g, &dst->g)) != MP_OKAY) { + WOLFSSL_MSG("mp_copy error"); + return ret; + } + + if ((ret = mp_copy(&src->q, &dst->q)) != MP_OKAY) { + WOLFSSL_MSG("mp_copy error"); + return ret; + } + +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) + if ((ret = mp_copy(&src->pub, &dst->pub)) != MP_OKAY) { + WOLFSSL_MSG("mp_copy error"); + return ret; + } + + if ((ret = mp_copy(&src->priv, &dst->priv)) != MP_OKAY) { + WOLFSSL_MSG("mp_copy error"); + return ret; + } +#endif + + dst->heap = src->heap; + + return MP_OKAY; } /* Sets private and public key in DhKey if both are available, otherwise sets diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 8e3a08a3d..2181d99e0 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -433,6 +433,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_sign wolfSSL_X509_sign #define X509_print wolfSSL_X509_print #define X509_print_ex wolfSSL_X509_print_ex +#define X509_print_fp wolfSSL_X509_print_fp +#define X509_REQ_print_fp wolfSSL_X509_print_fp #define X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string #define X509_verify_cert wolfSSL_X509_verify_cert #define X509_verify wolfSSL_X509_verify @@ -931,6 +933,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define sk_X509_NAME_find wolfSSL_sk_X509_NAME_find +#define DHparams_dup wolfSSL_DH_dup #define PEM_read_bio_DHparams wolfSSL_PEM_read_bio_DHparams #define PEM_read_bio_DSAparams wolfSSL_PEM_read_bio_DSAparams diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 570ffc1eb..a57353eae 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1352,6 +1352,7 @@ WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset #endif WOLFSSL_API int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, unsigned long nmflags, unsigned long cflag); +WOLFSSL_API int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509); WOLFSSL_API int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, char*, int); From a7ec58003e644611916c502eba04006c1c6e25b2 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 Jul 2020 17:06:28 +0200 Subject: [PATCH 09/53] PKCS7 changes - Allow PKCS7_EncodeSigned to be called with a zero content length - wc_HashUpdate now doesn't error out on zero length data - First cert in wolfSSL_PKCS7_encode_certs is treated as main cert and the PKCS7 struct is initialized with it - wolfSSL_BIO_get_mem_data returns the buffer from the last bio in chain --- src/bio.c | 4 ++++ src/ssl.c | 48 +++++++++++++++++++++++++++++++++++++- wolfcrypt/src/hash.c | 2 +- wolfcrypt/src/pkcs7.c | 7 +++--- wolfssl/openssl/include.am | 1 + wolfssl/openssl/txt_db.h | 27 +++++++++++++++++++++ wolfssl/openssl/x509.h | 7 +++++- wolfssl/ssl.h | 6 ----- 8 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 wolfssl/openssl/txt_db.h diff --git a/src/bio.c b/src/bio.c index 02ac5b353..626384acd 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1684,6 +1684,10 @@ int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p) if (bio == NULL) return WOLFSSL_FATAL_ERROR; + /* Return pointer from last BIO in chain */ + while (bio->next) + bio = bio->next; + if (p) { *(byte**)p = (byte*)bio->ptr; } diff --git a/src/ssl.c b/src/ssl.c index 65fe18772..c349fbad3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -48732,7 +48732,10 @@ int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, WOLFSSL_BIO* out) { + int ret; PKCS7* p7; + WC_RNG rng; + byte cleanRng = 0; WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs"); @@ -48743,6 +48746,28 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, p7 = &((WOLFSSL_PKCS7*)pkcs7)->pkcs7; + if (p7->certList) { + WOLFSSL_MSG("wolfSSL_PKCS7_encode_certs called multiple times on same " + "struct"); + return WOLFSSL_FAILURE; + } + + if (certs) { + /* Save some of the values */ + int hashOID = p7->hashOID; + byte version = p7->version; + + if (wc_PKCS7_InitWithCert(p7, certs->data.x509->derCert->buffer, + certs->data.x509->derCert->length) != 0) { + WOLFSSL_MSG("wc_PKCS7_InitWithCert error"); + return WOLFSSL_FAILURE; + } + certs = certs->next; + + p7->hashOID = hashOID; + p7->version = version; + } + /* Add the certs to the PKCS7 struct */ while (certs) { if (wc_PKCS7_AddCertificate(p7, certs->data.x509->derCert->buffer, @@ -48753,7 +48778,28 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, certs = certs->next; } - return wolfSSL_i2d_PKCS7_bio(out, p7); + if (wc_PKCS7_SetSignerIdentifierType(p7, DEGENERATE_SID) != 0) { + WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error"); + return WOLFSSL_FAILURE; + } + + if (!p7->rng) { + if (wc_InitRng(&rng) != 0) { + WOLFSSL_MSG("wc_InitRng error"); + return WOLFSSL_FAILURE; + } + p7->rng = &rng; + cleanRng = 1; + } + + ret = wolfSSL_i2d_PKCS7_bio(out, p7); + + if (cleanRng) { + wc_FreeRng(&rng); + p7->rng = NULL; + } + + return ret; } #endif /* !NO_BIO */ diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index e5d619703..b02caaec2 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -625,7 +625,7 @@ int wc_HashUpdate(wc_HashAlg* hash, enum wc_HashType type, const byte* data, { int ret = HASH_TYPE_E; /* Default to hash type error */ - if (hash == NULL || data == NULL) + if (hash == NULL || (data == NULL && dataSz > 0)) return BAD_FUNC_ARG; switch (type) { diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 7dbd4aace..471961588 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1151,6 +1151,7 @@ int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* derCert, word32 derCertSz) DYNAMIC_TYPE_PKCS7); if (cert == NULL) return MEMORY_E; + XMEMSET(cert, 0, sizeof(Pkcs7Cert)); cert->der = derCert; cert->derSz = derCertSz; @@ -2268,8 +2269,8 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, byte signingTime[MAX_TIME_STRING_SZ]; - if (pkcs7 == NULL || pkcs7->contentSz == 0 || - pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 || + if (pkcs7 == NULL || (pkcs7->contentSz > 0 && pkcs7->content == NULL) || + pkcs7->hashOID == 0 || output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 || hashBuf == NULL) { return BAD_FUNC_ARG; @@ -2746,7 +2747,7 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) #endif /* other args checked in wc_PKCS7_EncodeSigned_ex */ - if (pkcs7 == NULL || pkcs7->contentSz == 0 || pkcs7->content == NULL) { + if (pkcs7 == NULL || (pkcs7->contentSz > 0 && pkcs7->content == NULL)) { return BAD_FUNC_ARG; } diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 716b1d0ea..8a1209429 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -47,6 +47,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/ssl.h \ wolfssl/openssl/stack.h \ wolfssl/openssl/tls1.h \ + wolfssl/openssl/txt_db.h \ wolfssl/openssl/ui.h \ wolfssl/openssl/x509.h \ wolfssl/openssl/x509_vfy.h \ diff --git a/wolfssl/openssl/txt_db.h b/wolfssl/openssl/txt_db.h new file mode 100644 index 000000000..4fb940026 --- /dev/null +++ b/wolfssl/openssl/txt_db.h @@ -0,0 +1,27 @@ +/* txt_db.h + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_TXT_DB_H_ +#define WOLFSSL_TXT_DB_H_ + + + +#endif /* WOLFSSL_TXT_DB_H_ */ diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index 349dd089c..dd98f3d30 100644 --- a/wolfssl/openssl/x509.h +++ b/wolfssl/openssl/x509.h @@ -24,4 +24,9 @@ #define X509_FLAG_NO_IDS (1UL << 12) #define XN_FLAG_FN_SN 0 -#define XN_FLAG_SEP_CPLUS_SPC 2 +#define XN_FLAG_ONELINE 0 +#define XN_FLAG_RFC2253 1 +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) +#define XN_FLAG_DN_REV (1 << 20) +#define XN_FLAG_SPC_EQ (1 << 23) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a57353eae..c6f72bb94 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1816,12 +1816,6 @@ enum { X509_R_CERT_ALREADY_IN_HASH_TABLE, - XN_FLAG_SPC_EQ = (1 << 23), - XN_FLAG_SEP_CPLUS_SPC = (2 << 16), - XN_FLAG_ONELINE = 0, - XN_FLAG_RFC2253 = 1, - XN_FLAG_DN_REV = (1 << 20), - CRYPTO_LOCK = 1, CRYPTO_NUM_LOCKS = 10, From 1a50d8e028663c3d997027993cfbf6d8110dfa8b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 15 Jul 2020 18:48:05 +0200 Subject: [PATCH 10/53] WIP - wolfSSL_BIO_ctrl_pending ignore BASE64 bio's as well now - Save the last Finished messages sent or received in the WOLFSSL struct - Implement wolfSSL_CTX_set_max_proto_version - wolfSSL_d2i_X509_bio now uses wolfSSL_BIO_read so that the entire chain is properly read from the BIO --- configure.ac | 2 +- src/bio.c | 8 +- src/internal.c | 16 ++++ src/ssl.c | 165 ++++++++++++++++++++++++++---------------- wolfssl/internal.h | 4 + wolfssl/openssl/ssl.h | 2 + wolfssl/ssl.h | 4 +- 7 files changed, 131 insertions(+), 70 deletions(-) diff --git a/configure.ac b/configure.ac index 19ffd6bd7..3d222f01b 100644 --- a/configure.ac +++ b/configure.ac @@ -4104,7 +4104,7 @@ then # Requires Secure Renegotiation if test "x$ENABLED_SECURE_RENEGOTIATION" = "xno" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_SECURE_RENEGOTIATION -DHAVE_SERVER_RENEGOTIATION_INFO" + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SECURE_RENEGOTIATION -DHAVE_SERVER_RENEGOTIATION_INFO" fi fi diff --git a/src/bio.c b/src/bio.c index 626384acd..9c1e0c712 100644 --- a/src/bio.c +++ b/src/bio.c @@ -940,11 +940,13 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) return 0; } - if (bio->type == WOLFSSL_BIO_MD) { - /* MD is a wrapper only get next bio */ + if (bio->type == WOLFSSL_BIO_MD || + bio->type == WOLFSSL_BIO_BASE64) { + /* these are wrappers only, get next bio */ while (bio->next != NULL) { bio = bio->next; - if (bio->type != WOLFSSL_BIO_MD) { + if (bio->type == WOLFSSL_BIO_MD || + bio->type == WOLFSSL_BIO_BASE64) { break; } } diff --git a/src/internal.c b/src/internal.c index 654080f5d..811a539ae 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12109,6 +12109,14 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, ssl->secure_renegotiation->verifySet = 1; } #endif +#ifdef OPENSSL_ALL + if (ssl->options.side == WOLFSSL_CLIENT_END) + XMEMCPY(ssl->serverFinished, + input + *inOutIdx, TLS_FINISHED_SZ); + else + XMEMCPY(ssl->clientFinished, + input + *inOutIdx, TLS_FINISHED_SZ); +#endif /* force input exhaustion at ProcessReply consuming padSz */ *inOutIdx += size + ssl->keys.padSz; @@ -16759,6 +16767,14 @@ int SendFinished(WOLFSSL* ssl) TLS_FINISHED_SZ); } #endif +#ifdef OPENSSL_ALL + if (ssl->options.side == WOLFSSL_CLIENT_END) + XMEMCPY(ssl->clientFinished, + hashes, TLS_FINISHED_SZ); + else + XMEMCPY(ssl->serverFinished, + hashes, TLS_FINISHED_SZ); +#endif #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { diff --git a/src/ssl.c b/src/ssl.c index c349fbad3..434612ec4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -9460,6 +9460,8 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, sk = NULL; } } + /* null so that it doesn't get pushed again after switch */ + gn = NULL; } } else { @@ -9729,18 +9731,21 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, goto err; } } - if (obj && wolfSSL_sk_ASN1_OBJECT_push(sk, obj) == WOLFSSL_SUCCESS) { - /* obj pushed successfully on stack */ + if (obj) { + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto " + "stack."); + goto err; + } } - else if (gn && wolfSSL_sk_GENERAL_NAME_push(sk, gn) == WOLFSSL_SUCCESS) { - /* gn pushed successfully on stack */ - } - else { - /* Nothing to push or push failed */ - WOLFSSL_MSG("Error pushing ASN1_OBJECT or GENERAL_NAME object onto stack " - "or nothing to push."); - goto err; + else if (gn) { + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing GENERAL_NAME object onto " + "stack."); + goto err; + } } + ret = sk; (void)idx; @@ -9755,7 +9760,7 @@ err: wolfSSL_GENERAL_NAME_free(gn); } if (sk) { - wolfSSL_sk_ASN1_OBJECT_free(sk); + wolfSSL_sk_free(sk); } return NULL; } @@ -15985,9 +15990,37 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) { WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version"); - /* supported only at compile-time only */ - (void)ctx; - (void)ver; + if (!ctx) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + switch (ver) { + case SSL2_VERSION: + WOLFSSL_MSG("wolfSSL does not support SSLv2"); + return WOLFSSL_FAILURE; + case SSL3_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1); + FALL_THROUGH; + case TLS1_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1); + FALL_THROUGH; + case TLS1_1_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2); + FALL_THROUGH; + case TLS1_2_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3); +#ifdef WOLFSSL_TLS13 + FALL_THROUGH; + case TLS1_3_VERSION: + /* Nothing to do here */ +#endif + break; + default: + WOLFSSL_MSG("Unrecognized protocol version"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; } @@ -19012,30 +19045,13 @@ void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name) #ifdef OPENSSL_EXTRA void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free"); if (gens == NULL) { return; } - /* parse through stack freeing each node */ - node = gens->next; - while (gens->num > 1) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - wolfSSL_ASN1_OBJECT_free(tmp->data.obj); - XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); - gens->num -= 1; - } - - /* free head of stack */ - if (gens->num == 1) { - wolfSSL_ASN1_OBJECT_free(gens->data.obj); - } - XFREE(gens, NULL, DYNAMIC_TYPE_ASN1); + wolfSSL_sk_free(gens); } #if defined(OPENSSL_ALL) @@ -20481,7 +20497,7 @@ WOLFSSL_ABI WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert) { WOLFSSL_ENTER("wolfSSL_X509_get_subject_name"); - if (cert && cert->subject.sz != 0) + if (cert) return &cert->subject; return NULL; } @@ -22825,9 +22841,8 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out) WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) { WOLFSSL_X509* localX509 = NULL; - unsigned char* mem = NULL; - int ret; - word32 size; + byte* mem = NULL; + int size; WOLFSSL_ENTER("wolfSSL_d2i_X509_bio"); @@ -22836,15 +22851,27 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) return NULL; } - ret = wolfSSL_BIO_get_mem_data(bio, &mem); - if (mem == NULL || ret <= 0) { - WOLFSSL_MSG("Failed to get data from bio struct"); + size = wolfSSL_BIO_pending(bio); + if (size == 0) { + WOLFSSL_MSG("wolfSSL_BIO_pending error. Possibly no pending data."); + return NULL; + } + + if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) { + WOLFSSL_MSG("malloc error"); + return NULL; + } + + if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) { + WOLFSSL_MSG("wolfSSL_BIO_read error"); + XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); return NULL; } - size = ret; localX509 = wolfSSL_X509_d2i(NULL, mem, size); if (localX509 == NULL) { + WOLFSSL_MSG("wolfSSL_X509_d2i error"); + XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); return NULL; } @@ -23358,7 +23385,6 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); - ctx->chain = sk; for (i = 0; i < c->count && i < MAX_CHAIN_DEPTH; i++) { WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i); @@ -23408,7 +23434,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } } #endif - + ctx->chain = sk; } #endif /* SESSION_CERTS */ @@ -23648,13 +23674,12 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, } -/* free's own cert chain holding and extra data */ +/* free's extra data */ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) { WOLFSSL_ENTER("X509_STORE_CTX_free"); if (ctx != NULL) { #ifdef OPENSSL_EXTRA - wolfSSL_sk_free(ctx->chain); if (ctx->param != NULL){ XFREE(ctx->param,NULL,DYNAMIC_TYPE_OPENSSL); ctx->param = NULL; @@ -26307,29 +26332,41 @@ int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp) } #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) -#ifndef NO_WOLFSSL_STUB -/*** TBD ***/ -WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count) +WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count) { - (void)s; - (void)buf; - (void)count; - WOLFSSL_STUB("SSL_get_finished"); - return WOLFSSL_FAILURE; -} -#endif + WOLFSSL_ENTER("SSL_get_finished"); -#ifndef NO_WOLFSSL_STUB -/*** TBD ***/ -WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count) -{ - (void)s; - (void)buf; - (void)count; - WOLFSSL_STUB("SSL_get_peer_finished"); - return WOLFSSL_FAILURE; + if (!ssl || !buf || count < TLS_FINISHED_SZ) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (ssl->options.side == WOLFSSL_SERVER_END) + XMEMCPY(buf, ssl->serverFinished, + TLS_FINISHED_SZ); + else + XMEMCPY(buf, ssl->clientFinished, + TLS_FINISHED_SZ); + return TLS_FINISHED_SZ; +} + +WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count) +{ + WOLFSSL_ENTER("SSL_get_peer_finished"); + + if (!ssl || !buf || count < TLS_FINISHED_SZ) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (ssl->options.side == WOLFSSL_CLIENT_END) + XMEMCPY(buf, ssl->serverFinished, + TLS_FINISHED_SZ); + else + XMEMCPY(buf, ssl->clientFinished, + TLS_FINISHED_SZ); + return TLS_FINISHED_SZ; } -#endif #endif /* WOLFSSL_HAPROXY */ #ifndef NO_WOLFSSL_STUB diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 8d1bda9e4..2f2c98bf4 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4291,6 +4291,10 @@ struct WOLFSSL { #ifdef WOLFSSL_STATIC_EPHEMERAL StaticKeyExchangeInfo_t staticKE; #endif +#ifdef OPENSSL_ALL + byte clientFinished[TLS_FINISHED_SZ]; + byte serverFinished[TLS_FINISHED_SZ]; +#endif }; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 2181d99e0..c98f12b21 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -308,6 +308,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_set_ex_data wolfSSL_set_ex_data #define SSL_get_shutdown wolfSSL_get_shutdown +#define SSL_get_finished wolfSSL_get_finished +#define SSL_get_peer_finished wolfSSL_get_peer_finished #define SSL_set_rfd wolfSSL_set_rfd #define SSL_set_wfd wolfSSL_set_wfd #define SSL_set_shutdown wolfSSL_set_shutdown diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c6f72bb94..a08a79644 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3933,8 +3933,8 @@ WOLFSSL_API int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc, #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLFSSL_API const unsigned char *SSL_SESSION_get0_id_context( const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length); -WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count); -WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count); +WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count); +WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count); #endif WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len); From 4aa30d0bdeeb81c5dbff090b257bab11658631f0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 20 Jul 2020 21:23:16 +0200 Subject: [PATCH 11/53] Add CSR parsing capabilities to ParseCertRelative and wc_GetPubX509 - wolfSSL_BIO_get_mem_data now returns the last memory BIO in the chain - Change wolfSSL_BIO_pending calls to wolfSSL_BIO_get_len calls to get accurate length depending on BIO - Refactor X509 and X509_REQ functions to reuse similar code - X509 and X509_REQ i2d functions now generate their DER outputs instead of returning the input DER - Signature generated by wolfSSL_X509_resign_cert is now saved in the x509->sig buffer and added when calling *i2d - Add test_wolfSSL_d2i_X509_REQ --- csr.signed.der | Bin 0 -> 643 bytes src/bio.c | 17 ++- src/ssl.c | 303 +++++++++++++++++++++++++++++----------- tests/api.c | 17 ++- wolfcrypt/src/asn.c | 69 ++++++--- wolfssl/openssl/ssl.h | 5 +- wolfssl/ssl.h | 13 ++ wolfssl/wolfcrypt/asn.h | 8 +- 8 files changed, 326 insertions(+), 106 deletions(-) create mode 100644 csr.signed.der diff --git a/csr.signed.der b/csr.signed.der new file mode 100644 index 0000000000000000000000000000000000000000..7ae007f52f8d1cd43aa5ba552ffc3f01c2ba2e36 GIT binary patch literal 643 zcmXqLVyZW2VoYaZWH7KY6fqEDV-96u=HV{S&q*sT&e2QG&oxvsP+;TKYV&CO&dbQj zC?;H7T2PQ*RN{c7#-NE&$$%HGijk3(fw_s1pTVGsk&CH`k&)pr^F{4{mP?FWt%Far zXlvD!%-Xw3D~R3w+A_0E>_&YTc4bx{JM1#=N~6bL-Hb)u>AM$}o-ot#x+ML*d)Im1 zpYPv%Y?P~>&FnsFf9jd~RF%wSFGM<{pO}0}*Ys+us)~nN> z^ZsJnee*zRo`u$5KQ8t%ee&?!wENO^`~9Y05O}eI!=Q1!0=Kis(USBnMosy>ZHGD> zW|}qcl5;3h62Bgls#3h++;6~dR38vxzT#KJ8<1y8S z?RM_3HM{?-`W(4f`K9o3n}dY#hUBe9eg;RTx3uYo>0cN9UVmWS*FVuue=pp1nTeT^ zfpGx?au{)g!-$cgML$4G@c-SL zZ84|liOZ#4U+vG?CCQwu*B8ayyUcz*wx)0PVVQW>R`$0#GmBdUWs-YuZ|9GG|6Wpb zy5x?iUcW;%O(C}pKCaB&#~c6RgvBSR7nT{j_{3KgEaIsU{2nmz{+y#dOYW&v{kOf34T?FtF?-e(Tf)P*P)Zef$({mYek<~74LyjhFV zV&+fS{5Xv1X2aF6>m2%(YmM@ze9+dse!5n7V2q`>VEO_BUA>R{`e-9UA}u literal 0 HcmV?d00001 diff --git a/src/bio.c b/src/bio.c index 9c1e0c712..dbf29bcbe 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1681,20 +1681,25 @@ int wolfSSL_BIO_meth_set_destroy(WOLFSSL_BIO_METHOD *biom, /* this compatibility function can be used for multiple BIO types */ int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p) { + WOLFSSL_BIO* mem_bio; WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data"); if (bio == NULL) return WOLFSSL_FATAL_ERROR; - /* Return pointer from last BIO in chain */ - while (bio->next) + mem_bio = bio; + /* Return pointer from last memory BIO in chain */ + while (bio->next) { bio = bio->next; - - if (p) { - *(byte**)p = (byte*)bio->ptr; + if (bio->type == WOLFSSL_BIO_MEMORY) + mem_bio = bio; } - return bio->num; + if (p) { + *(byte**)p = (byte*)mem_bio->ptr; + } + + return mem_bio->num; } int wolfSSL_BIO_pending(WOLFSSL_BIO* bio) diff --git a/src/ssl.c b/src/ssl.c index 434612ec4..689e4579b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7507,7 +7507,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio, } (void)out; - memSz = wolfSSL_BIO_pending(bio); + memSz = wolfSSL_BIO_get_len(bio); if (memSz <= 0) { return NULL; } @@ -9450,15 +9450,12 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, } dns = dns->next; - /* last dns in list add at end of function */ - if (dns != NULL) { - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != - WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error pushing ASN1 object onto stack"); - wolfSSL_GENERAL_NAME_free(gn); - wolfSSL_sk_free(sk); - sk = NULL; - } + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != + WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1 object onto stack"); + wolfSSL_GENERAL_NAME_free(gn); + wolfSSL_sk_free(sk); + sk = NULL; } /* null so that it doesn't get pushed again after switch */ gn = NULL; @@ -17938,14 +17935,20 @@ WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in, return newX509; } - -WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) +static WOLFSSL_X509* wolfSSL_X509_X509_REQ_d2i(WOLFSSL_X509** x509, + const byte* in, int len, int req) { WOLFSSL_X509 *newX509 = NULL; WOLFSSL_ENTER("wolfSSL_X509_d2i"); - if (in != NULL && len != 0) { + if (in != NULL && len != 0 + #ifndef WOLFSSL_CERT_REQ + && req == 0 + #else + && (req == 0 || req == 1) + #endif + ) { #ifdef WOLFSSL_SMALL_STACK DecodedCert* cert; #else @@ -17960,6 +17963,9 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) #endif InitDecodedCert(cert, (byte*)in, len, NULL); + #ifdef WOLFSSL_CERT_REQ + cert->isCSR = req; + #endif if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) { newX509 = wolfSSL_X509_new(); if (newX509 != NULL) { @@ -17994,6 +18000,19 @@ int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509) return isCA; } + +WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) +{ + return wolfSSL_X509_X509_REQ_d2i(x509, in, len, 0); +} + +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509, + const unsigned char* in, int len) +{ + return wolfSSL_X509_X509_REQ_d2i(x509, in, len, 1); +} +#endif #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -22763,30 +22782,71 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, * * bio is the structure to hold output DER * x509 certificate to create DER from + * req if set then a CSR is generated * * returns WOLFSSL_SUCCESS on success */ -int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) +static int wolfSSL_i2d_X509_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req) { + int ret = WOLFSSL_FAILURE; + /* Get large buffer to hold cert der */ + int derSz = 8192; +#ifdef WOLFSSL_SMALL_STACK + byte* der; +#else + byte der[8192]; +#endif WOLFSSL_ENTER("wolfSSL_i2d_X509_bio"); if (bio == NULL || x509 == NULL) { return WOLFSSL_FAILURE; } - if (x509->derCert != NULL) { - word32 len = x509->derCert->length; - byte* der = x509->derCert->buffer; +#ifdef WOLFSSL_SMALL_STACK + der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!der) { + WOLFSSL_MSG("malloc failed"); + return WOLFSSL_FAILURE; + } +#endif - if (wolfSSL_BIO_write(bio, der, len) == (int)len) { - return WOLFSSL_SUCCESS; - } + + if (wolfSSL_X509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) { + goto cleanup; } - return WOLFSSL_FAILURE; + if (wolfSSL_BIO_write(bio, der, derSz) != derSz) { + goto cleanup; + } + + ret = WOLFSSL_SUCCESS; +cleanup: + #ifdef WOLFSSL_SMALL_STACK + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + return ret; } #endif /* !NO_BIO */ +/* Converts the X509 to DER format and outputs it into bio. + * + * bio is the structure to hold output DER + * x509 certificate to create DER from + * + * returns WOLFSSL_SUCCESS on success + */ +int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) +{ + return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 0); +} + +#ifdef WOLFSSL_CERT_REQ +int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) +{ + return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 1); +} +#endif /* WOLFSSL_CERT_REQ */ /* Converts an internal structure to a DER buffer * @@ -22829,16 +22889,16 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out) return derSz; } - #ifndef NO_BIO -/* Converts the DER from bio and creates a WOLFSSL_X509 structure from it. - * - * bio is the structure holding DER - * x509 certificate to create from DER. Can be NULL - * - * returns pointer to WOLFSSL_X509 structure on success and NULL on fail +/** + * Converts the DER from bio and creates a WOLFSSL_X509 structure from it. + * @param bio is the structure holding DER + * @param x509 certificate to create from DER. Can be NULL + * @param req 1 for a CSR and 0 for a x509 cert + * @return pointer to WOLFSSL_X509 structure on success and NULL on fail */ -WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) +static WOLFSSL_X509* wolfSSL_d2i_X509_X509_REQ_bio(WOLFSSL_BIO* bio, + WOLFSSL_X509** x509, int req) { WOLFSSL_X509* localX509 = NULL; byte* mem = NULL; @@ -22851,9 +22911,9 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) return NULL; } - size = wolfSSL_BIO_pending(bio); + size = wolfSSL_BIO_get_len(bio); if (size == 0) { - WOLFSSL_MSG("wolfSSL_BIO_pending error. Possibly no pending data."); + WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data."); return NULL; } @@ -22868,7 +22928,16 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) return NULL; } - localX509 = wolfSSL_X509_d2i(NULL, mem, size); + if (req) { +#ifdef WOLFSSL_CERT_REQ + localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size); +#else + WOLFSSL_MSG("CSR not compiled in"); +#endif + } + else { + localX509 = wolfSSL_X509_d2i(NULL, mem, size); + } if (localX509 == NULL) { WOLFSSL_MSG("wolfSSL_X509_d2i error"); XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); @@ -22883,6 +22952,17 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) } #endif /* !NO_BIO */ +WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) +{ + return wolfSSL_d2i_X509_X509_REQ_bio(bio, x509, 0); +} + +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) +{ + return wolfSSL_d2i_X509_X509_REQ_bio(bio, x509, 1); +} +#endif #if !defined(NO_ASN) && !defined(NO_PWDBASED) #ifndef NO_BIO @@ -38295,10 +38375,11 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) * updates derSz with certificate body size on success * return WOLFSSL_SUCCESS on success */ - static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, - unsigned char* der, int* derSz) + int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, + unsigned char* der, int* derSz, int includeSig) { - int ret; + int ret = WOLFSSL_FAILURE; + int totalLen; Cert cert; void* key = NULL; int type = -1; @@ -38385,14 +38466,20 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) ret = wc_MakeCert_ex(&cert, der, *derSz, type, key, &rng); wc_FreeRng(&rng); } + if (ret <= 0) { + ret = WOLFSSL_FAILURE; + goto cleanup; + } - if ((ret > 0) && (x509->serialSz == 0) && + if ((x509->serialSz == 0) && (cert.serialSz <= EXTERNAL_SERIAL_SIZE) && (cert.serialSz > 0)) { WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new(); if (i == NULL) { - ret = MEMORY_E; + WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error"); + ret = WOLFSSL_FAILURE; + goto cleanup; } else { i->length = cert.serialSz + 2; @@ -38401,12 +38488,34 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) XMEMCPY(i->data + 2, cert.serial, cert.serialSz); if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Issue setting generated serial number"); - ret = EXTENSIONS_E; + wolfSSL_ASN1_INTEGER_free(i); + ret = WOLFSSL_FAILURE; + goto cleanup; } wolfSSL_ASN1_INTEGER_free(i); } } + if (includeSig) { + if (!x509->sig.buffer) { + WOLFSSL_MSG("No signature buffer"); + ret = WOLFSSL_FAILURE; + goto cleanup; + } + totalLen = AddSignature(NULL, ret, NULL, x509->sig.length, + x509->sigOID); + if (totalLen > *derSz) { + WOLFSSL_MSG("Output der buffer too short"); + ret = WOLFSSL_FAILURE; + goto cleanup; + } + ret = AddSignature(der, ret, x509->sig.buffer, + x509->sig.length, x509->sigOID); + } + + *derSz = ret; + ret = WOLFSSL_SUCCESS; +cleanup: /* Dispose of the public key object. */ #ifndef NO_RSA if (x509->pubKeyOID == RSAk) @@ -38417,13 +38526,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) wc_ecc_free(&ecc); #endif - if (ret > 0) { - *derSz = ret; - return WOLFSSL_SUCCESS; - } - else { - return ret; - } + return ret; } @@ -38434,7 +38537,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) * WOLFSSL_X509 with the newly signed buffer. * returns size of signed buffer on success and negative values on fail */ - static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req, + static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md, WOLFSSL_EVP_PKEY* pkey) { @@ -38471,22 +38574,48 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) wc_FreeRng(&rng); if (ret < 0) return ret; + derSz = ret; - /* Put in the new certificate encoding into the x509 object. */ - FreeDer(&x509->derCert); - type = CERT_TYPE; - #ifdef WOLFSSL_REQ_CERT - if (req) { - type = CERTREQ_TYPE; + /* Extract signature from buffer */ + { + word32 idx = 0; + int len = 0; + + /* Read top level sequence */ + if (GetSequence(der, &idx, &len, derSz) < 0) { + WOLFSSL_MSG("GetSequence error"); + return WOLFSSL_FATAL_ERROR; + } + /* Move idx to signature */ + idx += certBodySz; + /* Read signature algo sequence */ + if (GetSequence(der, &idx, &len, derSz) < 0) { + WOLFSSL_MSG("GetSequence error"); + return WOLFSSL_FATAL_ERROR; + } + idx += len; + /* Read signature bit string */ + if (CheckBitString(der, &idx, &len, derSz, 0, NULL) != 0) { + WOLFSSL_MSG("CheckBitString error"); + return WOLFSSL_FATAL_ERROR; + } + /* Sanity check */ + if (idx + len != (word32)derSz) { + WOLFSSL_MSG("unexpected asn1 structure"); + return WOLFSSL_FATAL_ERROR; + } + x509->sig.length = 0; + if (x509->sig.buffer) + XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE); + x509->sig.buffer = (byte*)XMALLOC(len, x509->heap, + DYNAMIC_TYPE_SIGNATURE); + if (!x509->sig.buffer) { + WOLFSSL_MSG("malloc error"); + return WOLFSSL_FATAL_ERROR; + } + XMEMCPY(x509->sig.buffer, der + idx, len); + x509->sig.length = len; } - #endif - - if (AllocDer(&x509->derCert, ret, type, NULL) != 0) - return WOLFSSL_FATAL_ERROR; - XMEMCPY(x509->derCert->buffer, der, ret); - x509->derCert->length = ret; - - (void)req; return ret; } @@ -38502,7 +38631,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) { int ret; /* @TODO dynamic set based on expected cert size */ - byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); + byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); int derSz = WC_MAX_X509_GEN; WOLFSSL_ENTER("wolfSSL_X509_sign"); @@ -38513,7 +38642,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) } x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey); - if ((ret = wolfSSL_X509_make_der(x509, 0, der, &derSz)) != + if ((ret = wolfSSL_X509_make_der(x509, 0, der, &derSz, 0)) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Unable to make DER for X509"); WOLFSSL_LEAVE("wolfSSL_X509_sign", ret); @@ -41978,9 +42107,9 @@ WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out) } (void)out; - bioMemSz = wolfSSL_BIO_pending(bio); + bioMemSz = wolfSSL_BIO_get_len(bio); if (bioMemSz <= 0) { - WOLFSSL_MSG("wolfSSL_BIO_pending() failure"); + WOLFSSL_MSG("wolfSSL_BIO_get_len() failure"); return NULL; } @@ -42028,7 +42157,7 @@ WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out) } wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz); - if (wolfSSL_BIO_pending(bio) <= 0) { + if (wolfSSL_BIO_get_len(bio) <= 0) { WOLFSSL_MSG("Failed to write memory to bio"); XFREE((unsigned char*)extraBioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -42135,9 +42264,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio, } (void)out; - memSz = wolfSSL_BIO_pending(bio); + memSz = wolfSSL_BIO_get_len(bio); if (memSz <= 0) { - WOLFSSL_MSG("wolfSSL_BIO_pending() failure"); + WOLFSSL_MSG("wolfSSL_BIO_get_len() failure"); return NULL; } @@ -42175,7 +42304,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio, } wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz); - if (wolfSSL_BIO_pending(bio) <= 0) { + if (wolfSSL_BIO_get_len(bio) <= 0) { WOLFSSL_MSG("Failed to write memory to bio"); XFREE((unsigned char*)extraBioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -48677,7 +48806,7 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL) return NULL; - pkcs7->len = wolfSSL_BIO_pending(bio); + pkcs7->len = wolfSSL_BIO_get_len(bio); pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7); if (pkcs7->data == NULL) { wolfSSL_PKCS7_free((PKCS7*)pkcs7); @@ -49592,29 +49721,45 @@ void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer, int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out) { - const unsigned char* der; int derSz = 0; + int ret = WOLFSSL_FAILURE; + WOLFSSL_BIO* bio = NULL; WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ"); if (req == NULL || out == NULL) { return BAD_FUNC_ARG; } - der = wolfSSL_X509_get_der(req, &derSz); - if (der == NULL) { - return MEMORY_E; + if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) { + return WOLFSSL_FAILURE; } + if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error"); + goto cleanup; + } + + derSz = wolfSSL_BIO_get_len(bio); + if (*out == NULL) { *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); - if (*out == NULL) { - return MEMORY_E; + if (!*out) { + WOLFSSL_MSG("malloc error"); + ret = MEMORY_E; + goto cleanup; } } - XMEMCPY(*out, der, derSz); + if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) { + WOLFSSL_MSG("wolfSSL_BIO_read error"); + goto cleanup; + } - return derSz; + ret = derSz; +cleanup: + wolfSSL_BIO_free(bio); + + return ret; } WOLFSSL_X509* wolfSSL_X509_REQ_new(void) @@ -49638,11 +49783,11 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, /* Create a Cert that has the certificate request fields. */ req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey); - if (wolfSSL_X509_make_der(req, 1, der, &derSz) != WOLFSSL_SUCCESS) { + if (wolfSSL_X509_make_der(req, 1, der, &derSz, 0) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } - if (wolfSSL_X509_resign_cert(req, 1, der, sizeof(der), derSz, + if (wolfSSL_X509_resign_cert(req, der, sizeof(der), derSz, (WOLFSSL_EVP_MD*)md, pkey) <= 0) { return WOLFSSL_FAILURE; } diff --git a/tests/api.c b/tests/api.c index 675251fb7..c4e0a07a7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27585,8 +27585,7 @@ static void test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void) cmp = X509_NAME_cmp(caName, issuerName); AssertIntEQ(cmp, 0); #else - /* X509_STORE_CTX_get0_current_issuer() returns empty issuer */ - AssertNull(issuerName); + AssertNotNull(issuerName); #endif X509_free(issuer); @@ -37881,6 +37880,19 @@ static void test_wolfSSL_X509_CRL(void) return; } +static void test_wolfSSL_d2i_X509_REQ(void) +{ + const char* csrFile = "./csr.signed.der"; + BIO* bio = NULL; + X509* x509 = NULL; + + AssertNotNull(bio = BIO_new_file(csrFile, "rb")); + AssertNotNull(d2i_X509_REQ_bio(bio, &x509)); + + X509_free(x509); + BIO_free(bio); +} + static void test_wolfSSL_PEM_read_X509(void) { #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \ @@ -39597,6 +39609,7 @@ void ApiTest(void) test_wolfSSL_SHA256(); test_wolfSSL_X509_get_serialNumber(); test_wolfSSL_X509_CRL(); + test_wolfSSL_d2i_X509_REQ(); test_wolfSSL_PEM_read_X509(); test_wolfSSL_PEM_read(); #ifndef NO_BIO diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ff33fed3a..c09ceb269 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -934,7 +934,7 @@ static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx) #endif #endif -static int CheckBitString(const byte* input, word32* inOutIdx, int* len, +int CheckBitString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, int zeroBits, byte* unusedBits) { word32 idx = *inOutIdx; @@ -6673,19 +6673,25 @@ int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate) WOLFSSL_MSG("Got Cert Header"); - /* Using the sigIndex as the upper bound because that's where the - * actual certificate data ends. */ - if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID, - oidSigType, cert->sigIndex)) < 0) - return ret; +#ifdef WOLFSSL_CERT_REQ + if (!cert->isCSR) { +#endif + /* Using the sigIndex as the upper bound because that's where the + * actual certificate data ends. */ + if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID, + oidSigType, cert->sigIndex)) < 0) + return ret; - WOLFSSL_MSG("Got Algo ID"); + WOLFSSL_MSG("Got Algo ID"); - if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0) - return ret; + if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0) + return ret; - if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0) - *badDate = ret; + if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0) + *badDate = ret; +#ifdef WOLFSSL_CERT_REQ + } +#endif if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0) return ret; @@ -9415,6 +9421,9 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) int idx = 0; #endif byte* tsip_encRsaKeyIdx; +#ifdef WOLFSSL_CERT_REQ + int len = 0; +#endif if (cert == NULL) { return BAD_FUNC_ARG; @@ -9432,6 +9441,25 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) WOLFSSL_MSG("Parsed Past Key"); + +#ifdef WOLFSSL_CERT_REQ + /* Read attributes */ + if (cert->isCSR) { + if (GetASNHeader_ex(cert->source, + ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &cert->srcIdx, + &len, cert->maxIdx, 1) < 0) { + WOLFSSL_MSG("GetASNHeader_ex error"); + return ASN_PARSE_E; + } + + if (len) { + WOLFSSL_MSG("Non-empty attributes. wolfSSL doesn't support " + "parsing CSR attributes."); + return ASN_VERSION_E; + } + } +#endif + if (cert->srcIdx < cert->sigIndex) { #ifndef ALLOW_V1_EXTENSIONS if (cert->version < 2) { @@ -9461,14 +9489,23 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) cert->srcIdx = cert->sigIndex; } - if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID, - oidSigType, cert->maxIdx)) < 0) + if ((ret = GetAlgoId(cert->source, &cert->srcIdx, +#ifdef WOLFSSL_CERT_REQ + !cert->isCSR ? &confirmOID : &cert->signatureOID, +#else + &confirmOID, +#endif + oidSigType, cert->maxIdx)) < 0) return ret; if ((ret = GetSignature(cert)) < 0) return ret; - if (confirmOID != cert->signatureOID) + if (confirmOID != cert->signatureOID +#ifdef WOLFSSL_CERT_REQ + && !cert->isCSR +#endif + ) return ASN_SIG_OID_E; #ifndef NO_SKID @@ -13703,7 +13740,7 @@ exit_ms: /* add signature to end of buffer, size of buffer assumed checked, return new length */ -static int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, +int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, int sigAlgoType) { byte seq[MAX_SEQ_SZ]; @@ -13841,7 +13878,7 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, byte erSeq[MAX_SEQ_SZ]; byte erSet[MAX_SET_SZ]; - output[0] = 0xa0; + output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED; sz++; if (pw && pw[0]) { diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index c98f12b21..33a65fc89 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -361,9 +361,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define DSA_bits wolfSSL_DSA_bits #define i2d_X509_bio wolfSSL_i2d_X509_bio -#define i2d_X509_REQ_bio wolfSSL_i2d_X509_bio +#define i2d_X509_REQ_bio wolfSSL_i2d_X509_REQ_bio #define d2i_X509_bio wolfSSL_d2i_X509_bio -#define d2i_X509_REQ_bio wolfSSL_d2i_X509_bio +#define d2i_X509_REQ_bio wolfSSL_d2i_X509_REQ_bio #define d2i_X509_fp wolfSSL_d2i_X509_fp #define i2d_X509 wolfSSL_i2d_X509 #define d2i_X509 wolfSSL_d2i_X509 @@ -379,6 +379,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define i2d_PrivateKey wolfSSL_i2d_PrivateKey #define i2d_X509_REQ wolfSSL_i2d_X509_REQ +#define d2i_X509_REQ wolfSSL_d2i_X509_REQ #define X509_REQ_new wolfSSL_X509_REQ_new #define X509_REQ_free wolfSSL_X509_REQ_free #define X509_REQ_sign wolfSSL_X509_REQ_sign diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a08a79644..bcfadaa7b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2186,6 +2186,10 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in, int len); WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_API WOLFSSL_X509* + wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len); +#endif WOLFSSL_API int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out); WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL **crl, const unsigned char *in, int len); @@ -3423,7 +3427,12 @@ WOLFSSL_API int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, unsigned char* out, int outSz); WOLFSSL_API int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses); +WOLFSSL_LOCAL int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, + unsigned char* der, int* derSz, int includeSig); WOLFSSL_API int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_API int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); +#endif #if !defined(NO_FILESYSTEM) WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509** x509); @@ -3431,6 +3440,10 @@ WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s #endif WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, + WOLFSSL_X509** x509); +#endif #endif /* OPENSSL_EXTRA || OPENSSL_ALL */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 3210f9b19..ebb953f05 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -944,7 +944,9 @@ struct DecodedCert { #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT) byte extCertPolicyCrit : 1; #endif - +#ifdef WOLFSSL_CERT_REQ + byte isCSR : 1; /* Do we intend on parsing a CSR? */ +#endif }; @@ -1041,6 +1043,8 @@ WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz, WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm); WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); +WOLFSSL_LOCAL int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, + int sigAlgoType); WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm); WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify); WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate); @@ -1113,6 +1117,8 @@ WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, int check); WOLFSSL_LOCAL int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); +WOLFSSL_LOCAL int CheckBitString(const byte* input, word32* inOutIdx, int* len, + word32 maxIdx, int zeroBits, byte* unusedBits); WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetSet_ex(const byte* input, word32* inOutIdx, int* len, From be98404b3b0c91d7d345a58ceee174b95c601020 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 21 Jul 2020 23:05:04 +0200 Subject: [PATCH 12/53] Implement wolfSSL_X509_REQ_verify --- src/ssl.c | 58 +++++++--- tests/api.c | 17 ++- wolfcrypt/src/asn.c | 237 ++++++++++++++++++++++------------------ wolfssl/openssl/ssl.h | 2 +- wolfssl/ssl.h | 3 + wolfssl/wolfcrypt/asn.h | 4 + 6 files changed, 199 insertions(+), 122 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 689e4579b..3a8cb62ad 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23867,11 +23867,10 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) return WOLFSSL_FATAL_ERROR; } - /* Use the public key to verify the signature. Note: this only verifies * the certificate signature. * returns WOLFSSL_SUCCESS on successful signature verification */ -int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) +static int wolfSSL_X509_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req) { int ret; const byte* der; @@ -23906,13 +23905,31 @@ int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) return WOLFSSL_FATAL_ERROR; } - ret = CheckCertSignaturePubKey(der, derSz, x509->heap, - (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type); +#ifdef WOLFSSL_CERT_REQ + if (req) + ret = CheckCSRSignaturePubKey(der, derSz, x509->heap, + (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type); + else +#endif + ret = CheckCertSignaturePubKey(der, derSz, x509->heap, + (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type); if (ret == 0) { return WOLFSSL_SUCCESS; } return WOLFSSL_FAILURE; } + +int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) +{ + return wolfSSL_X509_X509_REQ_verify(x509, pkey, 0); +} + +#ifdef WOLFSSL_CERT_REQ +int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) +{ + return wolfSSL_X509_X509_REQ_verify(x509, pkey, 1); +} +#endif /* WOLFSSL_CERT_REQ */ #endif /* !NO_CERTS */ #if !defined(NO_FILESYSTEM) @@ -49644,7 +49661,8 @@ int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s) int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) { - byte* p; + byte* p = NULL; + int pLen; WOLFSSL_ENTER("wolfSSL_X509_set_pubkey"); if (cert == NULL || pkey == NULL) @@ -49657,15 +49675,29 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) else return WOLFSSL_FAILURE; - p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (p == NULL) - return WOLFSSL_FAILURE; + if (pkey->type == EVP_PKEY_RSA) { + /* Public and private key formats differ. Make sure to put in the + * public key format in the cert. */ + if ((pLen = wolfSSL_i2d_RSAPublicKey(pkey->rsa, (const byte**)&p)) <= 0) { + WOLFSSL_MSG("wolfSSL_i2d_RSAPublicKey error"); + return WOLFSSL_FAILURE; + } + if (cert->pubKey.buffer != NULL) + XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + cert->pubKey.buffer = p; + cert->pubKey.length = pLen; + } + else { + p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (p == NULL) + return WOLFSSL_FAILURE; - if (cert->pubKey.buffer != NULL) - XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - cert->pubKey.buffer = p; - XMEMCPY(cert->pubKey.buffer, pkey->pkey.ptr, pkey->pkey_sz); - cert->pubKey.length = pkey->pkey_sz; + if (cert->pubKey.buffer != NULL) + XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); + cert->pubKey.buffer = p; + XMEMCPY(cert->pubKey.buffer, pkey->pkey.ptr, pkey->pkey_sz); + cert->pubKey.length = pkey->pkey_sz; + } return WOLFSSL_SUCCESS; } diff --git a/tests/api.c b/tests/api.c index c4e0a07a7..3e1d5dce6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -37884,12 +37884,23 @@ static void test_wolfSSL_d2i_X509_REQ(void) { const char* csrFile = "./csr.signed.der"; BIO* bio = NULL; - X509* x509 = NULL; + X509* req = NULL; + EVP_PKEY *pub_key = NULL; AssertNotNull(bio = BIO_new_file(csrFile, "rb")); - AssertNotNull(d2i_X509_REQ_bio(bio, &x509)); + AssertNotNull(d2i_X509_REQ_bio(bio, &req)); - X509_free(x509); + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + + X509_free(req); BIO_free(bio); } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c09ceb269..efbdc078a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -9093,6 +9093,7 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm) /* Only quick step through the certificate to find fields that are then used * in certificate signature verification. * Must use the signature OID from the signed part of the certificate. + * Works also on certificate signing requests. * * This is only for minimizing dynamic memory usage during TLS certificate * chain processing. @@ -9100,7 +9101,7 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm) * OCSP Only: alt lookup using subject and pub key w/o sig check */ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, - void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID) + void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID, int req) { #ifndef WOLFSSL_SMALL_STACK SignatureCtx sigCtx[1]; @@ -9177,13 +9178,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, idx += len; /* signature */ - if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0) + if (!req && + GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0) ret = ASN_PARSE_E; } if (ret == 0) { issuerIdx = idx; - /* issuer */ + /* issuer for cert or subject for csr */ if (GetSequence(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; } @@ -9191,14 +9193,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, issuerSz = len + idx - issuerIdx; } #ifndef NO_SKID - if (ret == 0) { + if (!req && ret == 0) { idx += len; /* validity */ if (GetSequence(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; } - if (ret == 0) { + if (!req && ret == 0) { idx += len; /* subject */ @@ -9212,123 +9214,137 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, if (GetSequence(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; } - if (ret == 0) { + if (req && ret == 0) { idx += len; - if ((idx + 1) > certSz) - ret = BUFFER_E; - } - if (ret == 0) { - /* issuerUniqueID - optional */ - localIdx = idx; - if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) { - if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) { - idx++; - if (GetLength(cert, &idx, &len, certSz) < 0) - ret = ASN_PARSE_E; - idx += len; - } - } - } - if (ret == 0) { - if ((idx + 1) > certSz) - ret = BUFFER_E; - } - if (ret == 0) { - /* subjectUniqueID - optional */ - localIdx = idx; - if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) { - if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) { - idx++; - if (GetLength(cert, &idx, &len, certSz) < 0) - ret = ASN_PARSE_E; - idx += len; - } - } - } - - if (ret == 0) { - if ((idx + 1) > certSz) - ret = BUFFER_E; - } - /* extensions - optional */ - localIdx = idx; - if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 && - tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) { - idx++; - if (GetLength(cert, &idx, &extLen, certSz) < 0) + /* attributes */ + if (GetASNHeader_ex(cert, + ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx, + &len, certSz, 1) < 0) ret = ASN_PARSE_E; + } + if (!req) { if (ret == 0) { - if (GetSequence(cert, &idx, &extLen, certSz) < 0) - ret = ASN_PARSE_E; + idx += len; + + if ((idx + 1) > certSz) + ret = BUFFER_E; } if (ret == 0) { - extEndIdx = idx + extLen; - - /* Check each extension for the ones we want. */ - while (ret == 0 && idx < extEndIdx) { - if (GetSequence(cert, &idx, &len, certSz) < 0) - ret = ASN_PARSE_E; - if (ret == 0) { - extIdx = idx; - if (GetObjectId(cert, &extIdx, &oid, oidCertExtType, - certSz) < 0) { + /* issuerUniqueID - optional */ + localIdx = idx; + if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) { + if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) { + idx++; + if (GetLength(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; + idx += len; + } + } + } + if (ret == 0) { + if ((idx + 1) > certSz) + ret = BUFFER_E; + } + if (ret == 0) { + /* subjectUniqueID - optional */ + localIdx = idx; + if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) { + if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) { + idx++; + if (GetLength(cert, &idx, &len, certSz) < 0) + ret = ASN_PARSE_E; + idx += len; + } + } + } + + if (ret == 0) { + if ((idx + 1) > certSz) + ret = BUFFER_E; + } + /* extensions - optional */ + localIdx = idx; + if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 && + tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) { + idx++; + if (GetLength(cert, &idx, &extLen, certSz) < 0) + ret = ASN_PARSE_E; + if (ret == 0) { + if (GetSequence(cert, &idx, &extLen, certSz) < 0) + ret = ASN_PARSE_E; + } + if (ret == 0) { + extEndIdx = idx + extLen; + + /* Check each extension for the ones we want. */ + while (ret == 0 && idx < extEndIdx) { + if (GetSequence(cert, &idx, &len, certSz) < 0) + ret = ASN_PARSE_E; + if (ret == 0) { + extIdx = idx; + if (GetObjectId(cert, &extIdx, &oid, oidCertExtType, + certSz) < 0) { + ret = ASN_PARSE_E; + } + + if (ret == 0) { + if ((extIdx + 1) > certSz) + ret = BUFFER_E; + } } if (ret == 0) { - if ((extIdx + 1) > certSz) - ret = BUFFER_E; - } - } - - if (ret == 0) { - localIdx = extIdx; - if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 && - tag == ASN_BOOLEAN) { - if (GetBoolean(cert, &extIdx, certSz) < 0) - ret = ASN_PARSE_E; - } - } - if (ret == 0) { - if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0) - ret = ASN_PARSE_E; - } - - if (ret == 0) { - switch (oid) { - case AUTH_KEY_OID: - if (GetSequence(cert, &extIdx, &extLen, certSz) < 0) - ret = ASN_PARSE_E; - - if (ret == 0 && (extIdx + 1) >= certSz) - ret = BUFFER_E; - - if (ret == 0 && - GetASNTag(cert, &extIdx, &tag, certSz) == 0 && - tag == (ASN_CONTEXT_SPECIFIC | 0)) { - if (GetLength(cert, &extIdx, &extLen, certSz) <= 0) + localIdx = extIdx; + if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 && + tag == ASN_BOOLEAN) { + if (GetBoolean(cert, &extIdx, certSz) < 0) ret = ASN_PARSE_E; - if (ret == 0) { - extAuthKeyIdSet = 1; - if (extLen == KEYID_SIZE) - XMEMCPY(hash, cert + extIdx, extLen); - else { - ret = CalcHashId(cert + extIdx, extLen, - hash); + } + } + if (ret == 0) { + if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0) + ret = ASN_PARSE_E; + } + + if (ret == 0) { + switch (oid) { + case AUTH_KEY_OID: + if (GetSequence(cert, &extIdx, &extLen, certSz) < 0) + ret = ASN_PARSE_E; + + if (ret == 0 && (extIdx + 1) >= certSz) + ret = BUFFER_E; + + if (ret == 0 && + GetASNTag(cert, &extIdx, &tag, certSz) == 0 && + tag == (ASN_CONTEXT_SPECIFIC | 0)) { + if (GetLength(cert, &extIdx, &extLen, certSz) <= 0) + ret = ASN_PARSE_E; + if (ret == 0) { + extAuthKeyIdSet = 1; + if (extLen == KEYID_SIZE) + XMEMCPY(hash, cert + extIdx, extLen); + else { + ret = CalcHashId(cert + extIdx, extLen, + hash); + } } } - } - break; + break; - default: - break; + default: + break; + } } + idx += len; } - idx += len; } } } + else if (ret == 0) { + idx += len; + } if (ret == 0 && pubKey == NULL) { if (extAuthKeyIdSet) @@ -9354,6 +9370,9 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, /* signatureAlgorithm */ if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0) ret = ASN_PARSE_E; + /* In CSR signature data is not present in body */ + if (req) + signatureOID = oid; } if (ret == 0) { if (oid != signatureOID) @@ -9398,15 +9417,23 @@ int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID) { return CheckCertSignature_ex(cert, certSz, heap, NULL, - pubKey, pubKeySz, pubKeyOID); + pubKey, pubKeySz, pubKeyOID, 0); } +#ifdef WOLFSSL_CERT_REQ +int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap, + const byte* pubKey, word32 pubKeySz, int pubKeyOID) +{ + return CheckCertSignature_ex(cert, certSz, heap, NULL, + pubKey, pubKeySz, pubKeyOID, 1); +} +#endif /* WOLFSSL_CERT_REQ */ #endif /* OPENSSL_EXTRA */ #ifdef WOLFSSL_SMALL_CERT_VERIFY /* Call CheckCertSignature_ex using a certificate manager (cm) */ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) { - return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0); + return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0, 0); } #endif /* WOLFSSL_SMALL_CERT_VERIFY */ #endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 33a65fc89..b477c8374 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -441,7 +441,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string #define X509_verify_cert wolfSSL_X509_verify_cert #define X509_verify wolfSSL_X509_verify -#define X509_REQ_verify wolfSSL_X509_verify +#define X509_REQ_verify wolfSSL_X509_REQ_verify #define X509_check_private_key wolfSSL_X509_check_private_key #define X509_check_ca wolfSSL_X509_check_ca #define X509_check_host wolfSSL_X509_check_host diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index bcfadaa7b..c1a0effbc 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1377,6 +1377,9 @@ WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID( WOLFSSL_X509*, unsigned char*, int*); WOLFSSL_API int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_API int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey); +#endif WOLFSSL_API int wolfSSL_X509_set_subject_name(WOLFSSL_X509*, WOLFSSL_X509_NAME*); WOLFSSL_API int wolfSSL_X509_set_issuer_name(WOLFSSL_X509*, diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index ebb953f05..88742f5ae 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1043,6 +1043,10 @@ WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz, WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm); WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap, + const byte* pubKey, word32 pubKeySz, int pubKeyOID); +#endif /* WOLFSSL_CERT_REQ */ WOLFSSL_LOCAL int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, int sigAlgoType); WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm); From 42d4f35a982ee5b88f0739045d99819532345ee7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 23 Jul 2020 20:18:47 +0200 Subject: [PATCH 13/53] Implement OpenSSL Compat API: - Implement lhash as a stack with hash members - wolfSSL_lh_retrieve - wolfSSL_LH_strhash - IMPLEMENT_LHASH_COMP_FN - IMPLEMENT_LHASH_HASH_FN - wolfSSL_sk_CONF_VALUE_new - wolfSSL_sk_CONF_VALUE_free - wolfSSL_sk_CONF_VALUE_num - wolfSSL_sk_CONF_VALUE_value - wolfSSL_NCONF_new - wolfSSL_NCONF_get_string - wolfSSL_NCONF_get_section - wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve - wolfSSL_CONF_modules_load --- src/ssl.c | 510 +++++++++++++++++++++++++------------- tests/api.c | 6 + wolfssl/internal.h | 2 + wolfssl/openssl/bio.h | 1 + wolfssl/openssl/buffer.h | 2 + wolfssl/openssl/conf.h | 50 +++- wolfssl/openssl/lhash.h | 57 +++++ wolfssl/openssl/ssl.h | 7 + wolfssl/openssl/stack.h | 1 - wolfssl/openssl/txt_db.h | 6 + wolfssl/ssl.h | 7 +- wolfssl/wolfcrypt/types.h | 3 +- 12 files changed, 472 insertions(+), 180 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 3a8cb62ad..c6683b449 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -110,6 +110,7 @@ #include #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) #include + #include #endif /* WITH_STUNNEL */ #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #include @@ -18410,36 +18411,13 @@ WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509) /* return 1 on success 0 on fail */ int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509) { - WOLFSSL_STACK* node; WOLFSSL_ENTER("wolfSSL_sk_X509_push"); if (sk == NULL || x509 == NULL) { return WOLFSSL_FAILURE; } - /* no previous values in stack */ - if (sk->data.x509 == NULL) { - sk->data.x509 = x509; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = wolfSSL_sk_new_node(sk->heap); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - - /* push new x509 onto head of stack */ - node->data.x509 = sk->data.x509; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.x509 = x509; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, x509); } @@ -18564,39 +18542,9 @@ void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk) int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk, WOLFSSL_ACCESS_DESCRIPTION* access) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push"); - if (sk == NULL || access == NULL) { - return WOLFSSL_FAILURE; - } - - /* no previous values in stack */ - if (sk->data.access == NULL) { - sk->data.access = access; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_ASN1); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.access = sk->data.access; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.access = access; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, access); } /* Frees all nodes in ACCESS_DESCRIPTION stack @@ -18720,39 +18668,78 @@ int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in) /* return 1 on success 0 on fail */ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) { - int ret = WOLFSSL_FAILURE; + WOLFSSL_STACK* node; + WOLFSSL_CIPHER ciph; WOLFSSL_ENTER("wolfSSL_sk_push"); + if (!sk) { + return WOLFSSL_FAILURE; + } + + /* Check if empty data */ switch (sk->type) { #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - case STACK_TYPE_X509: - ret = wolfSSL_sk_X509_push(sk, (WOLFSSL_X509*) data); - break; - #ifndef NO_WOLFSSL_STUB case STACK_TYPE_CIPHER: - ret = wolfSSL_sk_CIPHER_push(sk, (WOLFSSL_CIPHER*) data); - break; - #endif - case STACK_TYPE_GEN_NAME: - ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data); - break; - case STACK_TYPE_ACCESS_DESCRIPTION: - ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(sk, - (WOLFSSL_ACCESS_DESCRIPTION*) data); - break; - case STACK_TYPE_NULL: - ret = wolfSSL_sk_GENERIC_push(sk, (void*) data); - break; - case STACK_TYPE_OBJ: - ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data); + /* check if entire struct is zero */ + XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER)); + if (XMEMCMP(&sk->data.cipher, &ciph, + sizeof(WOLFSSL_CIPHER)) == 0) { + sk->data.cipher = *(WOLFSSL_CIPHER*)data; + sk->num = 1; + return WOLFSSL_SUCCESS; + } break; #endif default: - ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data); + /* All other types are pointers */ + if (!sk->data.generic) { + sk->data.generic = (void*)data; + sk->num = 1; + return WOLFSSL_SUCCESS; + } break; } - return ret; + /* stack already has value(s) create a new node and add more */ + node = wolfSSL_sk_new_node(sk->heap); + if (!node) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + + /* push new x509 onto head of stack */ + node->next = sk->next; + node->type = sk->type; + sk->next = node; + sk->num += 1; + +#ifdef OPENSSL_ALL + node->comp = sk->comp; + node->hash_fn = sk->hash_fn; + node->hash = sk->hash; + sk->hash = 0; +#endif + switch (sk->type) { + #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + case STACK_TYPE_CIPHER: + node->data.cipher = sk->data.cipher; + sk->data.cipher = *(WOLFSSL_CIPHER*)data; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(&sk->data.cipher); + } + break; + #endif + default: + /* All other types are pointers */ + node->data.generic = sk->data.generic; + sk->data.generic = (void*)data; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(sk->data.generic); + } + break; + } + + return WOLFSSL_SUCCESS; } /* Creates and returns new GENERAL_NAME structure */ @@ -19074,6 +19061,278 @@ void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens) } #if defined(OPENSSL_ALL) + +void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data) +{ + unsigned long hash; + + WOLFSSL_ENTER("wolfSSL_lh_retrieve"); + + if (!sk || !data) { + WOLFSSL_MSG("Bad parameters"); + return NULL; + } + + if (!sk->hash_fn) { + WOLFSSL_MSG("No hash function defined"); + return NULL; + } + + hash = sk->hash_fn(data); + + while (sk) { + /* Calc hash if not done so yet */ + if (!sk->hash) { + switch (sk->type) { + case STACK_TYPE_CIPHER: + sk->hash = sk->hash_fn(&sk->data.cipher); + break; + default: + sk->hash = sk->hash_fn(sk->data.generic); + break; + } + } + if (sk->hash == hash) { + switch (sk->type) { + case STACK_TYPE_CIPHER: + return &sk->data.cipher; + default: + return sk->data.generic; + } + } + sk = sk->next; + } + + return NULL; +} + +/** + * This is the same hashing algo for WOLFSSL_CONF_VALUE as OpenSSL + */ +static unsigned long wolfSSL_CONF_VALUE_hash(const WOLFSSL_CONF_VALUE *val) +{ + if (val) + return (wolfSSL_LH_strhash(val->section) << 2) ^ + wolfSSL_LH_strhash(val->name); + else + return 0; +} + +static int wolfSSL_CONF_VALUE_cmp(const WOLFSSL_CONF_VALUE *a, + const WOLFSSL_CONF_VALUE *b) +{ + int cmp_val; + + if (!a || !b) { + return -1; + } + + if (a->section != b->section) { + if ((cmp_val = XSTRCMP(a->section, b->section)) != 0) { + return cmp_val; + } + } + + if (a->name && b->name) { + return XSTRCMP(a->name, b->name); + } + else if (a->name == b->name) { + return 0; + } + else { + return a->name ? 1 : -1; + } +} + +/* Use MD5 for hashing */ +unsigned long wolfSSL_LH_strhash(const char *str) +{ + unsigned long ret = 0; + int strLen; + byte digest[WC_MD5_DIGEST_SIZE]; + WOLFSSL_ENTER("wolfSSL_LH_strhash"); + + if (!str) + return 0; + +#ifndef NO_MD5 + strLen = XSTRLEN(str); + if (wc_Md5Hash((const byte*)str, strLen, digest) != 0) { + WOLFSSL_MSG("wc_Md5Hash error"); + return 0; + } + /* Take first 4 bytes in small endian as unsigned long */ + ret = digest[0]; + ret |= digest[1] << 8; + ret |= digest[2] << 16; + ret |= digest[3] << 24; +#else + WOLFSSL_MSG("No md5 available for wolfSSL_LH_strhash"); +#endif + return ret; +} + +WOLFSSL_CONF_VALUE *wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve( + WOLF_LHASH_OF(WOLFSSL_CONF_VALUE) *sk, WOLFSSL_CONF_VALUE *data) +{ + WOLFSSL_ENTER("wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve"); + + if (!sk || !data) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + return wolfSSL_lh_retrieve(sk, data); +} + +int wolfSSL_CONF_modules_load(const WOLFSSL_CONF *cnf, const char *appname, + unsigned long flags) +{ + WOLFSSL_ENTER("wolfSSL_CONF_modules_load"); + WOLFSSL_MSG("All wolfSSL modules are already compiled in. " + "wolfSSL_CONF_modules_load doesn't load anything new."); + return WOLFSSL_SUCCESS; +} + +WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth) +{ + WOLFSSL_CONF* ret; + WOLFSSL_ENTER("wolfSSL_NCONF_new"); + + if (meth) { + WOLFSSL_MSG("wolfSSL does not support CONF_METHOD"); + } + + ret = (WOLFSSL_CONF*)XMALLOC(sizeof(WOLFSSL_CONF), NULL, DYNAMIC_TYPE_OPENSSL); + if (ret) + XMEMSET(ret, 0, sizeof(WOLFSSL_CONF)); + return ret; +} + +char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf, + const char *group, const char *name) +{ + WOLFSSL_CONF_VALUE find_val; + WOLFSSL_CONF_VALUE *val; + WOLFSSL_ENTER("wolfSSL_NCONF_get_string"); + + if (!conf) { +#ifdef HAVE_SECURE_GETENV + return secure_getenv(name); +#else + WOLFSSL_MSG("Missing secure_getenv"); + return NULL; +#endif + } + + find_val.name = (char *)name; + if (group) { + find_val.section = (char *)group; + val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val); + if (val) + return val->value; + if (XSTRCMP(group, "ENV") == 0) { +#ifdef HAVE_SECURE_GETENV + return secure_getenv(name); +#else + WOLFSSL_MSG("Missing secure_getenv"); + return NULL; +#endif + } + } + + find_val.section = (char *)"default"; + val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val); + if (val) + return val->value; + else + return NULL; +} + +/** + * The WOLFSSL_CONF->value member is treated as a + * WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE) which becomes + * the return value. + * @param conf + * @param section + * @return WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE) + */ +WOLFSSL_STACK *wolfSSL_NCONF_get_section( + const WOLFSSL_CONF *conf, const char *section) +{ + WOLFSSL_CONF_VALUE *val; + WOLFSSL_CONF_VALUE find_val; + + WOLFSSL_ENTER("wolfSSL_NCONF_get_section"); + + if (!conf || !section) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + find_val.name = NULL; + find_val.section = (char*)section; + val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val); + if (val) + return (WOLFSSL_STACK*)val->value; + else + return NULL; +} + +WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc) +{ + WOLFSSL_STACK* ret; + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_new"); + ret = wolfSSL_sk_new_node(NULL); + if (!ret) + return NULL; + ret->comp = compFunc ? compFunc : (wolf_sk_compare_cb)wolfSSL_CONF_VALUE_cmp; + ret->hash_fn = (wolf_sk_hash_cb)wolfSSL_CONF_VALUE_hash; + ret->type = STACK_TYPE_CONF_VALUE; + return ret; +} + +/* Free the structure for WOLFSSL_CONF_VALUE stack + * + * sk stack to free nodes in + */ +void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_STACK* tmp; + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free"); + + if (sk == NULL) + return; + + /* parse through stack freeing each node */ + node = sk->next; + while (node) { + tmp = node; + node = node->next; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + } + + /* free head of stack */ + XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} + +int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_num"); + if (sk) + wolfSSL_sk_num(sk); + return 0; +} + +WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value(const WOLFSSL_STACK *sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_value"); + if (sk) + return wolfSSL_sk_value(sk, i); + return NULL; +} + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void) { WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); @@ -19742,39 +20001,13 @@ WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void) int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, WOLFSSL_ASN1_OBJECT* obj) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_push"); if (sk == NULL || obj == NULL) { return WOLFSSL_FAILURE; } - /* no previous values in stack */ - if (sk->data.obj == NULL) { - sk->data.obj = obj; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_ASN1); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.obj = sk->data.obj; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.obj = obj; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, obj); } @@ -20341,19 +20574,14 @@ WOLFSSL_STACK* wolfSSL_sk_new_cipher(void) return sk; } -#ifndef NO_WOLFSSL_STUB -/* Keep as stubs for now */ /* return 1 on success 0 on fail */ int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, WOLFSSL_CIPHER* cipher) { - WOLFSSL_STUB("wolfSSL_sk_CIPHER_push"); - (void)sk; - (void)cipher; - return 0; + return wolfSSL_sk_push(sk, cipher); } - +#ifndef NO_WOLFSSL_STUB WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) { WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop"); @@ -27750,7 +27978,7 @@ int wolfSSL_sk_num(const WOLFSSL_STACK* sk) return (int)sk->num; } -void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i) +void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) { WOLFSSL_ENTER("wolfSSL_sk_value"); @@ -27944,38 +28172,9 @@ void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, /* return 1 on success 0 on fail */ int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push"); - if (sk == NULL || generic == NULL) { - return WOLFSSL_FAILURE; - } - - /* no previous values in stack */ - if (sk->data.generic == NULL) { - sk->data.generic = generic; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK),NULL,DYNAMIC_TYPE_SSL); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new node onto head of stack */ - node->type = sk->type; - node->data.generic = sk->data.generic; - node->next = sk->next; - sk->next = node; - sk->data.generic = generic; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, generic); } void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) { @@ -28036,33 +28235,6 @@ void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, break; } } - -#if defined(OPENSSL_ALL) -/* Free the structure for WOLFSSL_CONF_VALUE stack - * - * sk stack to free nodes in - */ -void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk) -{ - WOLFSSL_STACK* node; - WOLFSSL_STACK* tmp; - WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free"); - - if (sk == NULL) - return; - - /* parse through stack freeing each node */ - node = sk->next; - while (node) { - tmp = node; - node = node->next; - XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); - } - - /* free head of stack */ - XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); -} -#endif /* OPENSSL_ALL */ #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) diff --git a/tests/api.c b/tests/api.c index 3e1d5dce6..5e198011a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25284,6 +25284,11 @@ static int test_wc_HashGetFlags(void) | Compatibility Tests *----------------------------------------------------------------------------*/ +static void test_wolfSSL_lhash(void) +{ + +} + static void test_wolfSSL_X509_NAME(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \ @@ -39493,6 +39498,7 @@ void ApiTest(void) test_wolfSSL_mcast(); /* compatibility tests */ + test_wolfSSL_lhash(); test_wolfSSL_X509_NAME(); #ifndef NO_BIO test_wolfSSL_X509_INFO(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2f2c98bf4..62ed053ef 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3620,6 +3620,8 @@ struct WOLFSSL_STACK { * (safety measure for freeing and shortcut for count) */ #if defined(OPENSSL_ALL) wolf_sk_compare_cb comp; + wolf_sk_hash_cb hash_fn; + unsigned long hash; #endif union { diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 62841a744..3218ad69f 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -149,6 +149,7 @@ #define BIO_CTRL_DGRAM_QUERY_MTU 40 +#define BIO_FP_TEXT 0x00 #define BIO_NOCLOSE 0x00 #define BIO_CLOSE 0x01 diff --git a/wolfssl/openssl/buffer.h b/wolfssl/openssl/buffer.h index 8e0a73000..600c66eff 100644 --- a/wolfssl/openssl/buffer.h +++ b/wolfssl/openssl/buffer.h @@ -40,6 +40,8 @@ WOLFSSL_API void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf); #define BUF_MEM_grow wolfSSL_BUF_MEM_grow #define BUF_MEM_free wolfSSL_BUF_MEM_free +#define BUF_strdup strdup + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index 373239ff6..bfceb602f 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -28,18 +28,56 @@ extern "C" { #endif -struct WOLFSSL_CONF_VALUE { +#include + +typedef struct WOLFSSL_CONF_VALUE { char *section; char *name; char *value; -}; +} WOLFSSL_CONF_VALUE; -struct WOLFSSL_INIT_SETTINGS { +typedef struct WOLFSSL_INIT_SETTINGS { char* appname; -}; +} WOLFSSL_INIT_SETTINGS; + +typedef struct WOLFSSL_CONF { + void *meth_data; + WOLF_LHASH_OF(WOLFSSL_CONF_VALUE) *data; +} WOLFSSL_CONF; + +typedef WOLFSSL_CONF CONF; +typedef WOLFSSL_CONF_VALUE CONF_VALUE; +typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; + +WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc); +WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(struct WOLFSSL_STACK *sk); +WOLFSSL_API int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk); +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value( + const struct WOLFSSL_STACK *sk, int i); + +WOLFSSL_API WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth); +WOLFSSL_API char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf, + const char *group, const char *name); +WOLFSSL_API WOLFSSL_STACK *wolfSSL_NCONF_get_section( + const WOLFSSL_CONF *conf, const char *section); + +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve( + WOLF_LHASH_OF(WOLFSSL_CONF_VALUE) *sk, WOLFSSL_CONF_VALUE *data); + +WOLFSSL_API int wolfSSL_CONF_modules_load(const WOLFSSL_CONF *cnf, const char *appname, + unsigned long flags); + +#define sk_CONF_VALUE_new wolfSSL_sk_CONF_VALUE_new +#define sk_CONF_VALUE_free wolfSSL_sk_CONF_VALUE_free +#define sk_CONF_VALUE_num wolfSSL_sk_CONF_VALUE_num +#define sk_CONF_VALUE_value wolfSSL_sk_CONF_VALUE_value + +#define lh_CONF_VALUE_retrieve wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve + +#define NCONF_new wolfSSL_NCONF_new +#define NCONF_get_string wolfSSL_NCONF_get_string +#define NCONF_get_section wolfSSL_NCONF_get_section -typedef struct WOLFSSL_CONF_VALUE CONF_VALUE; -typedef struct WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/lhash.h b/wolfssl/openssl/lhash.h index 01f8535f8..ab3ee4642 100644 --- a/wolfssl/openssl/lhash.h +++ b/wolfssl/openssl/lhash.h @@ -1,2 +1,59 @@ +/* lhash.h + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + /* lhash.h for openSSL */ +#ifndef WOLFSSL_lhash_H_ +#define WOLFSSL_lhash_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include + +#ifdef OPENSSL_ALL +#define IMPLEMENT_LHASH_HASH_FN(name, type) \ + unsigned long name##_LHASH_HASH(const void *arg) \ + { \ + const o_type *a = arg; \ + return name##_hash(a); \ + } +#define IMPLEMENT_LHASH_COMP_FN(name, type) \ + int name##_LHASH_COMP(const void *p1, const void *p2) \ + { \ + const type *_p1 = p1; \ + const type *_p2 = p2; \ + return name##_cmp(_p1, _p2); \ + } + +WOLFSSL_API unsigned long wolfSSL_LH_strhash(const char *str); + +WOLFSSL_API void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data); + +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WOLFSSL_lhash_H_ */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index b477c8374..9430d1aa8 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1129,6 +1129,12 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #endif /* HAVE_STUNNEL || WOLFSSL_NGINX */ + +#ifndef NO_WOLFSSL_STUB +#define b2i_PrivateKey_bio(...) NULL +#define b2i_PVK_bio(...) NULL +#endif + #define SSL_CTX_get_default_passwd_cb wolfSSL_CTX_get_default_passwd_cb #define SSL_CTX_get_default_passwd_cb_userdata wolfSSL_CTX_get_default_passwd_cb_userdata @@ -1166,6 +1172,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #include #define OPENSSL_STRING WOLFSSL_STRING +#define OPENSSL_CSTRING WOLFSSL_STRING #define TLSEXT_TYPE_application_layer_protocol_negotiation 16 diff --git a/wolfssl/openssl/stack.h b/wolfssl/openssl/stack.h index b13923916..c13d715b9 100644 --- a/wolfssl/openssl/stack.h +++ b/wolfssl/openssl/stack.h @@ -36,7 +36,6 @@ WOLFSSL_API void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, wolfSSL_sk_freef WOLFSSL_API void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK *); WOLFSSL_API int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK *sk, void *data); WOLFSSL_API void wolfSSL_sk_pop_free(WOLFSSL_STACK *st, void (*func) (void *)); -WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk); WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_new_null(void); WOLFSSL_API int wolfSSL_sk_CIPHER_push(WOLFSSL_STACK *st,WOLFSSL_CIPHER *cipher); diff --git a/wolfssl/openssl/txt_db.h b/wolfssl/openssl/txt_db.h index 4fb940026..4865fcbb7 100644 --- a/wolfssl/openssl/txt_db.h +++ b/wolfssl/openssl/txt_db.h @@ -22,6 +22,12 @@ #ifndef WOLFSSL_TXT_DB_H_ #define WOLFSSL_TXT_DB_H_ +#include +struct WOLFSSL_TXT_DB { + WOLF_STACK_OF(WOLFSSL_STRING) *data; +}; + +typedef struct WOLFSSL_TXT_DB TXT_DB; #endif /* WOLFSSL_TXT_DB_H_ */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c1a0effbc..a3d5eb5a7 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -102,8 +102,8 @@ extern "C" { #endif -/* for now LHASH is not implemented */ -typedef int WOLFSSL_LHASH; +/* LHASH is implemented as a stack */ +typedef struct WOLFSSL_STACK WOLFSSL_LHASH; #ifndef WOLF_LHASH_OF #define WOLF_LHASH_OF(x) WOLFSSL_LHASH #endif @@ -2089,7 +2089,7 @@ WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_ #endif WOLFSSL_API int wolfSSL_sk_num(const WOLFSSL_STACK* sk); -WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i); +WOLFSSL_API void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i); #if (defined(HAVE_EX_DATA) || defined(FORTRESS)) && \ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)) @@ -3648,6 +3648,7 @@ WOLFSSL_API void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)*); typedef int (*wolf_sk_compare_cb)(const void* const *a, const void* const *b); +typedef unsigned long (*wolf_sk_hash_cb) (const void *v); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new( wolf_sk_compare_cb); WOLFSSL_API int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)*, diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index aef56f987..1db84de6d 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -495,11 +495,12 @@ decouple library dependencies with standard string, memory and so on. #define XSTRLEN(s1) strlen((s1)) #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) - /* strstr, strncmp, and strncat only used by wolfSSL proper, + /* strstr, strncmp, strcmp, and strncat only used by wolfSSL proper, * not required for wolfCrypt only */ #define XSTRSTR(s1,s2) strstr((s1),(s2)) #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) + #define XSTRCMP(s1,s2) strcmp((s1),(s2)) #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) #ifdef USE_WOLF_STRSEP From e7f1d39456156720f363999684f2694e249a4868 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Sat, 25 Jul 2020 00:47:59 +0200 Subject: [PATCH 14/53] OpenSSL Compat layer Implement WOLFSSL_CONF_VALUE: - wolfSSL_CONF_VALUE_new - wolfSSL_CONF_VALUE_new_values - wolfSSL_CONF_add_string - wolfSSL_X509V3_conf_free - wolfSSL_sk_CONF_VALUE_push - wolfSSL_NCONF_load - wolfSSL_NCONF_free - wolfSSL_CONF_new_section - wolfSSL_CONF_get_section Implment some buffer functions - wolfSSL_strlcat - wolfSSL_strlcpy --- src/ssl.c | 413 ++++++++++++++++++++++++++++++++++++++- wolfssl/openssl/asn1.h | 5 +- wolfssl/openssl/buffer.h | 4 + wolfssl/openssl/conf.h | 20 ++ wolfssl/openssl/lhash.h | 23 ++- wolfssl/openssl/ssl.h | 6 + wolfssl/openssl/txt_db.h | 4 + wolfssl/openssl/x509.h | 12 ++ wolfssl/ssl.h | 2 + 9 files changed, 478 insertions(+), 11 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index c6683b449..e23cd196b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -19191,9 +19191,174 @@ int wolfSSL_CONF_modules_load(const WOLFSSL_CONF *cnf, const char *appname, WOLFSSL_ENTER("wolfSSL_CONF_modules_load"); WOLFSSL_MSG("All wolfSSL modules are already compiled in. " "wolfSSL_CONF_modules_load doesn't load anything new."); + (void)cnf; + (void)appname; + (void)flags; return WOLFSSL_SUCCESS; } +WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void) +{ + WOLFSSL_CONF_VALUE* ret; + + WOLFSSL_ENTER("wolfSSL_CONF_new"); + + ret = (WOLFSSL_CONF_VALUE*)XMALLOC(sizeof(WOLFSSL_CONF_VALUE), + NULL, DYNAMIC_TYPE_OPENSSL); + if (ret) + XMEMSET(ret, 0, sizeof(WOLFSSL_CONF_VALUE)); + return ret; +} + +WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, + char* name, char* value) +{ + WOLFSSL_CONF_VALUE* ret; + int len; + + WOLFSSL_ENTER("wolfSSL_CONF_VALUE_new_values"); + + if (!(ret = wolfSSL_CONF_VALUE_new())) { + WOLFSSL_MSG("wolfSSL_CONF_VALUE_new error"); + return NULL; + } + + if (section) { + len = XSTRLEN(section); + ret->section = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret->section) { + WOLFSSL_MSG("malloc error"); + wolfSSL_X509V3_conf_free(ret); + return NULL; + } + } + + if (name) { + len = XSTRLEN(name); + ret->name = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret->name) { + WOLFSSL_MSG("malloc error"); + wolfSSL_X509V3_conf_free(ret); + return NULL; + } + } + + if (value) { + len = XSTRLEN(value); + ret->value = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret->value) { + WOLFSSL_MSG("malloc error"); + wolfSSL_X509V3_conf_free(ret); + return NULL; + } + } + + return ret; +} + +int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf, + WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value) +{ + WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL; + + if (!conf || !section || !value) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *)section->value; + value->section = section->section; + + if (wolfSSL_sk_CONF_VALUE_push(sk, value) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_sk_CONF_VALUE_push(conf->data, value) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + +WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf, + const char *section) +{ + WOLFSSL_CONF_VALUE* ret = NULL; + WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL; + int slen; + + WOLFSSL_ENTER("wolfSSL_CONF_new_section"); + + if (!conf || !section) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + slen = XSTRLEN(section); + + if (!(ret = wolfSSL_CONF_VALUE_new())) { + WOLFSSL_MSG("wolfSSL_CONF_new error"); + goto error; + } + + if (!(ret->section = (char*)XMALLOC(slen+1, NULL, DYNAMIC_TYPE_OPENSSL))) { + WOLFSSL_MSG("section malloc error"); + goto error; + } + + if (!(sk = wolfSSL_sk_CONF_VALUE_new(NULL))) { + WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_new error"); + goto error; + } + + ret->value = (char*)sk; + + if (wolfSSL_sk_CONF_VALUE_push(conf->data, ret) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error"); + goto error; + } + + return ret; +error: + if (ret) { + /* NULL so that wolfSSL_X509V3_conf_free doesn't attempt to free it */ + ret->value = NULL; + wolfSSL_X509V3_conf_free(ret); + } + if (sk) { + wolfSSL_sk_CONF_VALUE_free(sk); + } + return NULL; +} + +WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, + const char *section) +{ + WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL; + + WOLFSSL_ENTER("wolfSSL_CONF_get_section"); + + if (!conf || !section) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + sk = conf->data; + + while (sk) { + WOLFSSL_CONF_VALUE* val = sk->data.conf; + if (val) { + if (XSTRCMP(section, val->section) == 0) { + return val; + } + } + sk = sk->next; + } + + return NULL; +} + WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth) { WOLFSSL_CONF* ret; @@ -19279,6 +19444,191 @@ WOLFSSL_STACK *wolfSSL_NCONF_get_section( return NULL; } +#define SKIP_WHITESPACE(idx, max_idx) \ + while (idx < max_idx && (*idx == ' ' || *idx == '\t')) \ + {idx++;} +int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) +{ + int ret = WOLFSSL_FAILURE; + WOLFSSL_BIO *in = NULL; + char* buf = NULL; + char* idx = NULL; + char* bufEnd = NULL; + CONF_VALUE* section = NULL; + long line = 0; + int bufLen = 0; + + if (!conf || !file) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + /* Open file */ + if (!(in = wolfSSL_BIO_new_file(file, "rb"))) { + WOLFSSL_MSG("wolfSSL_BIO_new_file error"); + return WOLFSSL_FAILURE; + } + + /* Read file */ + bufLen = wolfSSL_BIO_get_len(in); + if (bufLen <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_get_len error"); + goto cleanup; + } + if (!(buf = (char*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("malloc error"); + goto cleanup; + } + if (wolfSSL_BIO_read(in, buf, bufLen) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_BIO_read error"); + goto cleanup; + } + + if (!(section = wolfSSL_CONF_new_section(conf, "default"))) { + WOLFSSL_MSG("wolfSSL_CONF_new_section error"); + goto cleanup; + } + + /* LETS START READING SOME CONFIGS */ + idx = buf; + bufEnd = buf + bufLen; + while (idx < bufEnd) { + char* lineEnd = XSTRNSTR(idx, "\n", bufEnd - idx); + char* maxIdx; + if (!lineEnd) + lineEnd = bufEnd; /* Last line in file */ + maxIdx = XSTRNSTR(idx, "#", lineEnd - idx); + if (!maxIdx) + maxIdx = lineEnd; + line++; + SKIP_WHITESPACE(idx, maxIdx); + if (idx == maxIdx) { + /* Empty line */ + idx = lineEnd + 1; + continue; + } + + if (*idx == '[') { + /* New section. Spaces not allowed in section name. */ + char* sectionName; + int sectionNameLen; + + SKIP_WHITESPACE(idx, maxIdx); + sectionName = idx; + /* Find end of section name */ + while (idx < maxIdx && *idx != ' ' && *idx != ']') + idx++; + sectionNameLen = idx - sectionName; + SKIP_WHITESPACE(idx, maxIdx); + + if (*idx != ']') { + WOLFSSL_MSG("Section definition error. " + "Closing brace not found."); + goto cleanup; + } + + sectionName[sectionNameLen] = '\0'; + if (!(section = wolfSSL_CONF_get_section(conf, sectionName))) + section = wolfSSL_CONF_new_section(conf, sectionName); + } + else { + char* name; + int nameLen; + char* value; + int valueLen; + WOLFSSL_CONF_VALUE* newVal = NULL; + + SKIP_WHITESPACE(idx, maxIdx); + name = idx; + /* Find end of name */ + while (idx < maxIdx && *idx != ' ' && *idx != '=') + idx++; + nameLen = idx - name; + SKIP_WHITESPACE(idx, maxIdx); + if (*idx != '=') { + WOLFSSL_MSG("Missing equals sign"); + goto cleanup; + } + idx++; + SKIP_WHITESPACE(idx, maxIdx); + value = idx; + /* Find end of value */ + idx = maxIdx; + while (*idx == ' ' || *idx == '\t') + idx--; + valueLen = idx - value; + + /* Sanity checks */ + if (nameLen <= 0 || valueLen <= 0) { + WOLFSSL_MSG("Sanity checks failed"); + goto cleanup; + } + name[nameLen] = '\0'; + value[valueLen] = '\0'; + + if (!(newVal = wolfSSL_CONF_VALUE_new_values(section->section, + name, value))) { + WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error"); + goto cleanup; + } + + if (wolfSSL_CONF_add_string(conf, section, newVal) != + WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_CONF_add_string error"); + goto cleanup; + } + } + idx = lineEnd + 1; + } + + ret = WOLFSSL_SUCCESS; +cleanup: + if (in) + wolfSSL_BIO_free(in); + if (buf) + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (eline) + *eline = line; + return ret; +} + + +void wolfSSL_NCONF_free(WOLFSSL_CONF *conf) +{ + WOLFSSL_ENTER("wolfSSL_NCONF_free"); + if (conf) { + wolfSSL_sk_CONF_VALUE_free(conf->data); + } +} + +void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val) +{ + WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL; + + if (val) { + if (val->name) { + /* Not a section. Don't free section as it is a shared pointer. */ + XFREE(val->name, NULL, DYNAMIC_TYPE_OPENSSL); + if (val->value) + XFREE(val->value, NULL, DYNAMIC_TYPE_OPENSSL); + } + else { + /* Section so val->value is a stack */ + if (val->section) + XFREE(val->section, NULL, DYNAMIC_TYPE_OPENSSL); + /* Only free the stack structures. The contained conf values + * will be freed in wolfSSL_NCONF_free */ + sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE)*)val->value; + while (sk) { + WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *tmp = sk->next; + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + sk = tmp; + } + } + XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc) { WOLFSSL_STACK* ret; @@ -19310,6 +19660,7 @@ void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk) while (node) { tmp = node; node = node->next; + wolfSSL_X509V3_conf_free(tmp->data.conf); XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); } @@ -19333,6 +19684,19 @@ WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value(const WOLFSSL_STACK *sk, int i) return NULL; } +/* return 1 on success 0 on fail */ +int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk, + WOLFSSL_CONF_VALUE* val) +{ + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_push"); + + if (sk == NULL || val == NULL) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_sk_push(sk, val); +} + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void) { WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); @@ -41263,6 +41627,37 @@ void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf) } /* End Functions for openssl/buffer.h */ +size_t wolfSSL_strlcpy(char *dst, const char *src, size_t dstSize) +{ + size_t i; + + if (!dstSize) + return 0; + + /* Always have to leave a space for NULL */ + for (i = 0; i < (dstSize - 1) && *src != '\0'; i++) { + *dst++ = *src++; + } + *dst = '\0'; + + return i; /* return length without NULL */ +} + +size_t wolfSSL_strlcat(char *dst, const char *src, size_t dstSize) +{ + size_t dstLen; + + if (!dstSize) + return 0; + + dstLen = XSTRLEN(dst); + + if (dstSize < dstLen) + return dstLen + XSTRLEN(src); + + return dstLen + wolfSSL_strlcpy(dst + dstLen, src, dstSize - dstLen); + +} #endif /* OPENSSL_EXTRA */ @@ -45627,7 +46022,23 @@ WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x) return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length); } -#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ +char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, + int idx) +{ + for (; idx > 0 && strings != NULL; idx--) + strings = strings->next; + if (strings == NULL) + return NULL; + return strings->data.string; +} + +int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) +{ + if (strings) + return strings->num; + return 0; +} +#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 3f11e4f0c..9eea76d9b 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -75,10 +75,13 @@ #define V_ASN1_UTF8STRING 12 #define V_ASN1_SEQUENCE 16 #define V_ASN1_SET 17 +#define V_ASN1_PRINTABLESTRING 19 +#define V_ASN1_T61STRING 20 #define V_ASN1_IA5STRING 22 #define V_ASN1_UTCTIME 23 #define V_ASN1_GENERALIZEDTIME 24 -#define V_ASN1_PRINTABLESTRING 19 +#define V_ASN1_UNIVERSALSTRING 28 +#define V_ASN1_BMPSTRING 30 #define V_ASN1_CONSTRUCTED 0x20 diff --git a/wolfssl/openssl/buffer.h b/wolfssl/openssl/buffer.h index 600c66eff..5f1946dda 100644 --- a/wolfssl/openssl/buffer.h +++ b/wolfssl/openssl/buffer.h @@ -34,6 +34,8 @@ WOLFSSL_API WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void); WOLFSSL_API int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len); WOLFSSL_API void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf); +WOLFSSL_API size_t wolfSSL_strlcpy(char *dst, const char *src, size_t dstSize); +WOLFSSL_API size_t wolfSSL_strlcat(char *dst, const char *src, size_t dstSize); #define BUF_MEM_new wolfSSL_BUF_MEM_new @@ -41,6 +43,8 @@ WOLFSSL_API void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf); #define BUF_MEM_free wolfSSL_BUF_MEM_free #define BUF_strdup strdup +#define BUF_strlcpy wolfSSL_strlcpy +#define BUF_strlcat wolfSSL_strlcat #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index bfceb602f..9898b44e7 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -49,35 +49,55 @@ typedef WOLFSSL_CONF CONF; typedef WOLFSSL_CONF_VALUE CONF_VALUE; typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void); +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, + char* name, char* value); +WOLFSSL_API int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf, + WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value); +WOLFSSL_API void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val); + WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc); WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(struct WOLFSSL_STACK *sk); WOLFSSL_API int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk); WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value( const struct WOLFSSL_STACK *sk, int i); +WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk, + WOLFSSL_CONF_VALUE* val); WOLFSSL_API WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth); WOLFSSL_API char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf, const char *group, const char *name); WOLFSSL_API WOLFSSL_STACK *wolfSSL_NCONF_get_section( const WOLFSSL_CONF *conf, const char *section); +WOLFSSL_API int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline); +WOLFSSL_API void wolfSSL_NCONF_free(WOLFSSL_CONF *conf); WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve( WOLF_LHASH_OF(WOLFSSL_CONF_VALUE) *sk, WOLFSSL_CONF_VALUE *data); WOLFSSL_API int wolfSSL_CONF_modules_load(const WOLFSSL_CONF *cnf, const char *appname, unsigned long flags); +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf, + const char *section); +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, + const char *section); #define sk_CONF_VALUE_new wolfSSL_sk_CONF_VALUE_new #define sk_CONF_VALUE_free wolfSSL_sk_CONF_VALUE_free +#define sk_CONF_VALUE_pop_free(a,b) wolfSSL_sk_CONF_VALUE_free(a) #define sk_CONF_VALUE_num wolfSSL_sk_CONF_VALUE_num #define sk_CONF_VALUE_value wolfSSL_sk_CONF_VALUE_value #define lh_CONF_VALUE_retrieve wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve +#define lh_CONF_VALUE_insert wolfSSL_sk_CONF_VALUE_push #define NCONF_new wolfSSL_NCONF_new #define NCONF_get_string wolfSSL_NCONF_get_string #define NCONF_get_section wolfSSL_NCONF_get_section +#define CONF_modules_load wolfSSL_CONF_modules_load + +#define X509V3_conf_free wolfSSL_X509V3_conf_free #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/lhash.h b/wolfssl/openssl/lhash.h index ab3ee4642..ee0fba18e 100644 --- a/wolfssl/openssl/lhash.h +++ b/wolfssl/openssl/lhash.h @@ -32,23 +32,28 @@ #ifdef OPENSSL_ALL #define IMPLEMENT_LHASH_HASH_FN(name, type) \ - unsigned long name##_LHASH_HASH(const void *arg) \ - { \ - const o_type *a = arg; \ - return name##_hash(a); \ + unsigned long wolfSSL_##name##_LHASH_HASH(const void *arg) \ + { \ + const type *a = arg; \ + return name##_hash(a); \ } #define IMPLEMENT_LHASH_COMP_FN(name, type) \ - int name##_LHASH_COMP(const void *p1, const void *p2) \ - { \ - const type *_p1 = p1; \ - const type *_p2 = p2; \ - return name##_cmp(_p1, _p2); \ + int wolfSSL_##name##_LHASH_COMP(const void *p1, const void *p2) \ + { \ + const type *_p1 = p1; \ + const type *_p2 = p2; \ + return name##_cmp(_p1, _p2); \ } +#define LHASH_HASH_FN(name) wolfSSL_##name##_LHASH_HASH +#define LHASH_COMP_FN(name) wolfSSL_##name##_LHASH_COMP + WOLFSSL_API unsigned long wolfSSL_LH_strhash(const char *str); WOLFSSL_API void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data); +#define lh_strhash wolfSSL_LH_strhash + #endif diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 9430d1aa8..bd1f7bc92 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -402,6 +402,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_get_ext_d2i wolfSSL_X509_get_ext_d2i #define X509V3_EXT_i2d wolfSSL_X509V3_EXT_i2d #define X509_get0_extensions wolfSSL_X509_get0_extensions +#define X509_get_extensions wolfSSL_X509_get0_extensions +#define X509_REQ_get_extensions wolfSSL_X509_get0_extensions #define X509_get_ext wolfSSL_X509_get_ext #define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID #define X509_get_issuer_name wolfSSL_X509_get_issuer_name @@ -1222,7 +1224,11 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_set_tlsext_ticket_key_cb wolfSSL_CTX_set_tlsext_ticket_key_cb #define SSL_CTX_set_tlsext_status_cb wolfSSL_CTX_set_tlsext_status_cb #define SSL_CTX_get_extra_chain_certs wolfSSL_CTX_get_extra_chain_certs +#define sk_OPENSSL_STRING_num wolfSSL_sk_WOLFSSL_STRING_num #define sk_OPENSSL_STRING_value wolfSSL_sk_WOLFSSL_STRING_value +#define sk_OPENSSL_PSTRING_num wolfSSL_sk_WOLFSSL_STRING_num +#define sk_OPENSSL_PSTRING_value wolfSSL_sk_WOLFSSL_STRING_value +#define sk_OPENSSL_STRING_free wolfSSL_sk_free #define SSL_get0_alpn_selected wolfSSL_get0_alpn_selected #define SSL_select_next_proto wolfSSL_select_next_proto #define SSL_CTX_set_alpn_select_cb wolfSSL_CTX_set_alpn_select_cb diff --git a/wolfssl/openssl/txt_db.h b/wolfssl/openssl/txt_db.h index 4865fcbb7..578463e34 100644 --- a/wolfssl/openssl/txt_db.h +++ b/wolfssl/openssl/txt_db.h @@ -26,6 +26,10 @@ struct WOLFSSL_TXT_DB { WOLF_STACK_OF(WOLFSSL_STRING) *data; + WOLF_LHASH_OF(WOLFSSL_STRING) **index; + long error; + long arg1; + long arg2; }; typedef struct WOLFSSL_TXT_DB TXT_DB; diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index dd98f3d30..bf7ae25e3 100644 --- a/wolfssl/openssl/x509.h +++ b/wolfssl/openssl/x509.h @@ -25,8 +25,20 @@ #define XN_FLAG_FN_SN 0 #define XN_FLAG_ONELINE 0 +#define XN_FLAG_COMPAT 0 #define XN_FLAG_RFC2253 1 +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) #define XN_FLAG_SEP_CPLUS_SPC (2 << 16) #define XN_FLAG_SEP_SPLUS_SPC (3 << 16) +#define XN_FLAG_SEP_MULTILINE (4 << 16) +#define XN_FLAG_SEP_MASK (0xF << 16) #define XN_FLAG_DN_REV (1 << 20) +#define XN_FLAG_FN_LN (1 << 21) +#define XN_FLAG_FN_OID (2 << 21) +#define XN_FLAG_FN_NONE (3 << 21) +#define XN_FLAG_FN_MASK (3 << 21) #define XN_FLAG_SPC_EQ (1 << 23) +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) +#define XN_FLAG_FN_ALIGN (1 << 25) + +#define XN_FLAG_MULTILINE 0xFFFF diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a3d5eb5a7..c9633ea7b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3902,6 +3902,8 @@ WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); +WOLFSSL_API int wolfSSL_sk_WOLFSSL_STRING_num( + WOLF_STACK_OF(WOLFSSL_STRING)* strings); #endif /* HAVE_OCSP || OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio, From 753a3babc8411ce65bc078f393643ac0eb8c081a Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 28 Jul 2020 23:05:37 +0200 Subject: [PATCH 15/53] OpenSSL Compat layer Implement/stub: - wolfSSL_NCONF_get_number - wolfSSL_EVP_PKEY_CTX_ctrl_str - wolfSSL_PKCS12_verify_mac - wc_PKCS12_verify_ex - wolfSSL_BIO_new_fd - wolfSSL_X509_sign_ctx - wolfSSL_ASN1_STRING_cmp - wolfSSL_ASN1_TIME_set_string - X509V3_EXT_add_nconf - X509V3_set_nconf Implement TXT_DB functionality: - wolfSSL_TXT_DB_read - wolfSSL_TXT_DB_free - wolfSSL_TXT_DB_create_index - wolfSSL_TXT_DB_get_by_index --- src/bio.c | 19 ++ src/ssl.c | 355 +++++++++++++++++++++++++++++++++++- wolfcrypt/src/evp.c | 14 +- wolfcrypt/src/pkcs12.c | 10 +- wolfssl/openssl/bio.h | 2 + wolfssl/openssl/conf.h | 5 + wolfssl/openssl/evp.h | 4 + wolfssl/openssl/pkcs12.h | 1 + wolfssl/openssl/ssl.h | 16 ++ wolfssl/openssl/txt_db.h | 22 ++- wolfssl/openssl/x509v3.h | 9 + wolfssl/ssl.h | 11 +- wolfssl/wolfcrypt/pkcs12.h | 2 + wolfssl/wolfcrypt/wc_port.h | 1 + 14 files changed, 465 insertions(+), 6 deletions(-) diff --git a/src/bio.c b/src/bio.c index dbf29bcbe..89a3e9d29 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1322,6 +1322,25 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) } #ifndef NO_FILESYSTEM +WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag) +{ + WOLFSSL_BIO* bio; + + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + if (!bio) { + WOLFSSL_MSG("wolfSSL_BIO_new error"); + return NULL; + } + + if (wolfSSL_BIO_set_fd(bio, fd, close_flag) != WOLFSSL_SUCCESS) { + wolfSSL_BIO_free(bio); + WOLFSSL_MSG("wolfSSL_BIO_set_fp error"); + return NULL; + } + + return bio; +} + long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c) { WOLFSSL_ENTER("wolfSSL_BIO_set_fp"); diff --git a/src/ssl.c b/src/ssl.c index e23cd196b..76a9f0392 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -111,6 +111,7 @@ #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) #include #include + #include #endif /* WITH_STUNNEL */ #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #include @@ -9832,6 +9833,14 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int lo return WOLFSSL_FAILURE; } +WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc) +{ + WOLFSSL_STUB("wolfSSL_X509_delete_ext"); + (void)x509; + (void)loc; + return NULL; +} + /* currently LHASH is not implemented (and not needed for Apache port) */ WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid( WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid, @@ -15493,6 +15502,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_ENTER("wolfSSL_BIO_set_fd"); if (b != NULL) { + if (b->type == WOLFSSL_BIO_FILE) { + b->ptr = XFDOPEN(fd, "rw"); + if (!b->ptr) { + WOLFSSL_MSG("Error opening file descriptor"); + return WOLFSSL_FAILURE; + } + } b->num = fd; b->shutdown = (byte)closeF; } @@ -19414,6 +19430,26 @@ char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf, return NULL; } +int wolfSSL_NCONF_get_number(const CONF *conf, const char *group, + const char *name, long *result) +{ + char *str; + WOLFSSL_ENTER("wolfSSL_NCONF_get_number"); + + if (!conf || !group || !name || !result) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (!(str = wolfSSL_NCONF_get_string(conf, group, name))) { + WOLFSSL_MSG("wolfSSL_NCONF_get_string error"); + return WOLFSSL_FAILURE; + } + + *result = atol(str); + return WOLFSSL_SUCCESS; +} + /** * The WOLFSSL_CONF->value member is treated as a * WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE) which becomes @@ -20495,6 +20531,44 @@ int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in) return inLen; } +int wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING *s) +{ + char *idx; + char *copy; + WOLFSSL_ENTER("wolfSSL_ASN1_UNIVERSALSTRING_to_string"); + + if (!s) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (s->type != V_ASN1_UNIVERSALSTRING) { + WOLFSSL_MSG("Input is not a universal string"); + return WOLFSSL_FAILURE; + } + + if ((s->length % 4) != 0) { + WOLFSSL_MSG("Input string must be divisible by 4"); + return WOLFSSL_FAILURE; + } + + for (idx = s->data; idx < s->data + s->length; idx += 4) + if ((idx[0] != '\0') || (idx[1] != '\0') || (idx[2] != '\0')) + break; + + if (idx != s->data + s->length) { + WOLFSSL_MSG("Wrong string format"); + return WOLFSSL_FAILURE; + } + + for (copy = idx = s->data; idx < s->data + s->length; idx += 4) + *copy++ = idx[3]; + *copy = '\0'; + s->length /= 4; + s->type = V_ASN1_PRINTABLESTRING; + return WOLFSSL_SUCCESS; +} + /* Returns string representation of ASN1_STRING */ char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, const WOLFSSL_ASN1_STRING *s) @@ -21012,6 +21086,175 @@ void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) /* free head of stack */ XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); } + +/** + * This function reads a tab delimetered CSV input and returns + * a populated WOLFSSL_TXT_DB structure. + * @param in Tab delimetered CSV input + * @param num Number of fields in each row. + * @return + */ +WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) +{ + WOLFSSL_TXT_DB *ret = NULL; + char *buf = NULL; + char *bufEnd = NULL; + char *idx = NULL; + char* lineEnd = NULL; + int bufSz; + int failed = 1; + /* Space in front of str reserved for field pointers + \0 */ + int fieldsSz = (num + 1) * sizeof(char *); + WOLFSSL_ENTER("wolfSSL_TXT_DB_read"); + + if (!in || num <= 0 || num > WOLFSSL_TXT_DB_MAX_FIELDS) { + WOLFSSL_MSG("Bad parameter or too many fields"); + return NULL; + } + + if (!(ret = (WOLFSSL_TXT_DB*)XMALLOC(sizeof(WOLFSSL_TXT_DB), NULL, + DYNAMIC_TYPE_OPENSSL))) { + WOLFSSL_MSG("malloc error"); + goto error; + } + XMEMSET (ret, 0, sizeof(WOLFSSL_TXT_DB)); + ret->num_fields = num; + + if (!(ret->data = wolfSSL_sk_WOLFSSL_STRING_new())) { + WOLFSSL_MSG("wolfSSL_sk_WOLFSSL_STRING_new error"); + goto error; + } + + bufSz = wolfSSL_BIO_get_len(in); + if (bufSz <= 0 || + !(buf = (char*)XMALLOC(sizeof(bufSz+1), NULL, + DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("malloc error or no data in BIO"); + goto error; + } + + if (wolfSSL_BIO_read(in, buf, bufSz) != bufSz) { + WOLFSSL_MSG("malloc error or no data in BIO"); + goto error; + } + + buf[bufSz] = '\0'; + for (bufEnd = buf + bufSz; idx < bufEnd; idx = lineEnd + 1) { + char* strBuf = NULL; + char** fieldPtr = NULL; + int fieldPtrIdx = 0; + char* fieldCheckIdx = NULL; + lineEnd = XSTRNSTR(idx, "\n", bufEnd - idx); + if (!lineEnd) + lineEnd = bufEnd; + if (idx == lineEnd) /* empty line */ + continue; + if (*idx == '#') + continue; + *lineEnd = '\0'; + strBuf = (char*)XMALLOC(fieldsSz + lineEnd - idx + 1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!strBuf) { + WOLFSSL_MSG("malloc error"); + goto error; + } + XMEMCPY(strBuf + fieldsSz, idx, lineEnd - idx + 1); /* + 1 for NULL */ + /* Check for appropriate number of fields */ + fieldPtr = (char**)strBuf; + fieldCheckIdx = strBuf + fieldsSz; + fieldPtr[fieldPtrIdx++] = fieldCheckIdx; + while (*fieldCheckIdx != '\0') { + if (*fieldCheckIdx == '\t') { + fieldPtr[fieldPtrIdx++] = fieldCheckIdx + 1; + *fieldCheckIdx = '\0'; + if (fieldPtrIdx > num) { + WOLFSSL_MSG("too many fields"); + XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL); + goto error; + } + } + fieldCheckIdx++; + } + if (fieldPtrIdx != num) { + WOLFSSL_MSG("wrong number of fields"); + XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL); + goto error; + } + if (wolfSSL_sk_push(ret->data, strBuf) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_push error"); + XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL); + goto error; + } + } + + failed = 0; +error: + if (failed && ret) { + XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL); + ret = NULL; + } + if (buf) { + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + return ret; +} + +void wolfSSL_TXT_DB_free(WOLFSSL_TXT_DB *db) +{ + if (db) { + if (db->data) { + wolfSSL_sk_free(db->data); + } + XFREE(db, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field, + void* qual, wolf_sk_hash_cb hash, wolf_sk_compare_cb cmp) +{ + WOLFSSL_ENTER("wolfSSL_TXT_DB_create_index"); + (void)qual; + + if (!db || !hash || !cmp || field >= db->num_fields || field < 0) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + db->hash_fn[field] = hash; + db->comp[field] = cmp; + + return WOLFSSL_SUCCESS; +} + +WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx, + WOLFSSL_STRING *value) +{ + WOLF_STACK_OF(WOLFSSL_STRING)* data; + WOLFSSL_ENTER("wolfSSL_TXT_DB_get_by_index"); + + if (!db || idx < 0 || idx >= db->num_fields) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + if (!db->hash_fn[idx] || !db->comp[idx]) { + WOLFSSL_MSG("Missing hash or cmp functions"); + return NULL; + } + + /* Set the hash and comp functions */ + data = db->data; + while (data) { + if (data->comp != db->comp[idx] || data->hash_fn != db->hash_fn[idx]) { + data->comp = db->comp[idx]; + data->hash_fn = db->hash_fn[idx]; + data->hash = 0; + } + data= data->next; + } + + return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value); +} #endif #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ @@ -21713,6 +21956,26 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) XFREE(asn1, NULL, DYNAMIC_TYPE_OPENSSL); } } + + int wolfSSL_ASN1_STRING_cmp(const WOLFSSL_ASN1_STRING *a, const WOLFSSL_ASN1_STRING *b) + { + int i; + WOLFSSL_ENTER("wolfSSL_ASN1_STRING_cmp"); + + if (!a || !b) { + return WOLFSSL_FATAL_ERROR; + } + + if (a->length != b->length) { + return a->length - b->length; + } + + if ((i = XMEMCMP(a->data, b->data, a->length)) != 0) { + return i; + } + + return a->type - b->type; + } #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ @@ -24024,6 +24287,19 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, return WOLFSSL_SUCCESS; } + +int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw, + int pswLen) +{ + WOLFSSL_ENTER("wolfSSL_PKCS12_verify_mac"); + + if (!pkcs12) { + return WOLFSSL_FAILURE; + } + + return wc_PKCS12_verify_ex(pkcs12, (const byte*)psw, pswLen) == 0 ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} #endif /* !NO_ASN && !NO_PWDBASED */ @@ -28264,13 +28540,21 @@ int wolfSSL_ASN1_TIME_diff(int *pday, int *psec, return 0; } -WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t) +WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t) { WOLFSSL_STUB("wolfSSL_ASN1_TIME_set"); (void)s; (void)t; return s; } + +int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str) +{ + WOLFSSL_STUB("wolfSSL_ASN1_TIME_set_string"); + (void)s; + (void)str; + return WOLFSSL_FAILURE; +} #endif /* !NO_WOLFSSL_STUB */ #ifndef NO_BIO @@ -39220,6 +39504,64 @@ cleanup: } #endif /* WOLFSSL_CERT_GEN */ + int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx) + { + WOLFSSL_ENTER("wolfSSL_X509_sign_ctx"); + + if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + return wolfSSL_X509_sign(x509, ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(ctx)); + } + + /* Converts the x509 name structure into DER format. + * + * out pointer to either a pre setup buffer or a pointer to null for + * creating a dynamic buffer. In the case that a pre-existing buffer is + * used out will be incremented the size of the DER buffer on success. + * + * returns the size of the buffer on success, or negative value with failure + */ + int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out) + { + CertName cName; + unsigned char buf[256]; /* ASN_MAX_NAME */ + int sz; + WOLFSSL_ENTER("wolfSSL_i2d_X509_NAME"); + + if (out == NULL || name == NULL) { + return BAD_FUNC_ARG; + } + XMEMSET(&cName, 0, sizeof(CertName)); + + if (CopyX509NameToCertName(name, &cName) != SSL_SUCCESS) { + WOLFSSL_MSG("Error converting x509 name to internal CertName"); + return SSL_FATAL_ERROR; + } + + sz = SetName(buf, sizeof(buf), &cName); + if (sz < 0) { + return sz; + } + + /* using buffer passed in */ + if (*out != NULL) { + XMEMCPY(*out, buf, sz); + *out += sz; + } + else { + *out = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL); + if (*out == NULL) { + return MEMORY_E; + } + XMEMCPY(*out, buf, sz); + } + + return sz; + } +#endif /* WOLFSSL_CERT_GEN */ #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name, @@ -46022,6 +46364,17 @@ WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x) return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length); } +WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) +{ + WOLF_STACK_OF(WOLFSSL_STRING)* ret = wolfSSL_sk_new_node(NULL); + + if (ret) { + ret->type = STACK_TYPE_STRING; + } + + return ret; +} + char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) { diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 77d579349..7215b13b7 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1432,7 +1432,19 @@ int wolfSSL_EVP_PKEY_derive_set_peer(WOLFSSL_EVP_PKEY_CTX *ctx, WOLFSSL_EVP_PKEY return WOLFSSL_SUCCESS; } -#if !defined(NO_DH) || defined(HAVE_ECC) +#ifndef NO_WOLFSSL_STUB +int wolfSSL_EVP_PKEY_CTX_ctrl_str(WOLFSSL_EVP_PKEY_CTX *ctx, + const char *name, const char *value) +{ + WOLFSSL_STUB("wolfSSL_EVP_PKEY_CTX_ctrl_str"); + (void)ctx; + (void)name; + (void)value; + return WOLFSSL_FAILURE; +} +#endif /* NO_WOLFSSL_STUB */ + +#if !defined(NO_DH) && defined(HAVE_ECC) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION!=2)) int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 705c63bfb..ca9a4e53e 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -569,7 +569,6 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, return kLen; /* same as digest size */ } - /* check mac on pkcs12, pkcs12->mac has been sanity checked before entering * * returns the result of comparison, success is 0 */ static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz, @@ -613,6 +612,15 @@ static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz, return XMEMCMP(digest, mac->digest, mac->digestSz); } +int wc_PKCS12_verify_ex(WC_PKCS12* pkcs12, const byte* psw, word32 pswSz) +{ + if (pkcs12 == NULL || pkcs12->safe == NULL) { + return BAD_FUNC_ARG; + } + return wc_PKCS12_verify(pkcs12, pkcs12->safe->data, pkcs12->safe->dataSz, + psw, pswSz); +} + /* Convert DER format stored in der buffer to WC_PKCS12 struct * Puts the raw contents of Content Info into structure without completely diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 3218ad69f..d112f038f 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -57,6 +57,7 @@ #define BIO_set_write_buf_size wolfSSL_BIO_set_write_buf_size #define BIO_make_bio_pair wolfSSL_BIO_make_bio_pair +#define BIO_new_fd wolfSSL_BIO_new_fd #define BIO_set_fp wolfSSL_BIO_set_fp #define BIO_get_fp wolfSSL_BIO_get_fp #define BIO_seek wolfSSL_BIO_seek @@ -123,6 +124,7 @@ #define BIO_meth_set_create wolfSSL_BIO_meth_set_create #define BIO_meth_set_destroy wolfSSL_BIO_meth_set_destroy +#define BIO_snprintf XSNPRINTF /* BIO CTRL */ #define BIO_CTRL_RESET 1 diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index 9898b44e7..9dbe20ae0 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -67,6 +67,8 @@ WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk WOLFSSL_API WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth); WOLFSSL_API char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf, const char *group, const char *name); +WOLFSSL_API int wolfSSL_NCONF_get_number(const CONF *conf, const char *group, + const char *name, long *result); WOLFSSL_API WOLFSSL_STACK *wolfSSL_NCONF_get_section( const WOLFSSL_CONF *conf, const char *section); WOLFSSL_API int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline); @@ -92,8 +94,11 @@ WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, #define lh_CONF_VALUE_insert wolfSSL_sk_CONF_VALUE_push #define NCONF_new wolfSSL_NCONF_new +#define NCONF_free wolfSSL_NCONF_free #define NCONF_get_string wolfSSL_NCONF_get_string #define NCONF_get_section wolfSSL_NCONF_get_section +#define NCONF_get_number wolfSSL_NCONF_get_number +#define NCONF_load wolfSSL_NCONF_load #define CONF_modules_load wolfSSL_CONF_modules_load diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index fa1065a9d..d928becc7 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -557,6 +557,9 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_derive_init(WOLFSSL_EVP_PKEY_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_PKEY_derive_set_peer(WOLFSSL_EVP_PKEY_CTX *ctx, WOLFSSL_EVP_PKEY *peer); WOLFSSL_API int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_ctrl_str(WOLFSSL_EVP_PKEY_CTX *ctx, + const char *name, const char *value); + WOLFSSL_API int wolfSSL_EVP_PKEY_decrypt(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); @@ -830,6 +833,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_PKEY_type wolfSSL_EVP_PKEY_type #define EVP_PKEY_base_id wolfSSL_EVP_PKEY_base_id #define EVP_PKEY_id wolfSSL_EVP_PKEY_id +#define EVP_PKEY_CTX_ctrl_str wolfSSL_EVP_PKEY_CTX_ctrl_str #define EVP_SignFinal wolfSSL_EVP_SignFinal #define EVP_SignInit wolfSSL_EVP_SignInit #define EVP_SignInit_ex wolfSSL_EVP_SignInit_ex diff --git a/wolfssl/openssl/pkcs12.h b/wolfssl/openssl/pkcs12.h index bcd994c57..8f4011319 100644 --- a/wolfssl/openssl/pkcs12.h +++ b/wolfssl/openssl/pkcs12.h @@ -42,6 +42,7 @@ /* wolfSSL level using structs from ssl.h and calls down to wolfCrypt */ #define d2i_PKCS12_bio wolfSSL_d2i_PKCS12_bio #define PKCS12_parse wolfSSL_PKCS12_parse +#define PKCS12_verify_mac wolfSSL_PKCS12_verify_mac #define PKCS12_create wolfSSL_PKCS12_create #define PKCS12_PBE_add wolfSSL_PKCS12_PBE_add diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index bd1f7bc92..f390be82f 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -436,7 +436,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_set_version wolfSSL_X509_set_version #define X509_REQ_set_version wolfSSL_X509_set_version #define X509_sign wolfSSL_X509_sign +#define X509_sign_ctx wolfSSL_X509_sign_ctx #define X509_print wolfSSL_X509_print +#define X509_REQ_print wolfSSL_X509_print #define X509_print_ex wolfSSL_X509_print_ex #define X509_print_fp wolfSSL_X509_print_fp #define X509_REQ_print_fp wolfSSL_X509_print_fp @@ -445,6 +447,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_verify wolfSSL_X509_verify #define X509_REQ_verify wolfSSL_X509_REQ_verify #define X509_check_private_key wolfSSL_X509_check_private_key +#define X509_REQ_check_private_key wolfSSL_X509_check_private_key #define X509_check_ca wolfSSL_X509_check_ca #define X509_check_host wolfSSL_X509_check_host #define X509_check_ip_asc wolfSSL_X509_check_ip_asc @@ -452,6 +455,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_check_issued wolfSSL_X509_check_issued #define X509_dup wolfSSL_X509_dup #define X509_add_ext wolfSSL_X509_add_ext +#define X509_delete_ext wolfSSL_X509_delete_ext #define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object #define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data @@ -686,10 +690,16 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define sk_ASN1_OBJECT_free wolfSSL_sk_ASN1_OBJECT_free +#define ASN1_TIME_new wolfSSL_ASN1_TIME_new +#define ASN1_UTCTIME_new wolfSSL_ASN1_TIME_new #define ASN1_TIME_free wolfSSL_ASN1_TIME_free +#define ASN1_UTCTIME_free wolfSSL_ASN1_TIME_free #define ASN1_TIME_adj wolfSSL_ASN1_TIME_adj #define ASN1_TIME_print wolfSSL_ASN1_TIME_print #define ASN1_TIME_to_generalizedtime wolfSSL_ASN1_TIME_to_generalizedtime +#define ASN1_TIME_set wolfSSL_ASN1_TIME_set +#define ASN1_TIME_set_string wolfSSL_ASN1_TIME_set_string +#define ASN1_TIME_to_string wolfSSL_ASN1_TIME_to_string #define ASN1_GENERALIZEDTIME_print wolfSSL_ASN1_GENERALIZEDTIME_print #define ASN1_GENERALIZEDTIME_free wolfSSL_ASN1_GENERALIZEDTIME_free @@ -707,14 +717,20 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define i2a_ASN1_OBJECT wolfSSL_i2a_ASN1_OBJECT #define i2d_ASN1_OBJECT wolfSSL_i2d_ASN1_OBJECT +#define ASN1_STRING_new wolfSSL_ASN1_STRING_new +#define ASN1_STRING_free wolfSSL_ASN1_STRING_free +#define ASN1_STRING_cmp wolfSSL_ASN1_STRING_cmp #define ASN1_STRING_data wolfSSL_ASN1_STRING_data #define ASN1_STRING_get0_data wolfSSL_ASN1_STRING_data #define ASN1_STRING_length wolfSSL_ASN1_STRING_length #define ASN1_STRING_to_UTF8 wolfSSL_ASN1_STRING_to_UTF8 +#define ASN1_UNIVERSALSTRING_to_string wolfSSL_ASN1_UNIVERSALSTRING_to_string #define ASN1_STRING_print_ex wolfSSL_ASN1_STRING_print_ex #define ASN1_STRING_print(x, y) wolfSSL_ASN1_STRING_print ((WOLFSSL_BIO*)(x), (WOLFSSL_ASN1_STRING*)(y)) #define d2i_DISPLAYTEXT wolfSSL_d2i_DISPLAYTEXT +#define ASN1_PRINTABLE_type(...) V_ASN1_PRINTABLESTRING + #define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr #define ASN1_IA5STRING WOLFSSL_ASN1_STRING diff --git a/wolfssl/openssl/txt_db.h b/wolfssl/openssl/txt_db.h index 578463e34..7fcc29f94 100644 --- a/wolfssl/openssl/txt_db.h +++ b/wolfssl/openssl/txt_db.h @@ -24,14 +24,32 @@ #include +#define WOLFSSL_TXT_DB_MAX_FIELDS 10 + struct WOLFSSL_TXT_DB { + int num_fields; WOLF_STACK_OF(WOLFSSL_STRING) *data; - WOLF_LHASH_OF(WOLFSSL_STRING) **index; long error; long arg1; long arg2; + wolf_sk_compare_cb comp[WOLFSSL_TXT_DB_MAX_FIELDS]; + wolf_sk_hash_cb hash_fn[WOLFSSL_TXT_DB_MAX_FIELDS]; }; -typedef struct WOLFSSL_TXT_DB TXT_DB; +typedef struct WOLFSSL_TXT_DB WOLFSSL_TXT_DB; + +WOLFSSL_API WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num); +WOLFSSL_API void wolfSSL_TXT_DB_free(WOLFSSL_TXT_DB *db); +WOLFSSL_API int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field, + void* qual, wolf_sk_hash_cb hash, wolf_sk_compare_cb cmp); +WOLFSSL_API WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, + int idx, WOLFSSL_STRING *value); + +#define TXT_DB WOLFSSL_TXT_DB + +#define TXT_DB_read wolfSSL_TXT_DB_read +#define TXT_DB_free wolfSSL_TXT_DB_free +#define TXT_DB_create_index wolfSSL_TXT_DB_create_index +#define TXT_DB_get_by_index wolfSSL_TXT_DB_get_by_index #endif /* WOLFSSL_TXT_DB_H_ */ diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index cf4691a4d..406481bf4 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -83,6 +83,8 @@ struct WOLFSSL_X509_EXTENSION { #define X509V3_CTX WOLFSSL_X509V3_CTX +#define CTX_TEST 0x1 + typedef struct WOLFSSL_AUTHORITY_KEYID AUTHORITY_KEYID; typedef struct WOLFSSL_BASIC_CONSTRAINTS BASIC_CONSTRAINTS; typedef struct WOLFSSL_ACCESS_DESCRIPTION ACCESS_DESCRIPTION; @@ -107,10 +109,17 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, #define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING #define X509V3_EXT_get wolfSSL_X509V3_EXT_get #define X509V3_EXT_d2i wolfSSL_X509V3_EXT_d2i +#ifndef NO_WOLFSSL_STUB +#define X509V3_EXT_add_nconf(...) 0 +#endif #define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING #define X509V3_EXT_print wolfSSL_X509V3_EXT_print #define X509V3_EXT_conf_nid wolfSSL_X509V3_EXT_conf_nid #define X509V3_set_ctx wolfSSL_X509V3_set_ctx +#ifndef NO_WOLFSSL_STUB +#define X509V3_set_nconf(...) +#endif +#define X509V3_set_ctx_test(ctx) wolfSSL_X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) #define X509V3_set_ctx_nodb wolfSSL_X509V3_set_ctx_nodb #define X509v3_get_ext_count wolfSSL_sk_num diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c9633ea7b..68dbe1950 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1171,6 +1171,7 @@ WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_pop_free( WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, void (*f)(WOLFSSL_ASN1_OBJECT*)); WOLFSSL_API int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in); +WOLFSSL_API int wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING *s); WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value( WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx); @@ -1286,6 +1287,7 @@ WOLFSSL_API void wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr); #ifndef NO_FILESYSTEM WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_file(void); +WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag); #endif WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void); @@ -1396,6 +1398,7 @@ WOLFSSL_API int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_API int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v); WOLFSSL_API int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_MD* md); +WOLFSSL_API int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx); WOLFSSL_API int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME*); @@ -1410,6 +1413,7 @@ WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_dup(WOLFSSL_ASN1_STRING* as WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type); WOLFSSL_API int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1); WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING **asn, const unsigned char **in, long len); +WOLFSSL_API int wolfSSL_ASN1_STRING_cmp(const WOLFSSL_ASN1_STRING *a, const WOLFSSL_ASN1_STRING *b); WOLFSSL_API void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1); WOLFSSL_API int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int dataSz); @@ -1454,7 +1458,7 @@ WOLFSSL_API void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX*); WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL*); WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL*); -WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509*); WOLFSSL_API int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL*, WOLFSSL_EVP_PKEY*); @@ -2086,6 +2090,7 @@ WOLFSSL_API int wolfSSL_ASN1_TIME_diff(int *pday, int *psec, const WOLFSSL_ASN1_TIME *from, const WOLFSSL_ASN1_TIME *to); #ifdef OPENSSL_EXTRA WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t); +WOLFSSL_API int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str); #endif WOLFSSL_API int wolfSSL_sk_num(const WOLFSSL_STACK* sk); @@ -2238,6 +2243,8 @@ WOLFSSL_API WOLFSSL_X509_PKCS12* wolfSSL_d2i_PKCS12_fp(XFILE fp, WOLFSSL_API int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, WOLF_STACK_OF(WOLFSSL_X509)** ca); +WOLFSSL_API int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw, + int pswLen); WOLFSSL_API WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, WOLFSSL_EVP_PKEY* pkey, WOLFSSL_X509* cert, WOLF_STACK_OF(WOLFSSL_X509)* ca, @@ -3385,6 +3392,7 @@ WOLFSSL_API int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509 *x, int nid, int WOLFSSL_API int wolfSSL_X509_add_ext(WOLFSSL_X509 *x, WOLFSSL_X509_EXTENSION *ex, int loc); WOLFSSL_API WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit, void *data); +WOLFSSL_API WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid( WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid, char* value); @@ -3900,6 +3908,7 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 * WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void); WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); WOLFSSL_API int wolfSSL_sk_WOLFSSL_STRING_num( diff --git a/wolfssl/wolfcrypt/pkcs12.h b/wolfssl/wolfcrypt/pkcs12.h index 7082b6279..362c8bf57 100644 --- a/wolfssl/wolfcrypt/pkcs12.h +++ b/wolfssl/wolfcrypt/pkcs12.h @@ -53,6 +53,8 @@ WOLFSSL_API int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz); WOLFSSL_API int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, byte** pkey, word32* pkeySz, byte** cert, word32* certSz, WC_DerCertList** ca); +WOLFSSL_LOCAL int wc_PKCS12_verify_ex(WC_PKCS12* pkcs12, + const byte* psw, word32 pswSz); WOLFSSL_API WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name, byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca, int nidKey, int nidCert, int iter, int macIter, diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 2657739ca..b00cb9ff0 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -599,6 +599,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #else #define XFOPEN fopen #endif + #define XFDOPEN fdopen #define XFSEEK fseek #define XFTELL ftell #define XREWIND rewind From ff2574b3cbab74b210042614128af388338cc923 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 29 Jul 2020 23:46:08 +0200 Subject: [PATCH 16/53] OpenSSL Compat layer Implment/stub: - wolfSSL_X509_NAME_delete_entry - wolfSSL_X509_get_ext_by_OBJ - wolfSSL_a2i_ASN1_INTEGER - X509V3_parse_list - wolfSSL_TXT_DB_write - wolfSSL_TXT_DB_insert - wolfSSL_EVP_PKEY_get_default_digest_nid --- configure.ac | 4 +- src/ssl.c | 350 +++++++++++++++++++++++++++++++++---- wolfcrypt/src/evp.c | 16 +- wolfssl/openssl/dh.h | 1 + wolfssl/openssl/evp.h | 6 +- wolfssl/openssl/opensslv.h | 2 +- wolfssl/openssl/ssl.h | 2 + wolfssl/openssl/txt_db.h | 4 + wolfssl/openssl/x509v3.h | 1 + wolfssl/ssl.h | 6 + 10 files changed, 347 insertions(+), 45 deletions(-) diff --git a/configure.ac b/configure.ac index 3d222f01b..e449615e4 100644 --- a/configure.ac +++ b/configure.ac @@ -702,7 +702,7 @@ AC_ARG_ENABLE([mcast], # signal (--enable-signal) # lighty (--enable-lighty) HAVE_LIGHTY # stunnel (--enable-stunnel) HAVE_STUNNEL -# libest (--enable-libest) +# libest (--enable-libest) HAVE_LIBEST # asio (--enable-asio) WOLFSSL_ASIO # libwebsockets (--enable-libwebsockets) WOLFSSL_LIBWEBSOCKETS # qt (--enable-qt) WOLFSSL_QT @@ -4250,7 +4250,7 @@ AC_ARG_ENABLE([libest], if test "$ENABLED_LIBEST" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA" + AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DHAVE_LIBEST" # Requires opensslextra and opensslall if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" diff --git a/src/ssl.c b/src/ssl.c index 76a9f0392..bd538526c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8290,6 +8290,30 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc) return ext; } +int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, + const WOLFSSL_ASN1_OBJECT *obj, int lastpos) +{ + const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION) *sk; + + if (!x || !obj) { + WOLFSSL_MSG("Bad parameter"); + return -1; + } + + sk = wolfSSL_X509_get0_extensions(x); + if (!sk) { + WOLFSSL_MSG("No extensions"); + return -1; + } + lastpos++; + if (lastpos < 0) + lastpos = 0; + for (; lastpos < wolfSSL_sk_num(sk); lastpos++) + if (wolfSSL_OBJ_cmp(wolfSSL_sk_value(sk, lastpos), obj) == 0) + return lastpos; + return -1; +} + /* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509. * This is currently a helper function for wolfSSL_X509_get_ext * Caller does not free the returned WOLFSSL_X509_EXTENSION* @@ -21164,7 +21188,8 @@ WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) fieldCheckIdx = strBuf + fieldsSz; fieldPtr[fieldPtrIdx++] = fieldCheckIdx; while (*fieldCheckIdx != '\0') { - if (*fieldCheckIdx == '\t') { + /* Handle escaped tabs */ + if (*fieldCheckIdx == '\t' && fieldCheckIdx[-1] != '\\') { fieldPtr[fieldPtrIdx++] = fieldCheckIdx + 1; *fieldCheckIdx = '\0'; if (fieldPtrIdx > num) { @@ -21199,8 +21224,94 @@ error: return ret; } +long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db) +{ + const WOLF_STACK_OF(WOLFSSL_STRING)* data; + long totalLen = 0; + char buf[512]; /* Should be more than enough for a single row */ + char* bufEnd = buf + sizeof(buf); + int sz; + int i; + + WOLFSSL_ENTER("wolfSSL_TXT_DB_write"); + + if (!out || !db || !db->num_fields) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + data = db->data; + while (data) { + char** fields = (char**)data->data.string; + char* idx = buf; + + if (!fields) { + WOLFSSL_MSG("Missing row"); + return WOLFSSL_FAILURE; + } + + for (i = 0; i < db->num_fields; i++) { + char* fieldValue = fields[i]; + if (!fieldValue) { + WOLFSSL_MSG("Missing fields ptr"); + return WOLFSSL_FAILURE; + } + + /* Copy over field escaping tabs */ + while (*fieldValue != '\0') { + if (idx+1 < bufEnd) { + if (*fieldValue == '\t') + *idx++ = '\\'; + *idx++ = *fieldValue++; + } + else { + WOLFSSL_MSG("Data row is too big"); + return WOLFSSL_FAILURE; + } + } + if (idx < bufEnd) { + *idx++ = '\t'; + } + else { + WOLFSSL_MSG("Data row is too big"); + return WOLFSSL_FAILURE; + } + } + idx[-1] = '\n'; + sz = idx - buf; + + if (wolfSSL_BIO_write(out, buf, sz) != sz) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + totalLen += sz; + + data = data->next; + } + + return totalLen; +} + +int wolfSSL_TXT_DB_insert(WOLFSSL_TXT_DB *db, WOLFSSL_STRING *row) +{ + WOLFSSL_ENTER("wolfSSL_TXT_DB_insert"); + + if (!db || !row || !db->data) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_sk_push(db->data, row) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_push error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + void wolfSSL_TXT_DB_free(WOLFSSL_TXT_DB *db) { + WOLFSSL_ENTER("wolfSSL_TXT_DB_free"); if (db) { if (db->data) { wolfSSL_sk_free(db->data); @@ -40711,6 +40822,7 @@ err: { int ret; WOLFSSL_X509_NAME_ENTRY* entry; + WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_NID"); entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); if (entry == NULL) @@ -40719,6 +40831,40 @@ err: wolfSSL_X509_NAME_ENTRY_free(entry); return ret; } + + WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry( + WOLFSSL_X509_NAME *name, int loc) + { + WOLFSSL_X509_NAME_ENTRY* ret; + WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry"); + + if (!name) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + ret = wolfSSL_X509_NAME_get_entry(name, loc); + if (!ret) { + WOLFSSL_MSG("loc entry not found"); + return NULL; + } + + if (loc <= DN_NAMES_MAX + name->fullName.dcNum) { + name->fullName.loc[loc] = ASN_DN_NULL; + } + else if (name->fullName.dcMode) { + if (name->fullName.fullName != NULL) { + if (loc == name->fullName.dcNum) { + name->fullName.dcNum = 0; + } + else { + name->fullName.dcIdx[loc] = -1; + } + } + } + + return ret; + } #endif /* !NO_CERTS */ @@ -41583,7 +41729,37 @@ err: if (name->entry[loc].set) { return &name->entry[loc]; } - else { + /* DC component */ + if (name->fullName.dcMode) { + if (name->fullName.fullName != NULL){ + if (loc == name->fullName.dcNum){ + name->cnEntry.data.data + = &name->fullName.fullName[name->fullName.cIdx]; + name->cnEntry.data.length = name->fullName.cLen; + name->cnEntry.nid = ASN_COUNTRY_NAME; + } + else if (name->fullName.dcIdx[loc] >= 0) { + name->cnEntry.data.data + = &name->fullName.fullName[name->fullName.dcIdx[loc]]; + name->cnEntry.data.length = name->fullName.dcLen[loc]; + name->cnEntry.nid = ASN_DOMAIN_COMPONENT; + } + else { + WOLFSSL_MSG("loc passed in is not in range of parsed DN's"); + return NULL; + } + } + name->cnEntry.data.type = CTC_UTF8; + /* common name index case */ + } else if (loc == name->fullName.cnIdx && name->x509 != NULL) { + /* get CN shortcut from x509 since it has null terminator */ + name->cnEntry.data.data = name->x509->subjectCN; + name->cnEntry.data.length = name->fullName.cnLen; + name->cnEntry.data.type = CTC_UTF8; + name->cnEntry.nid = ASN_COMMON_NAME; + name->cnEntry.set = 1; + } else { + WOLFSSL_MSG("loc passed in is not in range of parsed DN's"); return NULL; } } @@ -45861,14 +46037,138 @@ WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl) #endif /* NO_SESSION_CACHE */ +int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername) +{ + int ret; + DecodedCert dCert; + + WOLFSSL_ENTER("wolfSSL_X509_check_host"); + + /* flags and peername not needed for Nginx. */ + (void)flags; + (void)peername; + + if (flags == WOLFSSL_NO_WILDCARDS) { + WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented"); + return WOLFSSL_FAILURE; + } + + InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL); + ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL); + if (ret != 0) { + FreeDecodedCert(&dCert); + return WOLFSSL_FAILURE; + } + + ret = CheckHostName(&dCert, (char *)chk, chklen); + FreeDecodedCert(&dCert); + if (ret != 0) + return WOLFSSL_FAILURE; + return WOLFSSL_SUCCESS; +} + #ifndef NO_BIO +int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, + char *buf, int size) +{ + int readNextLine; + int lineLen; + int len; + byte isNumCheck; + word32 outLen; + const int extraTagSz = MAX_LENGTH_SZ - 1; + + WOLFSSL_ENTER("wolfSSL_a2i_ASN1_INTEGER"); + + if (!bio || !asn1 || !buf || size <= 0) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + /* Reset asn1 */ + if (asn1->isDynamic && asn1->data) { + XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL); + asn1->isDynamic = 0; + } + XMEMSET(asn1->intData, 0, sizeof(WOLFSSL_ASN1_INTEGER)); + asn1->data = asn1->intData; + asn1->length = 0; + asn1->negative = 0; + asn1->type = V_ASN1_INTEGER; + + lineLen = wolfSSL_BIO_gets(bio, buf, size); + do { + readNextLine = 0; + if (lineLen <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_gets error"); + return WOLFSSL_FAILURE; + } + while (lineLen && buf[lineLen-1] == '\n' && buf[lineLen-1] == '\r') + lineLen--; + if (buf[lineLen-1] == '\\') + readNextLine = 1; + /* Ignore none-hex chars at the end of the line */ + outLen = 1; + while (lineLen && Base16_Decode((byte*)buf + lineLen - 1, 1, + &isNumCheck, &outLen) == ASN_INPUT_E) + lineLen--; + if (!lineLen || lineLen % 2) { + WOLFSSL_MSG("Invalid line length"); + return WOLFSSL_FAILURE; + } + len = asn1->length + (lineLen/2); + /* Check if it will fit in static memory and + * save space for the ASN tag in front */ + if (len > (int)(sizeof(asn1->intData) - extraTagSz)) { + /* Allocate mem for data */ + if (asn1->isDynamic) { + byte* tmp = XREALLOC(asn1->data, len + extraTagSz, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!tmp) { + WOLFSSL_MSG("realloc error"); + return WOLFSSL_FAILURE; + } + asn1->data = tmp; + } + else { + asn1->data = XMALLOC(len + extraTagSz, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!asn1->data) { + WOLFSSL_MSG("malloc error"); + return WOLFSSL_FAILURE; + } + XMEMCPY(asn1->data, asn1->intData, asn1->length); + } + } + len = lineLen/2; + if (Base16_Decode((byte*)buf, lineLen, asn1->data + asn1->length, + (word32*)&len) != 0) { + WOLFSSL_MSG("Base16_Decode error"); + return WOLFSSL_FAILURE; + } + asn1->length += len; + } while (readNextLine); + + /* Write ASN tag */ + outLen = SetLength(asn1->length, NULL); + if (asn1->data[0] == 0x80) + outLen++; /* Special ASN integer case */ + XMEMMOVE(asn1->data + outLen + 1, asn1->data, asn1->length); + asn1->data[0] = ASN_INTEGER; + (void)SetLength(asn1->length, asn1->data + 1); + if (asn1->data[outLen+1] == 0x80) + asn1->data[outLen] = 0; + + return WOLFSSL_SUCCESS; +} + int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a) { - static char num[16] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - int i; - word32 j; - word32 len = 0; + word32 idx = 1; + int len = 0; + byte buf[512]; + word32 bufLen = 512; WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER"); @@ -45876,32 +46176,9 @@ int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a) return WOLFSSL_FAILURE; /* Skip ASN.1 INTEGER (type) byte. */ - i = 1; - /* When indefinite length, can't determine length with data available. */ - if (a->data[i] == 0x80) + if (a->data[idx] == 0x80 || /* Indefinite length, can't determine length */ + GetLength(a->data, &idx, &len, a->length) < 0) { return 0; - /* One length byte if less than 0x80. */ - if (a->data[i] < 0x80) - len = a->data[i++]; - /* Multiple length byte if greater than 0x80. */ - else if (a->data[i] > 0x80) { - switch (a->data[i++] - 0x80) { - case 4: - len |= a->data[i++] << 24; - FALL_THROUGH; - case 3: - len |= a->data[i++] << 16; - FALL_THROUGH; - case 2: - len |= a->data[i++] << 8; - FALL_THROUGH; - case 1: - len |= a->data[i++]; - break; - default: - /* Not supporting greater than 4 bytes of length. */ - return 0; - } } /* Zero length integer is the value zero. */ @@ -45910,14 +46187,11 @@ int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a) return 2; } - /* Don't do negative - just write out every byte. */ - for (j = 0; j < len; i++,j++) { - wolfSSL_BIO_write(bp, &num[a->data[i] >> 4], 1); - wolfSSL_BIO_write(bp, &num[a->data[i] & 0xf], 1); + if (Base16_Encode(a->data + idx, len, buf, &bufLen) != 0) { + return 0; } - /* Two nibbles written for each byte. */ - return len * 2; + return wolfSSL_BIO_write(bp, buf, bufLen); } #endif /* !NO_BIO */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 7215b13b7..74f6294dc 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6494,7 +6494,7 @@ int wolfSSL_EVP_PKEY_type(int type) } -int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey) +int wolfSSL_EVP_PKEY_id(const WOLFSSL_EVP_PKEY *pkey) { if (pkey != NULL) return pkey->type; @@ -6502,13 +6502,25 @@ int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey) } -int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey) +int wolfSSL_EVP_PKEY_base_id(const WOLFSSL_EVP_PKEY *pkey) { if (pkey == NULL) return NID_undef; return wolfSSL_EVP_PKEY_type(pkey->type); } +int wolfSSL_EVP_PKEY_get_default_digest_nid(WOLFSSL_EVP_PKEY *pkey, int *pnid) +{ + (void)pkey; +#ifndef NO_SHA256 + if (pnid) { + *pnid = NID_sha256; + } + return WOLFSSL_SUCCESS; +#else + return -2; +#endif +} /* increments ref count of WOLFSSL_EVP_PKEY. Return 1 on success, 0 on error */ int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey) diff --git a/wolfssl/openssl/dh.h b/wolfssl/openssl/dh.h index ac4d7e1a0..6fb896c84 100644 --- a/wolfssl/openssl/dh.h +++ b/wolfssl/openssl/dh.h @@ -26,6 +26,7 @@ #define WOLFSSL_DH_H_ #include +#include #ifdef __cplusplus extern "C" { diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index d928becc7..2ee0cc28c 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -575,8 +575,9 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b); WOLFSSL_API int wolfSSL_EVP_PKEY_type(int type); -WOLFSSL_API int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey); -WOLFSSL_API int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_id(const WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_base_id(const WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_get_default_digest_nid(WOLFSSL_EVP_PKEY *pkey, int *pnid); WOLFSSL_API int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_SignInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type); @@ -832,6 +833,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_PKEY_cmp wolfSSL_EVP_PKEY_cmp #define EVP_PKEY_type wolfSSL_EVP_PKEY_type #define EVP_PKEY_base_id wolfSSL_EVP_PKEY_base_id +#define EVP_PKEY_get_default_digest_nid wolfSSL_EVP_PKEY_get_default_digest_nid #define EVP_PKEY_id wolfSSL_EVP_PKEY_id #define EVP_PKEY_CTX_ctrl_str wolfSSL_EVP_PKEY_CTX_ctrl_str #define EVP_SignFinal wolfSSL_EVP_SignFinal diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index 2199cdf6a..4b32dcc7e 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -30,7 +30,7 @@ defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x10100000L) ||\ defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x10001040L) /* valid version */ -#elif defined(WOLFSSL_APACHE_HTTPD) +#elif defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIBEST) /* For Apache httpd, Use 1.1.0 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10100000L #elif defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || \ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index f390be82f..7174c2c0a 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -346,6 +346,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_MODE_RELEASE_BUFFERS 0x00000010U #define ASN1_BOOLEAN WOLFSSL_ASN1_BOOLEAN #define X509_get_ext wolfSSL_X509_get_ext + #define X509_get_ext_by_OBJ wolfSSL_X509_get_ext_by_OBJ #define X509_cmp wolfSSL_X509_cmp #define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object #define X509_EXTENSION_get_critical wolfSSL_X509_EXTENSION_get_critical @@ -705,6 +706,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ASN1_tag2str wolfSSL_ASN1_tag2str +#define a2i_ASN1_INTEGER wolfSSL_a2i_ASN1_INTEGER #define i2a_ASN1_INTEGER wolfSSL_i2a_ASN1_INTEGER #define i2c_ASN1_INTEGER wolfSSL_i2c_ASN1_INTEGER #define ASN1_INTEGER_new wolfSSL_ASN1_INTEGER_new diff --git a/wolfssl/openssl/txt_db.h b/wolfssl/openssl/txt_db.h index 7fcc29f94..a3e0fd362 100644 --- a/wolfssl/openssl/txt_db.h +++ b/wolfssl/openssl/txt_db.h @@ -39,6 +39,8 @@ struct WOLFSSL_TXT_DB { typedef struct WOLFSSL_TXT_DB WOLFSSL_TXT_DB; WOLFSSL_API WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num); +WOLFSSL_API long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db); +WOLFSSL_API int wolfSSL_TXT_DB_insert(WOLFSSL_TXT_DB *db, WOLFSSL_STRING *row); WOLFSSL_API void wolfSSL_TXT_DB_free(WOLFSSL_TXT_DB *db); WOLFSSL_API int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field, void* qual, wolf_sk_hash_cb hash, wolf_sk_compare_cb cmp); @@ -48,6 +50,8 @@ WOLFSSL_API WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, #define TXT_DB WOLFSSL_TXT_DB #define TXT_DB_read wolfSSL_TXT_DB_read +#define TXT_DB_write wolfSSL_TXT_DB_write +#define TXT_DB_insert wolfSSL_TXT_DB_insert #define TXT_DB_free wolfSSL_TXT_DB_free #define TXT_DB_create_index wolfSSL_TXT_DB_create_index #define TXT_DB_get_by_index wolfSSL_TXT_DB_get_by_index diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index 406481bf4..ba8a73051 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -111,6 +111,7 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, #define X509V3_EXT_d2i wolfSSL_X509V3_EXT_d2i #ifndef NO_WOLFSSL_STUB #define X509V3_EXT_add_nconf(...) 0 +#define X509V3_parse_list(...) NULL #endif #define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING #define X509V3_EXT_print wolfSSL_X509V3_EXT_print diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 68dbe1950..d1b79c60a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3360,6 +3360,8 @@ WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name, WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid, int type, const unsigned char *bytes, int len, int loc, int set); +WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry( + WOLFSSL_X509_NAME *name, int loc); WOLFSSL_API int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x, const WOLFSSL_X509_NAME* y); WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void); @@ -3418,6 +3420,8 @@ WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx, WOLFSSL_API int wolfSSL_X509_cmp(const WOLFSSL_X509* a, const WOLFSSL_X509* b); WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x, int loc); +WOLFSSL_API int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, + const WOLFSSL_ASN1_OBJECT *obj, int lastpos); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x, int loc); WOLFSSL_API int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void); @@ -4008,6 +4012,8 @@ WOLFSSL_API unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t); WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t, WOLFSSL_ASN1_TIME **out); WOLFSSL_API int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp); +WOLFSSL_API int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, + char *buf, int size); WOLFSSL_API int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE *store); WOLFSSL_API long wolfSSL_X509_get_version(const WOLFSSL_X509 *x); WOLFSSL_API int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509* x); From aaba7ed2861dee915bd150d1d9c2b70ff2da1189 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 31 Jul 2020 18:57:12 +0200 Subject: [PATCH 17/53] OpenSSL Compat layer Implement/stub: - wolfSSL_X509V3_EXT_add_nconf - wolfSSL_EVP_PKEY_copy_parameters --- src/ssl.c | 105 ++++++++++++++++++++++++++++++++------- wolfcrypt/src/asn.c | 2 +- wolfcrypt/src/evp.c | 91 +++++++++++++++++++++++++++++++++ wolfssl/openssl/evp.h | 2 + wolfssl/openssl/ssl.h | 8 +++ wolfssl/openssl/x509v3.h | 4 +- wolfssl/ssl.h | 6 +-- 7 files changed, 194 insertions(+), 24 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index bd538526c..855530c29 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8862,6 +8862,20 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, } #endif /* !NO_BIO */ +#ifndef NO_WOLFSSL_STUB +int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx, + const char *section, WOLFSSL_X509 *cert) +{ + WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf"); + WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf"); + (void)conf; + (void)ctx; + (void)section; + (void)cert; + return WOLFSSL_SUCCESS; +} +#endif + /* Returns crit flag in X509_EXTENSION object */ int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex) { @@ -18726,6 +18740,9 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) sizeof(WOLFSSL_CIPHER)) == 0) { sk->data.cipher = *(WOLFSSL_CIPHER*)data; sk->num = 1; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(&sk->data.cipher); + } return WOLFSSL_SUCCESS; } break; @@ -18735,6 +18752,9 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) if (!sk->data.generic) { sk->data.generic = (void*)data; sk->num = 1; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(sk->data.generic); + } return WOLFSSL_SUCCESS; } break; @@ -19265,32 +19285,35 @@ WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, if (section) { len = XSTRLEN(section); - ret->section = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); if (!ret->section) { WOLFSSL_MSG("malloc error"); wolfSSL_X509V3_conf_free(ret); return NULL; } + XMEMCPY(ret->section, section, len+1); } if (name) { len = XSTRLEN(name); - ret->name = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); if (!ret->name) { WOLFSSL_MSG("malloc error"); wolfSSL_X509V3_conf_free(ret); return NULL; } + XMEMCPY(ret->name, name, len+1); } if (value) { len = XSTRLEN(value); - ret->value = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); if (!ret->value) { WOLFSSL_MSG("malloc error"); wolfSSL_X509V3_conf_free(ret); return NULL; } + XMEMCPY(ret->value, value, len+1); } return ret; @@ -19346,6 +19369,7 @@ WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf, WOLFSSL_MSG("section malloc error"); goto error; } + XMEMCPY(ret->section, section, slen+1); if (!(sk = wolfSSL_sk_CONF_VALUE_new(NULL))) { WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_new error"); @@ -19409,8 +19433,14 @@ WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth) } ret = (WOLFSSL_CONF*)XMALLOC(sizeof(WOLFSSL_CONF), NULL, DYNAMIC_TYPE_OPENSSL); - if (ret) + if (ret) { XMEMSET(ret, 0, sizeof(WOLFSSL_CONF)); + ret->data = wolfSSL_sk_CONF_VALUE_new(NULL); + if (!ret->data) { + wolfSSL_NCONF_free(ret); + return NULL; + } + } return ret; } @@ -19539,7 +19569,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) WOLFSSL_MSG("malloc error"); goto cleanup; } - if (wolfSSL_BIO_read(in, buf, bufLen) != WOLFSSL_SUCCESS) { + if (wolfSSL_BIO_read(in, buf, bufLen) != bufLen) { WOLFSSL_MSG("wolfSSL_BIO_read error"); goto cleanup; } @@ -19573,6 +19603,13 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) char* sectionName; int sectionNameLen; + if (idx < maxIdx) + idx++; + else { + WOLFSSL_MSG("Invalid section definition."); + goto cleanup; + } + SKIP_WHITESPACE(idx, maxIdx); sectionName = idx; /* Find end of section name */ @@ -19613,10 +19650,10 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) SKIP_WHITESPACE(idx, maxIdx); value = idx; /* Find end of value */ - idx = maxIdx; + idx = maxIdx-1; while (*idx == ' ' || *idx == '\t') idx--; - valueLen = idx - value; + valueLen = idx - value + 1; /* Sanity checks */ if (nameLen <= 0 || valueLen <= 0) { @@ -21151,7 +21188,7 @@ WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) bufSz = wolfSSL_BIO_get_len(in); if (bufSz <= 0 || - !(buf = (char*)XMALLOC(sizeof(bufSz+1), NULL, + !(buf = (char*)XMALLOC(bufSz+1, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { WOLFSSL_MSG("malloc error or no data in BIO"); goto error; @@ -21163,6 +21200,7 @@ WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) } buf[bufSz] = '\0'; + idx = buf; for (bufEnd = buf + bufSz; idx < bufEnd; idx = lineEnd + 1) { char* strBuf = NULL; char** fieldPtr = NULL; @@ -21183,6 +21221,7 @@ WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) goto error; } XMEMCPY(strBuf + fieldsSz, idx, lineEnd - idx + 1); /* + 1 for NULL */ + XMEMSET(strBuf, 0, fieldsSz); /* Check for appropriate number of fields */ fieldPtr = (char**)strBuf; fieldCheckIdx = strBuf + fieldsSz; @@ -25063,8 +25102,8 @@ void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl) { WOLFSSL_ENTER("wolfSSL_X509_CRL_free"); - FreeCRL(crl, 1); - return; + if (crl) + FreeCRL(crl, 1); } #endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */ @@ -28661,10 +28700,24 @@ WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t) int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str) { - WOLFSSL_STUB("wolfSSL_ASN1_TIME_set_string"); - (void)s; - (void)str; - return WOLFSSL_FAILURE; + int slen; + WOLFSSL_ENTER("wolfSSL_ASN1_TIME_set_string"); + + if (!str) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + slen = XSTRLEN(str)+1; + if (slen > CTC_DATE_SIZE) { + WOLFSSL_MSG("Date string too long"); + return WOLFSSL_FAILURE; + } + if (s) { + XMEMCPY(s->data, str, slen); + s->length = slen; + s->type = slen == ASN_UTC_TIME_SIZE ? ASN_UTC_TIME : ASN_GENERALIZED_TIME; + } + return WOLFSSL_SUCCESS; } #endif /* !NO_WOLFSSL_STUB */ @@ -40850,7 +40903,10 @@ err: } if (loc <= DN_NAMES_MAX + name->fullName.dcNum) { - name->fullName.loc[loc] = ASN_DN_NULL; + XMEMMOVE(&name->fullName.loc[loc], &name->fullName.loc[loc+1], + DN_NAMES_MAX + name->fullName.dcNum - loc - 1); + if (name->fullName.dcNum > 0) + name->fullName.dcNum--; } else if (name->fullName.dcMode) { if (name->fullName.fullName != NULL) { @@ -40862,6 +40918,12 @@ err: } } } + else if (loc == name->fullName.cnIdx && name->x509 != NULL) { + name->fullName.cnIdx = -1; + } + else { + WOLFSSL_MSG("Couldn't find name entry"); + } return ret; } @@ -46104,7 +46166,7 @@ int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, WOLFSSL_MSG("wolfSSL_BIO_gets error"); return WOLFSSL_FAILURE; } - while (lineLen && buf[lineLen-1] == '\n' && buf[lineLen-1] == '\r') + while (lineLen && (buf[lineLen-1] == '\n' || buf[lineLen-1] == '\r')) lineLen--; if (buf[lineLen-1] == '\\') readNextLine = 1; @@ -46157,8 +46219,13 @@ int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, XMEMMOVE(asn1->data + outLen + 1, asn1->data, asn1->length); asn1->data[0] = ASN_INTEGER; (void)SetLength(asn1->length, asn1->data + 1); - if (asn1->data[outLen+1] == 0x80) + if (asn1->data[outLen+1] == 0x80) { asn1->data[outLen] = 0; + asn1->dataMax = asn1->length += 1 + outLen + 1; + } + else { + asn1->dataMax = asn1->length += 1 + outLen; + } return WOLFSSL_SUCCESS; } @@ -46649,14 +46716,14 @@ WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) return ret; } -char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, +WOLFSSL_STRING* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) { for (; idx > 0 && strings != NULL; idx--) strings = strings->next; if (strings == NULL) return NULL; - return strings->data.string; + return (WOLFSSL_STRING*)strings->data.string; } int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index efbdc078a..33f909daa 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -9443,7 +9443,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) int ret = 0; int checkPathLen = 0; int decrementMaxPathLen = 0; - word32 confirmOID; + word32 confirmOID = 0; #if defined(WOLFSSL_RENESAS_TSIP) int idx = 0; #endif diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 74f6294dc..8dd4773db 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1885,6 +1885,87 @@ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) return 0; } + +int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, + const WOLFSSL_EVP_PKEY *from) +{ + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_copy_parameters"); + + if (!to || !from) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (to->type == EVP_PKEY_NONE) { + to->type = from->type; + } + else if (to->type != from->type) { + WOLFSSL_MSG("Different key types"); + return WOLFSSL_FAILURE; + } + + switch(from->type) { +#ifdef HAVE_ECC + case EVP_PKEY_EC: + if (from->ecc) { + if (!to->ecc && !(to->ecc = wolfSSL_EC_KEY_new())) { + WOLFSSL_MSG("wolfSSL_EC_KEY_new error"); + return WOLFSSL_FAILURE; + } + to->ecc->group->curve_idx = from->ecc->group->curve_idx; + to->ecc->group->curve_nid = from->ecc->group->curve_nid; + to->ecc->group->curve_oid = from->ecc->group->curve_oid; + } + else { + WOLFSSL_MSG("Missing ECC struct"); + return WOLFSSL_FAILURE; + } + break; +#endif +#ifndef NO_DSA + case EVP_PKEY_DSA: + if (from->dsa) { + WOLFSSL_BIGNUM cpy; + if (!to->dsa && !(to->dsa = wolfSSL_DSA_new())) { + WOLFSSL_MSG("wolfSSL_DSA_new error"); + return WOLFSSL_FAILURE; + } + if (!(cpy = wolfSSL_BN_dup(from->dsa->p))) { + WOLFSSL_MSG("wolfSSL_BN_dup error"); + return WOLFSSL_FAILURE; + } + to->dsa->p = cpy; + if (!(cpy = wolfSSL_BN_dup(from->dsa->q)) { + WOLFSSL_MSG("wolfSSL_BN_dup error"); + return WOLFSSL_FAILURE; + } + to->dsa->q = cpy; + if (!(cpy = wolfSSL_BN_dup(from->dsa->g)) { + WOLFSSL_MSG("wolfSSL_BN_dup error"); + return WOLFSSL_FAILURE; + } + to->dsa->g = cpy; + } + else { + WOLFSSL_MSG("Missing DSA struct"); + return WOLFSSL_FAILURE; + } + break; +#endif +#ifndef NO_RSA + case EVP_PKEY_RSA: +#endif +#ifndef NO_DH + case EVP_PKEY_DH: +#endif + default: + WOLFSSL_MSG("Copy parameters not available for this key type"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + #ifndef NO_WOLFSSL_STUB WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey) { @@ -3183,11 +3264,21 @@ const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) {"SHA", "SHA1"}, { NULL, NULL} }; + char nameUpper[15]; /* 15 bytes should be enough for any name */ + size_t i; const struct alias *al; const struct s_ent *ent; + for (i = 0; i < sizeof(nameUpper) && name[i] != '\0'; i++) { + nameUpper[i] = XTOUPPER(name[i]); + } + if (i < sizeof(nameUpper)) + nameUpper[i] = '\0'; + else + return NULL; + name = nameUpper; for (al = alias_tbl; al->name != NULL; al++) if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) { name = al->name; diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 2ee0cc28c..9848921c1 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -572,6 +572,7 @@ WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_EVP_PKEY_new(void); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_ex(void* heap); WOLFSSL_API void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY*); WOLFSSL_API int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, const WOLFSSL_EVP_PKEY *from); WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b); WOLFSSL_API int wolfSSL_EVP_PKEY_type(int type); @@ -829,6 +830,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_PKEY_free wolfSSL_EVP_PKEY_free #define EVP_PKEY_up_ref wolfSSL_EVP_PKEY_up_ref #define EVP_PKEY_size wolfSSL_EVP_PKEY_size +#define EVP_PKEY_copy_parameters wolfSSL_EVP_PKEY_copy_parameters #define EVP_PKEY_missing_parameters wolfSSL_EVP_PKEY_missing_parameters #define EVP_PKEY_cmp wolfSSL_EVP_PKEY_cmp #define EVP_PKEY_type wolfSSL_EVP_PKEY_type diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 7174c2c0a..5b2b05e36 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -505,6 +505,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_NAME_add_entry wolfSSL_X509_NAME_add_entry #define X509_NAME_add_entry_by_txt wolfSSL_X509_NAME_add_entry_by_txt #define X509_NAME_add_entry_by_NID wolfSSL_X509_NAME_add_entry_by_NID +#define X509_NAME_delete_entry wolfSSL_X509_NAME_delete_entry #define X509_NAME_oneline wolfSSL_X509_NAME_oneline #define X509_NAME_get_index_by_NID wolfSSL_X509_NAME_get_index_by_NID #define X509_NAME_print_ex wolfSSL_X509_NAME_print_ex @@ -730,6 +731,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ASN1_STRING_print_ex wolfSSL_ASN1_STRING_print_ex #define ASN1_STRING_print(x, y) wolfSSL_ASN1_STRING_print ((WOLFSSL_BIO*)(x), (WOLFSSL_ASN1_STRING*)(y)) #define d2i_DISPLAYTEXT wolfSSL_d2i_DISPLAYTEXT +#ifndef NO_WOLFSSL_STUB +#define ASN1_STRING_set_default_mask_asc(...) 1 +#endif #define ASN1_PRINTABLE_type(...) V_ASN1_PRINTABLESTRING @@ -1303,6 +1307,10 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define OpenSSL_version(x) wolfSSL_OpenSSL_version() +#ifndef NO_WOLFSSL_STUB +#define OBJ_create_objects(...) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index ba8a73051..75e128a4f 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -101,6 +101,8 @@ WOLFSSL_API char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, const WOLFSSL_ASN1_STRING *s); WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, unsigned long flag, int indent); +WOLFSSL_API int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx, + const char *section, WOLFSSL_X509 *cert); #define BASIC_CONSTRAINTS_free wolfSSL_BASIC_CONSTRAINTS_free #define AUTHORITY_KEYID_free wolfSSL_AUTHORITY_KEYID_free @@ -109,8 +111,8 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, #define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING #define X509V3_EXT_get wolfSSL_X509V3_EXT_get #define X509V3_EXT_d2i wolfSSL_X509V3_EXT_d2i +#define X509V3_EXT_add_nconf wolfSSL_X509V3_EXT_add_nconf #ifndef NO_WOLFSSL_STUB -#define X509V3_EXT_add_nconf(...) 0 #define X509V3_parse_list(...) NULL #endif #define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index d1b79c60a..71e046d0f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3658,8 +3658,8 @@ WOLFSSL_API void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* void (*f) (WOLFSSL_X509_INFO*)); WOLFSSL_API void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)*); -typedef int (*wolf_sk_compare_cb)(const void* const *a, - const void* const *b); +typedef int (*wolf_sk_compare_cb)(const void* a, + const void* b); typedef unsigned long (*wolf_sk_hash_cb) (const void *v); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new( wolf_sk_compare_cb); @@ -3913,7 +3913,7 @@ WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void); -WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( +WOLFSSL_API WOLFSSL_STRING* wolfSSL_sk_WOLFSSL_STRING_value( WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); WOLFSSL_API int wolfSSL_sk_WOLFSSL_STRING_num( WOLF_STACK_OF(WOLFSSL_STRING)* strings); From 8e62bf25889f5007769d31edc052af1eea682dfc Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 3 Aug 2020 14:38:25 +0200 Subject: [PATCH 18/53] Pass libest estclient_simple example --- src/ssl.c | 98 ++++++++++++++++++++++++++--------------- wolfcrypt/src/asn.c | 2 +- wolfssl/openssl/ssl.h | 2 +- wolfssl/ssl.h | 2 +- wolfssl/wolfcrypt/asn.h | 1 + 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 855530c29..793c1ee88 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -19769,7 +19769,7 @@ int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk) { WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_num"); if (sk) - wolfSSL_sk_num(sk); + return wolfSSL_sk_num(sk); return 0; } @@ -21290,10 +21290,9 @@ long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db) } for (i = 0; i < db->num_fields; i++) { - char* fieldValue = fields[i]; + const char* fieldValue = fields[i]; if (!fieldValue) { - WOLFSSL_MSG("Missing fields ptr"); - return WOLFSSL_FAILURE; + fieldValue = ""; } /* Copy over field escaping tabs */ @@ -23815,7 +23814,6 @@ static int wolfSSL_i2d_X509_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, i } #endif - if (wolfSSL_X509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) { goto cleanup; } @@ -28813,7 +28811,7 @@ void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) case STACK_TYPE_X509_EXT: return (void*)sk->data.ext; case STACK_TYPE_CONF_VALUE: - return (void*)sk->data.conf->value; + return (void*)sk->data.conf; case STACK_TYPE_NULL: default: return (void*)sk->data.generic; @@ -30459,6 +30457,9 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFS { WOLFSSL_ASN1_INTEGER* a; int len; + const int extraTagSz = MAX_LENGTH_SZ + 1; + byte intTag[MAX_LENGTH_SZ + 1]; + int idx = 0; WOLFSSL_ENTER("wolfSSL_BN_to_ASN1_INTEGER"); if (ai == NULL) { @@ -30483,9 +30484,10 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFS len = 1; /* allocate buffer */ - if (len > (int)sizeof(a->intData)) { + if (len + extraTagSz > (int)sizeof(a->intData)) { /* create new data buffer and copy over */ - a->data = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL); + a->data = (byte*)XMALLOC(len + extraTagSz, NULL, + DYNAMIC_TYPE_OPENSSL); if (a->data == NULL) { if (a != ai) wolfSSL_ASN1_INTEGER_free(a); @@ -30497,7 +30499,6 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFS XMEMSET(a->intData, 0, sizeof(a->intData)); a->data = a->intData; } - a->length = len; /* populate data */ if (wolfSSL_BN_is_zero(bn)) { @@ -30507,6 +30508,12 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFS len = wolfSSL_BN_bn2bin(bn, a->data); } a->length = len; + + /* Write ASN tag */ + idx = SetASNInt(a->length, a->data[0], intTag); + XMEMMOVE(a->data + idx, a->data, a->length); + XMEMCPY(a->data, intTag, idx); + a->dataMax = a->length += idx; } return a; @@ -42895,10 +42902,15 @@ int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert) { - byte* pem; + byte* pem = NULL; int pemSz = 0; - const unsigned char* der; - int derSz; + /* Get large buffer to hold cert der */ + int derSz = 8192; +#ifdef WOLFSSL_SMALL_STACK + byte* der; +#else + byte der[8192]; +#endif int ret; WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()"); @@ -42908,25 +42920,31 @@ int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert) return WOLFSSL_FAILURE; } - der = wolfSSL_X509_get_der(cert, &derSz); - if (der == NULL) { +#ifdef WOLFSSL_SMALL_STACK + der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!der) { + WOLFSSL_MSG("malloc failed"); return WOLFSSL_FAILURE; } +#endif + + if (wolfSSL_X509_make_der(cert, 0, der, &derSz, 1) != WOLFSSL_SUCCESS) { + goto error; + } /* get PEM size */ pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE); if (pemSz < 0) { - return WOLFSSL_FAILURE; + goto error; } /* create PEM buffer and convert from DER */ pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - return WOLFSSL_FAILURE; + goto error; } if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) { - XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + goto error; } /* write the PEM to BIO */ @@ -42935,6 +42953,14 @@ int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert) if (ret <= 0) return WOLFSSL_FAILURE; return WOLFSSL_SUCCESS; + +error: + #ifdef WOLFSSL_SMALL_STACK + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + if (pem) + XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; } #endif /* !NO_BIO */ @@ -46139,7 +46165,9 @@ int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, int len; byte isNumCheck; word32 outLen; - const int extraTagSz = MAX_LENGTH_SZ - 1; + const int extraTagSz = MAX_LENGTH_SZ + 1; + byte intTag[MAX_LENGTH_SZ + 1]; + int idx = 0; WOLFSSL_ENTER("wolfSSL_a2i_ASN1_INTEGER"); @@ -46213,19 +46241,10 @@ int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, } while (readNextLine); /* Write ASN tag */ - outLen = SetLength(asn1->length, NULL); - if (asn1->data[0] == 0x80) - outLen++; /* Special ASN integer case */ - XMEMMOVE(asn1->data + outLen + 1, asn1->data, asn1->length); - asn1->data[0] = ASN_INTEGER; - (void)SetLength(asn1->length, asn1->data + 1); - if (asn1->data[outLen+1] == 0x80) { - asn1->data[outLen] = 0; - asn1->dataMax = asn1->length += 1 + outLen + 1; - } - else { - asn1->dataMax = asn1->length += 1 + outLen; - } + idx = SetASNInt(asn1->length, asn1->data[0], intTag); + XMEMMOVE(asn1->data + idx, asn1->data, asn1->length); + XMEMCPY(asn1->data, intTag, idx); + asn1->dataMax = asn1->length += idx; return WOLFSSL_SUCCESS; } @@ -46254,11 +46273,12 @@ int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a) return 2; } - if (Base16_Encode(a->data + idx, len, buf, &bufLen) != 0) { + if (Base16_Encode(a->data + idx, len, buf, &bufLen) != 0 || + bufLen <= 0) { return 0; } - return wolfSSL_BIO_write(bp, buf, bufLen); + return wolfSSL_BIO_write(bp, buf, bufLen - 1); /* Don't write out NULL char */ } #endif /* !NO_BIO */ @@ -46716,14 +46736,14 @@ WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) return ret; } -WOLFSSL_STRING* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, +WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) { for (; idx > 0 && strings != NULL; idx--) strings = strings->next; if (strings == NULL) return NULL; - return (WOLFSSL_STRING*)strings->data.string; + return strings->data.string; } int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) @@ -51004,6 +51024,12 @@ void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer, if (!ctx || !ctx->x509) return; + if (!ctx->x509) { + ctx->x509 = wolfSSL_X509_new(); + if (!ctx->x509) + return; + } + /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */ if (issuer) ret = wolfSSL_X509_set_issuer_name(ctx->x509,&issuer->issuer); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 33f909daa..e5062c3d8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -647,7 +647,7 @@ const char* GetSigName(int oid) { * output Buffer to write into. * returns the number of bytes added to the buffer. */ -static int SetASNInt(int len, byte firstByte, byte* output) +int SetASNInt(int len, byte firstByte, byte* output) { word32 idx = 0; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 5b2b05e36..2736f39d3 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1249,7 +1249,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define sk_OPENSSL_STRING_num wolfSSL_sk_WOLFSSL_STRING_num #define sk_OPENSSL_STRING_value wolfSSL_sk_WOLFSSL_STRING_value #define sk_OPENSSL_PSTRING_num wolfSSL_sk_WOLFSSL_STRING_num -#define sk_OPENSSL_PSTRING_value wolfSSL_sk_WOLFSSL_STRING_value +#define sk_OPENSSL_PSTRING_value (WOLFSSL_STRING*)wolfSSL_sk_WOLFSSL_STRING_value #define sk_OPENSSL_STRING_free wolfSSL_sk_free #define SSL_get0_alpn_selected wolfSSL_get0_alpn_selected #define SSL_select_next_proto wolfSSL_select_next_proto diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 71e046d0f..2d65d76d6 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3913,7 +3913,7 @@ WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void); -WOLFSSL_API WOLFSSL_STRING* wolfSSL_sk_WOLFSSL_STRING_value( +WOLFSSL_API WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value( WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); WOLFSSL_API int wolfSSL_sk_WOLFSSL_STRING_num( WOLF_STACK_OF(WOLFSSL_STRING)* strings); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 88742f5ae..dc8112552 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1157,6 +1157,7 @@ WOLFSSL_LOCAL int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz); WOLFSSL_LOCAL int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz); WOLFSSL_LOCAL int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); #endif +WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output); WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); From 2e2beb279d57ad35d51a15e1335eaea59c801f3f Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 5 Aug 2020 14:32:55 +0200 Subject: [PATCH 19/53] WIP --- src/ssl.c | 49 ++++++++++++++++++++++++++++++++++++++++- wolfssl/openssl/ec.h | 3 +++ wolfssl/openssl/ssl.h | 4 ++++ wolfssl/ssl.h | 7 ++++++ wolfssl/wolfcrypt/asn.h | 1 + 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 793c1ee88..75a33fba6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -22989,7 +22989,40 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) #endif /* XSNPRINTF */ #endif /* !NO_BIO */ -#endif /* OPENSSL_EXTRA */ + int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp, + const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig) + { + WOLFSSL_ENTER("wolfSSL_X509_signature_print"); + + if (!bp || !sigalg || !sig) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_puts(bp, " Signature Algorithm: ") <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_puts error"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) { + WOLFSSL_MSG("wolfSSL_i2a_ASN1_OBJECT error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; + } + +#ifndef NO_WOLFSSL_STUB + void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig, + const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509) + { + (void)psig; + (void)palg; + (void)x509; + WOLFSSL_STUB("wolfSSL_X509_get0_signature"); + } +#endif + #endif /* !NO_CERTS */ #ifdef OPENSSL_EXTRA @@ -51159,6 +51192,20 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, return WOLFSSL_FAILURE; } +int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt"); + WOLFSSL_STUB("wolfSSL_X509_REQ_add1_attr_by_txt"); + (void)req; + (void)attrname; + (void)type; + (void)bytes; + (void)len; + return WOLFSSL_FAILURE; +} + int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, int nid, int lastpos) { diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 477e06ea3..83a413639 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -301,6 +301,9 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order #define EC_GROUP_order_bits wolfSSL_EC_GROUP_order_bits #define EC_GROUP_method_of wolfSSL_EC_GROUP_method_of +#ifndef NO_WOLFSSL_STUB +#define EC_GROUP_set_point_conversion_form(...) +#endif #define EC_METHOD_get_field_type wolfSSL_EC_METHOD_get_field_type diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 2736f39d3..6d3c10c6c 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -387,6 +387,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_sign_ctx wolfSSL_X509_REQ_sign_ctx #define X509_REQ_add_extensions wolfSSL_X509_REQ_add_extensions #define X509_REQ_add1_attr_by_NID wolfSSL_X509_REQ_add1_attr_by_NID +#define X509_REQ_add1_attr_by_txt wolfSSL_X509_REQ_add1_attr_by_txt #define X509_REQ_get_attr_by_NID wolfSSL_X509_REQ_get_attr_by_NID #define X509_REQ_get_attr wolfSSL_X509_REQ_get_attr #define X509_to_X509_REQ wolfSSL_X509_to_X509_REQ @@ -443,6 +444,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_print_ex wolfSSL_X509_print_ex #define X509_print_fp wolfSSL_X509_print_fp #define X509_REQ_print_fp wolfSSL_X509_print_fp +#define X509_signature_print wolfSSL_X509_signature_print +#define X509_get0_signature wolfSSL_X509_get0_signature #define X509_verify_cert_error_string wolfSSL_X509_verify_cert_error_string #define X509_verify_cert wolfSSL_X509_verify_cert #define X509_verify wolfSSL_X509_verify @@ -603,6 +606,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_CRL_get_REVOKED wolfSSL_X509_CRL_get_REVOKED #define X509_get_X509_PUBKEY wolfSSL_X509_get_X509_PUBKEY +#define X509_REQ_get_X509_PUBKEY wolfSSL_X509_get_X509_PUBKEY #define X509_get0_tbs_sigalg wolfSSL_X509_get0_tbs_sigalg #define X509_PUBKEY_get0_param wolfSSL_X509_PUBKEY_get0_param #define X509_PUBKEY_get wolfSSL_X509_PUBKEY_get diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2d65d76d6..55e49c6b1 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1355,6 +1355,10 @@ WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset WOLFSSL_API int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, unsigned long nmflags, unsigned long cflag); WOLFSSL_API int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509); +WOLFSSL_API int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp, + const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig); +WOLFSSL_API void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig, + const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509); WOLFSSL_API int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, char*, int); @@ -3594,6 +3598,9 @@ WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, int len); WOLFSSL_API int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, int nid, int lastpos); +WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, + const char *attrname, int type, + const unsigned char *bytes, int len); WOLFSSL_API WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( const WOLFSSL_X509 *req, int loc); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index dc8112552..a1628c04a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -229,6 +229,7 @@ enum NID_inhibit_any_policy = 168, /* 2.5.29.54 */ NID_tlsfeature = 1020, /* id-pe 24 */ NID_commonName = 0x03, /* matches ASN_COMMON_NAME in asn.h */ + NID_buildingName = 1494, NID_surname = 0x04, /* SN */ From ff7b8d3715430a8e00a58fa76b12d46ee70d951d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 10 Aug 2020 20:40:16 +0200 Subject: [PATCH 20/53] Don't attempt TLS 1.3 if server options disable it --- src/internal.c | 8 ++++++-- wolfssl/internal.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index 811a539ae..f74a3f979 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15578,7 +15578,11 @@ int ProcessReply(WOLFSSL* ssl) ssl->buffers.inputBuffer.length); #endif } - else if (!IsAtLeastTLSv1_3(ssl->version)) { + else if (!IsAtLeastTLSv1_3(ssl->version) +#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) + || !TLSv1_3_Capable(ssl) +#endif + ) { #ifndef WOLFSSL_NO_TLS12 ret = DoHandShakeMsg(ssl, ssl->buffers.inputBuffer.buffer, @@ -20435,7 +20439,7 @@ exit_dpk: #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) /* returns 1 if able to do TLS 1.3 otherwise 0 */ - static int TLSv1_3_Capable(WOLFSSL* ssl) + int TLSv1_3_Capable(WOLFSSL* ssl) { #ifndef WOLFSSL_TLS13 return 0; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 62ed053ef..4c398e4bf 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4456,6 +4456,7 @@ WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side); WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl); WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl); WOLFSSL_LOCAL int IsAtLeastTLSv1_3(const ProtocolVersion pv); +WOLFSSL_LOCAL int TLSv1_3_Capable(WOLFSSL* ssl); WOLFSSL_LOCAL void FreeHandshakeResources(WOLFSSL* ssl); WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree); From 2689d499b95b427dba6bf8bb5ce9fbe99ff753cb Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 27 Aug 2020 17:39:03 +0200 Subject: [PATCH 21/53] Tests starting to pass --- certs/csr.attr.der | Bin 0 -> 1171 bytes csr.signed.der => certs/csr.signed.der | Bin configure.ac | 5 + src/internal.c | 31 ++ src/ssl.c | 449 +++++++++++++++++++++---- tests/api.c | 58 +++- wolfcrypt/src/asn.c | 109 +++++- wolfcrypt/src/evp.c | 72 ++-- wolfcrypt/src/pkcs7.c | 3 +- wolfssl/internal.h | 3 + wolfssl/openssl/pem.h | 3 + wolfssl/openssl/ssl.h | 6 + wolfssl/ssl.h | 7 +- wolfssl/wolfcrypt/asn.h | 17 + 14 files changed, 623 insertions(+), 140 deletions(-) create mode 100644 certs/csr.attr.der rename csr.signed.der => certs/csr.signed.der (100%) diff --git a/certs/csr.attr.der b/certs/csr.attr.der new file mode 100644 index 0000000000000000000000000000000000000000..bceadd777f6f0b9a776e210024ef1a7d63d45bb3 GIT binary patch literal 1171 zcmXqLV(B+%Vk&21WH1mh6fzKCV-96u7UncGGS@TEGte_MXkt<_;AP{~YV&CO&dbQi z$jZRn#Kg~F(8R>W)WpQdaL(4rU#DWl^-o8RX8)bLdN1FR&rZ_UUA<(~cG*mtSuZB} z_sDE!h1r=V4eCkk+D~Wi>&~n)oOx!M0{`Ya1?s*j`h77e`cF2CWHUY#`8|0{bKddB z109_IQ)8OTye7^LkGW#NHe>Cg`EPG0s{G!x$MM%DkMuY3nz8$KZLrQ34ea8{oD-;P zx%{W8&bi-O#b!Hf)?4H(?lUT zA6=hYH%z*_zj2zQOvg=u`nsK)UIfLvm~UVzZ}D%1VuCJ6jz1qvMTSX2p)(&mMg?YTEq#Tlu2jIt&Vz{uoa9;iBZ$ ztK;_T(aXP6Heda}^dmNhe`VL-3#z59yN&e&r|4Gk%0JW3FXZ*%Gi(r?((vW4iLsIW zYnEeEJNSft-MZmi)4z@LX`I8B+Vwo8jisF{_y0(GEl~P~pNW}~fpLMEfiNiLup06R za~T>Lo0yuJTUa_8$iov3C%d7Luz*p8r>k~hVS#>8MrBAufHrc<;s&QIMuua;7rydG zZrOi3|8DWY*8T^cLA494BG-ING?U*Ln0*KfbF_Iw)9kM6zYIJ*`H9amQMES<_Qp>Zz=O5g^~T5dSh1|XuA;TPJaeka$+tYJsabr*h0`zXTzoxq!TRp= zopM+Gm~CoSxc6sR`0Z}@kTUNJo!_uA<;bqW%*urCQ3bUGXzQ@Mc0z*abkRj`e|A3RNRt+Ed7j|FVFGgQC-U8GPPq0yPrt@1+7gS%ZJX41nghL8J$7f-J;FibjXb53UNN#m6! S!S5ePD^>ihQQmc}dm#WcdmXR< literal 0 HcmV?d00001 diff --git a/csr.signed.der b/certs/csr.signed.der similarity index 100% rename from csr.signed.der rename to certs/csr.signed.der diff --git a/configure.ac b/configure.ac index e449615e4..51b6a04c2 100644 --- a/configure.ac +++ b/configure.ac @@ -4316,6 +4316,11 @@ then ENABLED_SESSIONCERTS="yes" AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS" fi + + if test "x$ENABLED_DSA" = "xno" + then + AC_MSG_WARN([Enabling DSA with --enable-dsa is recommended for libest]) + fi fi # MD4 diff --git a/src/internal.c b/src/internal.c index f74a3f979..62bbeaa8c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9567,6 +9567,37 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) else x509->subjectCN[0] = '\0'; +#ifdef WOLFSSL_CERT_REQ + /* CSR attributes */ + if (dCert->cPwd) { + if (dCert->cPwdLen < CTC_NAME_SIZE) { + XMEMCPY(x509->challengePw, dCert->cPwd, dCert->cPwdLen); + x509->challengePw[dCert->cPwdLen] = '\0'; + if (x509->challengePwAttr) { + wolfSSL_X509_ATTRIBUTE_free(x509->challengePwAttr); + } + x509->challengePwAttr = wolfSSL_X509_ATTRIBUTE_new(); + if (x509->challengePwAttr) { + x509->challengePwAttr->value->value.asn1_string = + wolfSSL_ASN1_STRING_new(); + if (wolfSSL_ASN1_STRING_set( + x509->challengePwAttr->value->value.asn1_string, + dCert->cPwd, dCert->cPwdLen) != WOLFSSL_SUCCESS) { + ret = MEMORY_E; + } + x509->challengePwAttr->value->type = V_ASN1_PRINTABLESTRING; + } + else { + ret = MEMORY_E; + } + } + else { + WOLFSSL_MSG("Challenge password too long"); + ret = MEMORY_E; + } + } +#endif + #ifdef WOLFSSL_SEP { int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE); diff --git a/src/ssl.c b/src/ssl.c index 75a33fba6..47ff87855 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -442,7 +442,7 @@ WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method) int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx) { int refCount = SSL_CTX_RefCount(ctx, 1); - return ((refCount > 1) ? 1 : 0); + return ((refCount > 1) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE); } #endif @@ -3586,12 +3586,18 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap) DYNAMIC_TYPE_CERT_MANAGER); if (cm) { XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER)); + cm->refCount = 1; if (wc_InitMutex(&cm->caLock) != 0) { WOLFSSL_MSG("Bad mutex init"); wolfSSL_CertManagerFree(cm); return NULL; } + if (wc_InitMutex(&cm->refMutex) != 0) { + WOLFSSL_MSG("Bad mutex init"); + wolfSSL_CertManagerFree(cm); + return NULL; + } #ifdef WOLFSSL_TRUST_PEER_CERT if (wc_InitMutex(&cm->tpLock) != 0) { @@ -3623,37 +3629,62 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void) void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) { + int doFree = 0; WOLFSSL_ENTER("wolfSSL_CertManagerFree"); if (cm) { - #ifdef HAVE_CRL - if (cm->crl) - FreeCRL(cm->crl, 1); - #endif - #ifdef HAVE_OCSP - if (cm->ocsp) - FreeOCSP(cm->ocsp, 1); - XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); - #if !defined(NO_WOLFSSL_SERVER) && \ - (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ - defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) - if (cm->ocsp_stapling) - FreeOCSP(cm->ocsp_stapling, 1); - #endif - #endif - FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); - wc_FreeMutex(&cm->caLock); + if (wc_LockMutex(&cm->refMutex) != 0) { + WOLFSSL_MSG("Couldn't lock cm mutex"); + } + cm->refCount--; + if (cm->refCount == 0) + doFree = 1; + wc_UnLockMutex(&cm->refMutex); + if (doFree) { + #ifdef HAVE_CRL + if (cm->crl) + FreeCRL(cm->crl, 1); + #endif + #ifdef HAVE_OCSP + if (cm->ocsp) + FreeOCSP(cm->ocsp, 1); + XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); + #if !defined(NO_WOLFSSL_SERVER) && \ + (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + if (cm->ocsp_stapling) + FreeOCSP(cm->ocsp_stapling, 1); + #endif + #endif + FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); + wc_FreeMutex(&cm->caLock); - #ifdef WOLFSSL_TRUST_PEER_CERT - FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); - wc_FreeMutex(&cm->tpLock); - #endif + #ifdef WOLFSSL_TRUST_PEER_CERT + FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); + wc_FreeMutex(&cm->tpLock); + #endif - XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); + XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); + } } } +int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm) +{ + if (cm) { + if (wc_LockMutex(&cm->refMutex) != 0) { + WOLFSSL_MSG("Failed to lock cm mutex"); + } + cm->refCount++; + wc_UnLockMutex(&cm->refMutex); + + return WOLFSSL_SUCCESS; + } + + return WOLFSSL_FAILURE; +} + #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) #if defined(WOLFSSL_SIGNER_DER_CERT) /****************************************************************************** @@ -15333,15 +15364,20 @@ int wolfSSL_set_compression(WOLFSSL* ssl) void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str) { - if (ctx == NULL || str == NULL) { + if (ctx == NULL || str == NULL || ctx->cm == str->cm) { return; } + if (wolfSSL_CertManager_up_ref(str->cm) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_CertManager_up_ref error"); + return; + } /* free cert manager if have one */ if (ctx->cm != NULL) { wolfSSL_CertManagerFree(ctx->cm); } ctx->cm = str->cm; + ctx->x509_store.cm = str->cm; /* free existing store if it exists */ if (ctx->x509_store_pt != NULL) { @@ -15888,6 +15924,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) wc_RemoveErrorNode(0); } } while (ret >= 0); + wolfSSL_BIO_write(bio, "", 1); } #endif /* !NO_BIO */ #endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */ @@ -19534,6 +19571,98 @@ WOLFSSL_STACK *wolfSSL_NCONF_get_section( return NULL; } +static char* expandValue(WOLFSSL_CONF *conf, const char* section, + char *str) +{ + int strLen = XSTRLEN(str); + char* ret = NULL; + + /* Check to see if there is anything to expand */ + if (XSTRNSTR(str, "$", strLen)) { + int idx = 0; + char* strIdx = str; + ret = (char*)XMALLOC(strLen + 1, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret) { + WOLFSSL_MSG("malloc error"); + return str; + } + + while (*strIdx) { + if (*strIdx == '$') { + /* Expand variable */ + char* startIdx = ++strIdx; + char* endIdx; + const char* s = section; + const char* value; + char prevValue; + + if (*startIdx == '{') { + /* First read the section. Ex: ${ENV::COUNT} */ + s = ++startIdx; + while (*strIdx && *strIdx != ':') strIdx++; + if (!strIdx || s == strIdx || strIdx[1] != ':') { + WOLFSSL_MSG("invalid section name in " + "variable expansion"); + goto expand_cleanup; + } + *strIdx = '\0'; + *strIdx += 2; + startIdx = strIdx; + } + while (*strIdx && (XISALPHA(*strIdx) || *strIdx == '_')) + strIdx++; + endIdx = strIdx; + if (startIdx == endIdx) { + WOLFSSL_MSG("invalid variable name in config"); + goto expand_cleanup; + } + if (s != section) { + /* We are expecting a trailing '}' */ + if (*strIdx != '}') { + WOLFSSL_MSG("Missing '}' in variable"); + goto expand_cleanup; + } + strIdx++; + } + /* Save char value at the end of the name so that we can place + * a null char there. */ + prevValue = *endIdx; + *endIdx = '\0'; + value = wolfSSL_NCONF_get_string(conf, s, startIdx); + *endIdx = prevValue; + /* Skip copy if no value or zero-length value */ + if (value && *value) { + int valueLen = XSTRLEN(value); + char* newRet; + /* This will allocate slightly more memory than necessary + * but better be safe */ + strLen += valueLen; + newRet = (char*)XREALLOC(ret, strLen + 1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!newRet) { + WOLFSSL_MSG("realloc error"); + goto expand_cleanup; + } + ret = newRet; + XMEMCPY(ret + idx, value, valueLen); + idx += valueLen; + } + } + else { + ret[idx++] = *strIdx++; + } + } + ret[idx] = '\0'; + } + + return ret ? ret : str; + +expand_cleanup: + if (ret) + XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; +} + #define SKIP_WHITESPACE(idx, max_idx) \ while (idx < max_idx && (*idx == ' ' || *idx == '\t')) \ {idx++;} @@ -19632,6 +19761,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) char* name; int nameLen; char* value; + char* exValue; /* expanded value */ int valueLen; WOLFSSL_CONF_VALUE* newVal = NULL; @@ -19663,12 +19793,22 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) name[nameLen] = '\0'; value[valueLen] = '\0'; - if (!(newVal = wolfSSL_CONF_VALUE_new_values(section->section, - name, value))) { - WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error"); + if (!(exValue = expandValue(conf, section->section, value))) { + WOLFSSL_MSG("Variable expansion failed"); goto cleanup; } + if (!(newVal = wolfSSL_CONF_VALUE_new_values(section->section, + name, exValue))) { + WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error"); + if (exValue != value) + XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL); + goto cleanup; + } + + if (exValue != value) + XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL); + if (wolfSSL_CONF_add_string(conf, section, newVal) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("wolfSSL_CONF_add_string error"); @@ -27089,6 +27229,13 @@ void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at) case V_ASN1_GENERALIZEDTIME: wolfSSL_ASN1_TIME_free(at->value.generalizedtime); break; + case V_ASN1_UTF8STRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_IA5STRING: + case V_ASN1_UNIVERSALSTRING: + wolfSSL_ASN1_STRING_free(at->value.asn1_string); + break; default: WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE"); break; @@ -27190,10 +27337,14 @@ int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key) { WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get"); - if(key == NULL || key->pkey == NULL){ + if (key == NULL || key->pkey == NULL) { WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG); return NULL; } + if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) { + WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E); + return NULL; + } WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS); return key->pkey; } @@ -29775,6 +29926,10 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { "jurisdictionCountryName"}, { NID_jurisdictionStateOrProvinceName, NID_jurisdictionStateOrProvinceName, oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"}, +#ifdef WOLFSSL_CERT_REQ + { NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID, + oidCsrAttrType, "challengePassword", "challengePassword"}, +#endif #endif #ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */ /* oidHashType */ @@ -38425,10 +38580,10 @@ int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa) rsa->refCount++; wc_UnLockMutex(&rsa->refMutex); - return 1; + return WOLFSSL_SUCCESS; } - return 0; + return WOLFSSL_FAILURE; } /* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */ @@ -38441,10 +38596,10 @@ int wolfSSL_X509_up_ref(WOLFSSL_X509* x509) x509->refCount++; wc_UnLockMutex(&x509->refMutex); - return 1; + return WOLFSSL_SUCCESS; } - return 0; + return WOLFSSL_FAILURE; } #endif /* OPENSSL_EXTRA || OPENSSL_ALL */ @@ -39182,6 +39337,12 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) if (req->keyUsageSet) cert->keyUsage = req->keyUsage; /* Extended Key Usage not supported. */ + #endif + #ifdef WOLFSSL_CERT_REQ + if (XSTRLEN(cert->challengePw) > 0) { + XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE); + cert->challengePwPrintableString = 1; + } #endif } @@ -41552,6 +41713,7 @@ err: { word32 oid = 0; word32 idx = 0; + int ret; WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid"); @@ -41569,9 +41731,29 @@ err: if (o->nid > 0) return o->nid; - if (GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz) < 0) { - WOLFSSL_MSG("Issue getting OID of object"); - return -1; + if ((ret = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) { + if (ret == ASN_OBJECT_ID_E) { + /* Put ASN object tag in front and try again */ + int len = SetObjectId(o->objSz, NULL) + o->objSz; + byte* buf = XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!buf) { + WOLFSSL_MSG("malloc error"); + return -1; + } + idx = SetObjectId(o->objSz, buf); + XMEMCPY(buf + idx, o->obj, o->objSz); + idx = 0; + ret = GetObjectId(buf, &idx, &oid, o->grp, len); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (ret < 0) { + WOLFSSL_MSG("Issue getting OID of object"); + return -1; + } + } + else { + WOLFSSL_MSG("Issue getting OID of object"); + return -1; + } } return oid2nid(oid, o->grp); @@ -47149,6 +47331,7 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, int oid2nid(word32 oid, int grp) { + size_t i; /* get OID type */ switch (grp) { /* oidHashType */ @@ -47470,9 +47653,23 @@ int oid2nid(word32 oid, int grp) } break; + case oidCsrAttrType: + switch (oid) { + case CHALLENGE_PASSWORD_OID: + return NID_pkcs9_challengePassword; + case SERIAL_NUMBER_OID: + return NID_serialNumber; + } + break; + default: WOLFSSL_MSG("NID not in table"); - return -1; + } + /* If not found in above switch then try the table */ + for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) { + if (wolfssl_object_info[i].id == (int)oid) { + return wolfssl_object_info[i].nid; + } } return -1; @@ -50270,6 +50467,11 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, int hashOID = p7->hashOID; byte version = p7->version; + if (!certs->data.x509 || !certs->data.x509->derCert) { + WOLFSSL_MSG("Missing cert"); + return WOLFSSL_FAILURE; + } + if (wc_PKCS7_InitWithCert(p7, certs->data.x509->derCert->buffer, certs->data.x509->derCert->length) != 0) { WOLFSSL_MSG("wc_PKCS7_InitWithCert error"); @@ -50283,6 +50485,10 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, /* Add the certs to the PKCS7 struct */ while (certs) { + if (!certs->data.x509 || !certs->data.x509->derCert) { + WOLFSSL_MSG("Missing cert"); + return WOLFSSL_FAILURE; + } if (wc_PKCS7_AddCertificate(p7, certs->data.x509->derCert->buffer, certs->data.x509->derCert->length) != 0) { WOLFSSL_MSG("wc_PKCS7_AddCertificate error"); @@ -51165,7 +51371,11 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, WOLFSSL_EVP_MD_CTX* md_ctx) { - return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(md_ctx)); + if (md_ctx && md_ctx->pctx) + return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey, + wolfSSL_EVP_MD_CTX_md(md_ctx)); + else + return WOLFSSL_FAILURE; } #ifndef NO_WOLFSSL_STUB @@ -51176,22 +51386,6 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, (void)ext; return WOLFSSL_FAILURE; } - -int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, - int nid, int type, - const unsigned char *bytes, - int len) -{ - WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID"); - WOLFSSL_STUB("wolfSSL_X509_REQ_add1_attr_by_NID"); - (void)req; - (void)nid; - (void)type; - (void)bytes; - (void)len; - return WOLFSSL_FAILURE; -} - int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, const char *attrname, int type, const unsigned char *bytes, int len) @@ -51205,28 +51399,157 @@ int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, (void)len; return WOLFSSL_FAILURE; } +#endif /* NO_WOLFSSL_STUB */ +int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, + int nid, int type, + const unsigned char *bytes, + int len) +{ + WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID"); + + if (!req || !bytes || type != MBSTRING_ASC) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + switch (nid) { + case NID_pkcs9_challengePassword: + if (len < 0) + len = XSTRLEN((char*)bytes); + if (len < CTC_NAME_SIZE) { + XMEMCPY(req->challengePw, bytes, len); + req->challengePw[len] = '\0'; + } + else { + WOLFSSL_MSG("Challenge password too long"); + return WOLFSSL_FAILURE; + } + if (req->challengePwAttr) { + wolfSSL_X509_ATTRIBUTE_free(req->challengePwAttr); + } + req->challengePwAttr = wolfSSL_X509_ATTRIBUTE_new(); + if (req->challengePwAttr) { + req->challengePwAttr->value->value.asn1_string = + wolfSSL_ASN1_STRING_new(); + if (wolfSSL_ASN1_STRING_set( + req->challengePwAttr->value->value.asn1_string, + bytes, len) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error"); + return WOLFSSL_FAILURE; + } + req->challengePwAttr->value->type = V_ASN1_PRINTABLESTRING; + } + else { + WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error"); + return WOLFSSL_FAILURE; + } + break; + default: + WOLFSSL_MSG("Unsupported attribute"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; +} + + +/* Return NID as the attr index */ int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, int nid, int lastpos) { WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID"); - WOLFSSL_STUB("wolfSSL_X509_REQ_get_attr_by_NID"); - (void)req; - (void)nid; - (void)lastpos; - return WOLFSSL_FATAL_ERROR; + + /* Since we only support 1 attr per attr type then a lastpos of >= 0 + * indicates that one was already returned */ + if (!req || lastpos >= 0) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FATAL_ERROR; + } + + switch (nid) { + case NID_pkcs9_challengePassword: + return req->challengePwAttr ? nid : WOLFSSL_FATAL_ERROR; + default: + WOLFSSL_MSG("Unsupported attribute"); + return WOLFSSL_FATAL_ERROR; + } } +/** + * @param req X509_REQ containing attribute + * @param loc NID of the attribute to return + */ WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( const WOLFSSL_X509 *req, int loc) { WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr"); - WOLFSSL_STUB("wolfSSL_X509_REQ_get_attr"); - (void)req; - (void)loc; - return NULL; + + if (!req) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + switch (loc) { + case NID_pkcs9_challengePassword: + return req->challengePwAttr; + default: + WOLFSSL_MSG("Unsupported attribute"); + return NULL; + } +} + +WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void) +{ + WOLFSSL_X509_ATTRIBUTE* ret; + WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new"); + ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE), + NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret) { + WOLFSSL_MSG("malloc error"); + return NULL; + } + XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE)); + ret->object = wolfSSL_ASN1_OBJECT_new(); + ret->value = wolfSSL_ASN1_TYPE_new(); + /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE + * is not supported as a stack type */ + if (!ret->object || !ret->value) { + WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error"); + wolfSSL_X509_ATTRIBUTE_free(ret); + return NULL; + } + return ret; +} + +void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr) +{ + WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free"); + if (attr) { + if (attr->object) { + wolfSSL_ASN1_OBJECT_free(attr->object); + } + if (attr->value) { + wolfSSL_ASN1_TYPE_free(attr->value); + } + if (attr->set) { + wolfSSL_sk_free(attr->set); + } + XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type( + WOLFSSL_X509_ATTRIBUTE *attr, int idx) +{ + WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type"); + + if (!attr || idx != 0) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + return attr->value; } -#endif WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md) diff --git a/tests/api.c b/tests/api.c index 5e198011a..24278065c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30086,7 +30086,8 @@ static void test_wolfSSL_ERR_print_errors(void) AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57); AssertIntEQ(XSTRNCMP("error:295:wolfSSL library:unknown error number:asn.c:100", buf, 56), 0); - AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0); + AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 1); + AssertIntEQ(buf[0], '\0'); AssertIntEQ(ERR_get_error_line(NULL, NULL), 0); BIO_free(bio); @@ -33280,9 +33281,9 @@ static void test_wolfSSL_get_ciphers_compat(void) static void test_wolfSSL_X509_PUBKEY_get(void) { - WOLFSSL_X509_PUBKEY pubkey; + WOLFSSL_X509_PUBKEY pubkey = {0}; WOLFSSL_X509_PUBKEY* key; - WOLFSSL_EVP_PKEY evpkey; + WOLFSSL_EVP_PKEY evpkey = {0}; WOLFSSL_EVP_PKEY* evpPkey; WOLFSSL_EVP_PKEY* retEvpPkey; @@ -37887,26 +37888,51 @@ static void test_wolfSSL_X509_CRL(void) static void test_wolfSSL_d2i_X509_REQ(void) { - const char* csrFile = "./csr.signed.der"; + const char* csrFile = "./certs/csr.signed.der"; + const char* csrPopFile = "./certs/csr.attr.der"; BIO* bio = NULL; X509* req = NULL; EVP_PKEY *pub_key = NULL; - AssertNotNull(bio = BIO_new_file(csrFile, "rb")); - AssertNotNull(d2i_X509_REQ_bio(bio, &req)); + { + AssertNotNull(bio = BIO_new_file(csrFile, "rb")); + AssertNotNull(d2i_X509_REQ_bio(bio, &req)); - /* - * Extract the public key from the CSR - */ - AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); - /* - * Verify the signature in the CSR - */ - AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); - X509_free(req); - BIO_free(bio); + X509_free(req); + BIO_free(bio); + } + { + AssertNotNull(bio = BIO_new_file(csrPopFile, "rb")); + AssertNotNull(d2i_X509_REQ_bio(bio, &req)); + + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + + /* + * Obtain the challenge password from the CSR + */ + AssertIntGE(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1), 0); + + X509_free(req); + BIO_free(bio); + } } static void test_wolfSSL_PEM_read_X509(void) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e5062c3d8..d686dfb39 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1660,6 +1660,13 @@ static const byte extExtKeyUsageCodeSigningOid[] = {43, 6, 1, 5, 5, 7, 3, 3}; static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4}; static const byte extExtKeyUsageTimestampOid[] = {43, 6, 1, 5, 5, 7, 3, 8}; static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9}; + +#ifdef WOLFSSL_CERT_REQ +/* csrAttrType */ +static const byte attrChallengePasswordOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 7}; +static const byte attrSerialNumberOid[] = {85, 4, 5}; +#endif + /* kdfType */ static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12}; @@ -2287,6 +2294,20 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) } break; #endif /* WOLFSSL_APACHE_HTTPD */ +#ifdef WOLFSSL_CERT_REQ + case oidCsrAttrType: + switch (id) { + case CHALLENGE_PASSWORD_OID: + oid = attrChallengePasswordOid; + *oidSz = sizeof(attrChallengePasswordOid); + break; + case SERIAL_NUMBER_OID: + oid = attrSerialNumberOid; + *oidSz = sizeof(attrSerialNumberOid); + break; + } + break; +#endif case oidIgnoreType: default: break; @@ -2454,8 +2475,11 @@ int SetObjectId(int len, byte* output) { int idx = 0; - output[idx++] = ASN_OBJECT_ID; - idx += SetLength(len, output + idx); + if (output) + output[idx++] = ASN_OBJECT_ID; + else + idx++; + idx += SetLength(len, output ? output + idx : NULL); return idx; } @@ -5453,6 +5477,7 @@ static int GetKey(DecodedCert* cert) } #endif /* NO_DSA */ default: + WOLFSSL_MSG("Unknown or not compiled in key OID"); return ASN_UNKNOWN_OID_E; } } @@ -9480,9 +9505,67 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } if (len) { - WOLFSSL_MSG("Non-empty attributes. wolfSSL doesn't support " - "parsing CSR attributes."); - return ASN_VERSION_E; + word32 attrMaxIdx = cert->srcIdx + len; + word32 oid; + byte tag; + + if (attrMaxIdx > cert->maxIdx) { + WOLFSSL_MSG("Attribute length greater than CSR length"); + return ASN_PARSE_E; + } + + while (cert->srcIdx < attrMaxIdx) { + /* Attributes have the structure: + * SEQ -> OID -> SET -> ATTRIBUTE */ + if (GetSequence(cert->source, &cert->srcIdx, &len, + attrMaxIdx) < 0) { + WOLFSSL_MSG("attr GetSequence error"); + return ASN_PARSE_E; + } + if (GetObjectId(cert->source, &cert->srcIdx, &oid, + oidCsrAttrType, attrMaxIdx) < 0) { + WOLFSSL_MSG("attr GetObjectId error"); + return ASN_PARSE_E; + } + if (GetSet(cert->source, &cert->srcIdx, &len, + attrMaxIdx) < 0) { + WOLFSSL_MSG("attr GetSet error"); + return ASN_PARSE_E; + } + /* For now all supported attributes have the type value + * of ASN_PRINTABLE_STRING or ASN_UTF8STRING but as more + * attributes are supported then this will have to be done + * on a per attribute basis. */ + if (GetHeader(cert->source, &tag, + &cert->srcIdx, &len, attrMaxIdx, 1) < 0) { + WOLFSSL_MSG("attr GetHeader error"); + return ASN_PARSE_E; + } + if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING && + tag != ASN_IA5_STRING) { + WOLFSSL_MSG("Unsupported attribute value format"); + return ASN_PARSE_E; + } + switch (oid) { + case CHALLENGE_PASSWORD_OID: + cert->cPwd = (char*)cert->source + cert->srcIdx; + cert->cPwdLen = len; + cert->srcIdx += len; + break; + case SERIAL_NUMBER_OID: + cert->sNum = (char*)cert->source + cert->srcIdx; + cert->sNumLen = len; + cert->srcIdx += len; + if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) { + XMEMCPY(cert->serial, cert->sNum, cert->sNumLen); + cert->serialSz = cert->sNumLen; + } + break; + default: + WOLFSSL_MSG("Unsupported attribute type"); + return ASN_PARSE_E; + } + } } } #endif @@ -13883,9 +13966,6 @@ int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, int extSz) { - const byte cpOid[] = - { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x07 }; const byte erOid[] = { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e }; @@ -13916,8 +13996,11 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, cpStrSz = SetUTF8String(pwSz, cpStr); } cpSetSz = SetSet(cpStrSz + pwSz, cpSet); - cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq); - cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz; + /* +2 for tag and length parts of the TLV triplet */ + cpSeqSz = SetSequence(2 + sizeof(attrChallengePasswordOid) + cpSetSz + + cpStrSz + pwSz, cpSeq); + cpSz = cpSeqSz + 2 + sizeof(attrChallengePasswordOid) + cpSetSz + + cpStrSz + pwSz; } if (extSz) { @@ -13932,8 +14015,10 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, if (cpSz) { XMEMCPY(&output[sz], cpSeq, cpSeqSz); sz += cpSeqSz; - XMEMCPY(&output[sz], cpOid, sizeof(cpOid)); - sz += sizeof(cpOid); + sz += SetObjectId(sizeof(attrChallengePasswordOid), output + sz); + XMEMCPY(&output[sz], attrChallengePasswordOid, + sizeof(attrChallengePasswordOid)); + sz += sizeof(attrChallengePasswordOid); XMEMCPY(&output[sz], cpSet, cpSetSz); sz += cpSetSz; XMEMCPY(&output[sz], cpStr, cpStrSz); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 8dd4773db..2f268a18f 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1330,7 +1330,6 @@ int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx) WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e) { WOLFSSL_EVP_PKEY_CTX* ctx; - int type = NID_undef; if (pkey == NULL) return 0; if (e != NULL) return 0; @@ -1344,15 +1343,8 @@ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_E #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) ctx->padding = RSA_PKCS1_PADDING; #endif - type = wolfSSL_EVP_PKEY_type(pkey->type); - - if (type != NID_undef) { - if (wc_LockMutex(&pkey->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock pkey mutex"); - } - pkey->references++; - - wc_UnLockMutex(&pkey->refMutex); + if (wolfSSL_EVP_PKEY_up_ref(pkey) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Couldn't increase key reference count"); } return ctx; } @@ -1925,7 +1917,7 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, #ifndef NO_DSA case EVP_PKEY_DSA: if (from->dsa) { - WOLFSSL_BIGNUM cpy; + WOLFSSL_BIGNUM* cpy; if (!to->dsa && !(to->dsa = wolfSSL_DSA_new())) { WOLFSSL_MSG("wolfSSL_DSA_new error"); return WOLFSSL_FAILURE; @@ -1935,12 +1927,12 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, return WOLFSSL_FAILURE; } to->dsa->p = cpy; - if (!(cpy = wolfSSL_BN_dup(from->dsa->q)) { + if (!(cpy = wolfSSL_BN_dup(from->dsa->q))) { WOLFSSL_MSG("wolfSSL_BN_dup error"); return WOLFSSL_FAILURE; } to->dsa->q = cpy; - if (!(cpy = wolfSSL_BN_dup(from->dsa->g)) { + if (!(cpy = wolfSSL_BN_dup(from->dsa->g))) { WOLFSSL_MSG("wolfSSL_BN_dup error"); return WOLFSSL_FAILURE; } @@ -2375,21 +2367,16 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, ctx->isHMAC = 1; } - else { - int ret; + else if (wolfSSL_EVP_DigestInit(ctx, type) != 1) + return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { - ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e); - if (ctx->pctx == NULL) - return WOLFSSL_FAILURE; - } - - ret = wolfSSL_EVP_DigestInit(ctx, type); - if (ret == WOLFSSL_SUCCESS && pctx != NULL) - *pctx = ctx->pctx; - return ret; + if (ctx->pctx == NULL) { + ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return WOLFSSL_FAILURE; } - + if (pctx != NULL) + *pctx = ctx->pctx; return WOLFSSL_SUCCESS; } @@ -2399,10 +2386,7 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, static int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx, const void *d, unsigned int cnt) { - if (ctx->pctx == NULL) { - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; - + if (ctx->isHMAC) { if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0) return WOLFSSL_FAILURE; @@ -2421,12 +2405,9 @@ static int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx, { int ret; - if (ctx->pctx == NULL) { + if (ctx->isHMAC) { Hmac hmacCopy; - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; - if (wolfSSL_HmacCopy(&hmacCopy, &ctx->hash.hmac) != WOLFSSL_SUCCESS) return WOLFSSL_FAILURE; ret = wc_HmacFinal(&hmacCopy, md) == 0; @@ -2561,10 +2542,7 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, return WOLFSSL_FAILURE; /* Return the maximum size of the signaure when sig is NULL. */ - if (ctx->pctx == NULL) { - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; - + if (ctx->isHMAC) { hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); if (sig == NULL) { @@ -2594,7 +2572,7 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0) return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { + if (ctx->isHMAC) { /* Copy the HMAC result as signature. */ if ((unsigned int)(*siglen) > hashLen) *siglen = hashLen; @@ -2679,9 +2657,7 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, if (ctx == NULL || sig == NULL) return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; + if (ctx->isHMAC) { hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); @@ -2693,7 +2669,7 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0) return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { + if (ctx->isHMAC) { /* Check HMAC result matches the signature. */ if (XMEMCMP(sig, digest, siglen) == 0) return WOLFSSL_SUCCESS; @@ -5766,11 +5742,15 @@ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key) if ((pkey == NULL) || (key == NULL)) return WOLFSSL_FAILURE; + if (wolfSSL_RSA_up_ref(key) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_RSA_up_ref failed"); + return WOLFSSL_FAILURE; + } if (pkey->rsa != NULL && pkey->ownRsa == 1) { wolfSSL_RSA_free(pkey->rsa); } pkey->rsa = key; - pkey->ownRsa = 0; /* pkey does not own RSA */ + pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */ pkey->type = EVP_PKEY_RSA; if (key->inSet == 0) { if (SetRsaInternal(key) != WOLFSSL_SUCCESS) { @@ -6623,10 +6603,10 @@ int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey) pkey->references++; wc_UnLockMutex(&pkey->refMutex); - return 1; + return WOLFSSL_SUCCESS; } - return 0; + return WOLFSSL_FAILURE; } #ifndef NO_RSA diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 471961588..78a368ef0 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2269,8 +2269,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, byte signingTime[MAX_TIME_STRING_SZ]; - if (pkcs7 == NULL || (pkcs7->contentSz > 0 && pkcs7->content == NULL) || - pkcs7->hashOID == 0 || + if (pkcs7 == NULL || pkcs7->hashOID == 0 || output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 || hashBuf == NULL) { return BAD_FUNC_ARG; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4c398e4bf..53d2c1545 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2029,6 +2029,8 @@ struct WOLFSSL_CERT_MANAGER { #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum allowed ECC key size */ #endif + wolfSSL_Mutex refMutex; /* reference count mutex */ + int refCount; /* reference count */ }; WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*); @@ -3762,6 +3764,7 @@ struct WOLFSSL_X509 { byte serial[EXTERNAL_SERIAL_SIZE]; char subjectCN[ASN_NAME_MAX]; /* common name short cut */ #ifdef WOLFSSL_CERT_REQ + WOLFSSL_X509_ATTRIBUTE* challengePwAttr; char challengePw[CTC_NAME_SIZE]; /* for REQ certs */ #endif WOLFSSL_X509_NAME issuer; diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 5d6029173..31c88d619 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -242,6 +242,9 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); #define PEM_write_ECPrivateKey wolfSSL_PEM_write_ECPrivateKey #define PEM_read_bio_ECPrivateKey wolfSSL_PEM_read_bio_ECPrivateKey #define PEM_read_bio_EC_PUBKEY wolfSSL_PEM_read_bio_EC_PUBKEY +#ifndef NO_WOLFSSL_STUB +#define PEM_write_bio_ECPKParameters(...) 0 +#endif /* EVP_KEY */ #define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey #define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 6d3c10c6c..0b097c1ca 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -390,6 +390,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_add1_attr_by_txt wolfSSL_X509_REQ_add1_attr_by_txt #define X509_REQ_get_attr_by_NID wolfSSL_X509_REQ_get_attr_by_NID #define X509_REQ_get_attr wolfSSL_X509_REQ_get_attr +#define X509_ATTRIBUTE_get0_type wolfSSL_X509_ATTRIBUTE_get0_type #define X509_to_X509_REQ wolfSSL_X509_to_X509_REQ #define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name #define X509_REQ_set_pubkey wolfSSL_X509_REQ_set_pubkey @@ -654,6 +655,11 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size #define BIO_f_ssl wolfSSL_BIO_f_ssl #define BIO_new_socket wolfSSL_BIO_new_socket +#ifndef NO_WOLFSSL_STUB +#define BIO_new_connect(...) NULL +#define BIO_set_conn_port(...) 0 +#define BIO_do_connect(...) 0 +#endif #define SSL_set_bio wolfSSL_set_bio #define BIO_set_ssl wolfSSL_BIO_set_ssl #define BIO_eof wolfSSL_BIO_eof diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 55e49c6b1..c09990a12 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -334,6 +334,7 @@ struct WOLFSSL_ASN1_TYPE { struct WOLFSSL_X509_ATTRIBUTE { WOLFSSL_ASN1_OBJECT *object; + WOLFSSL_ASN1_TYPE *value; WOLF_STACK_OF(WOLFSSL_ASN1_TYPE) *set; }; @@ -2771,6 +2772,7 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap); WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void); WOLFSSL_API void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER*); + WOLFSSL_API int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER*); WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER*, const char* f, const char* d); @@ -3603,7 +3605,10 @@ WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, const unsigned char *bytes, int len); WOLFSSL_API WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( const WOLFSSL_X509 *req, int loc); - +WOLFSSL_API WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void); +WOLFSSL_API void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr); +WOLFSSL_API WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type( + WOLFSSL_X509_ATTRIBUTE *attr, int idx); WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md); #endif diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index a1628c04a..c99608915 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -100,6 +100,7 @@ enum ASN_Tags { ASN_SEQUENCE = 0x10, ASN_SET = 0x11, ASN_PRINTABLE_STRING = 0x13, + ASN_IA5_STRING = 0x16, ASN_UTC_TIME = 0x17, ASN_OTHER_TYPE = 0x00, ASN_RFC822_TYPE = 0x01, @@ -427,6 +428,7 @@ enum Oid_Types { oidCertNameType = 17, oidTlsExtType = 18, oidCrlExtType = 19, + oidCsrAttrType = 20, oidIgnoreType }; @@ -593,6 +595,13 @@ enum KeyIdType { }; #endif +#ifdef WOLFSSL_CERT_REQ +enum CsrAttyType { + CHALLENGE_PASSWORD_OID = 659, + SERIAL_NUMBER_OID = 94, +}; +#endif + /* Key usage extension bits (based on RFC 5280) */ #define KEYUSE_DIGITAL_SIG 0x0080 #define KEYUSE_CONTENT_COMMIT 0x0040 @@ -894,6 +903,14 @@ struct DecodedCert { int extCertPoliciesNb; #endif /* defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) */ +#ifdef WOLFSSL_CERT_REQ + /* CSR attributes */ + char* cPwd; /* challengePassword */ + int cPwdLen; + char* sNum; /* Serial Number */ + int sNumLen; +#endif /* WOLFSSL_CERT_REQ */ + Signer* ca; #ifndef NO_CERTS SignatureCtx sigCtx; From 932ef25e79387d833fae3acd906822da9a5ed6d9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 31 Aug 2020 19:17:13 +0200 Subject: [PATCH 22/53] Set default digest NID --- wolfcrypt/src/evp.c | 55 ++++++++++++++++++++++++++++++++++--------- wolfssl/openssl/evp.h | 1 - 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 2f268a18f..30cbf187d 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -2287,7 +2287,6 @@ const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey, return (const unsigned char*)pkey->pkey.ptr; } - /* Initialize an EVP_DigestSign/Verify operation. * Initialize a digest for RSA and ECC keys, or HMAC for HMAC key. */ @@ -2297,6 +2296,19 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, WOLFSSL_ENGINE *e, WOLFSSL_EVP_PKEY *pkey) { + if (!type) { + int default_digest; + if (wolfSSL_EVP_PKEY_get_default_digest_nid(pkey, &default_digest) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Could not get default digest"); + return WOLFSSL_FAILURE; + } + type = wolfSSL_EVP_get_digestbynid(default_digest); + if (!type) { + return BAD_FUNC_ARG; + } + } + if (pkey->type == EVP_PKEY_HMAC) { int hashType; const unsigned char* key; @@ -2511,7 +2523,7 @@ int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx, { WOLFSSL_ENTER("EVP_DigestSignInit"); - if (ctx == NULL || type == NULL || pkey == NULL) + if (ctx == NULL || pkey == NULL) return BAD_FUNC_ARG; return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey); @@ -5393,7 +5405,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) WOLFSSL_ENTER("EVP_DigestInit"); - if (ctx == NULL || md == NULL) { + if (ctx == NULL) { return BAD_FUNC_ARG; } @@ -5407,7 +5419,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) /* Set to 0 if no match */ ctx->macType = wolfSSL_EVP_md2macType(md); - if (XSTRNCMP(md, "SHA256", 6) == 0) { + if (md == NULL) { + XMEMSET(&ctx->hash.digest, 0, sizeof(WOLFSSL_Hasher)); + } + else if (XSTRNCMP(md, "SHA256", 6) == 0) { ret = wolfSSL_SHA256_Init(&(ctx->hash.digest.sha256)); } #ifdef WOLFSSL_SHA224 @@ -5673,6 +5688,10 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) #ifndef NO_SHA case NID_sha1: return wolfSSL_EVP_sha1(); +#endif +#ifndef NO_SHA256 + case NID_sha256: + return wolfSSL_EVP_sha256(); #endif default: WOLFSSL_MSG("Bad digest id value"); @@ -6582,15 +6601,29 @@ int wolfSSL_EVP_PKEY_base_id(const WOLFSSL_EVP_PKEY *pkey) int wolfSSL_EVP_PKEY_get_default_digest_nid(WOLFSSL_EVP_PKEY *pkey, int *pnid) { - (void)pkey; -#ifndef NO_SHA256 - if (pnid) { - *pnid = NID_sha256; + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get_default_digest_nid"); + + if (!pkey || !pnid) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; } - return WOLFSSL_SUCCESS; -#else - return -2; + + switch (pkey->type) { + case EVP_PKEY_HMAC: +#ifndef NO_DSA + case EVP_PKEY_DSA: #endif +#ifndef NO_RSA + case EVP_PKEY_RSA: +#endif +#ifdef HAVE_ECC + case EVP_PKEY_EC: +#endif + *pnid = NID_sha256; + return WOLFSSL_SUCCESS; + default: + return WOLFSSL_FAILURE; + } } /* increments ref count of WOLFSSL_EVP_PKEY. Return 1 on success, 0 on error */ diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 9848921c1..b84058b03 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -925,7 +925,6 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_R_PRIVATE_KEY_DECODE_ERROR (-MIN_CODE_E + 100 + 4) #define EVP_PKEY_NONE NID_undef -#define EVP_PKEY_RSA 6 #define EVP_PKEY_RSA2 19 #define EVP_PKEY_DH 28 #define EVP_CIPHER_mode WOLFSSL_CIPHER_mode From 86d21778765c85a98d26efb0f217ed9b43c926c6 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 2 Sep 2020 11:57:35 +0200 Subject: [PATCH 23/53] wolfSSL_X509_resign_cert updates x509 der buffer as well --- src/ssl.c | 109 ++++++++---------------------------------- tests/api.c | 4 +- wolfssl/openssl/ssl.h | 1 + 3 files changed, 23 insertions(+), 91 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 47ff87855..5db86f8b1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23163,6 +23163,8 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) } #endif +#endif /* OPENSSL_EXTRA */ + #endif /* !NO_CERTS */ #ifdef OPENSSL_EXTRA @@ -39739,7 +39741,7 @@ cleanup: * WOLFSSL_X509 with the newly signed buffer. * returns size of signed buffer on success and negative values on fail */ - static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, + static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req, unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md, WOLFSSL_EVP_PKEY* pkey) { @@ -39818,6 +39820,20 @@ cleanup: XMEMCPY(x509->sig.buffer, der + idx, len); x509->sig.length = len; } + + /* Put in the new certificate encoding into the x509 object. */ + FreeDer(&x509->derCert); + type = CERT_TYPE; + #ifdef WOLFSSL_CERT_REQ + if (req) { + type = CERTREQ_TYPE; + } + #endif + if (AllocDer(&x509->derCert, derSz, type, NULL) != 0) + return WOLFSSL_FATAL_ERROR; + XMEMCPY(x509->derCert->buffer, der, derSz); + x509->derCert->length = derSz; + return ret; } @@ -41102,30 +41118,7 @@ err: WOLFSSL_MSG("loc entry not found"); return NULL; } - - if (loc <= DN_NAMES_MAX + name->fullName.dcNum) { - XMEMMOVE(&name->fullName.loc[loc], &name->fullName.loc[loc+1], - DN_NAMES_MAX + name->fullName.dcNum - loc - 1); - if (name->fullName.dcNum > 0) - name->fullName.dcNum--; - } - else if (name->fullName.dcMode) { - if (name->fullName.fullName != NULL) { - if (loc == name->fullName.dcNum) { - name->fullName.dcNum = 0; - } - else { - name->fullName.dcIdx[loc] = -1; - } - } - } - else if (loc == name->fullName.cnIdx && name->x509 != NULL) { - name->fullName.cnIdx = -1; - } - else { - WOLFSSL_MSG("Couldn't find name entry"); - } - + name->entry[loc].set = 0; return ret; } #endif /* !NO_CERTS */ @@ -42013,37 +42006,7 @@ err: if (name->entry[loc].set) { return &name->entry[loc]; } - /* DC component */ - if (name->fullName.dcMode) { - if (name->fullName.fullName != NULL){ - if (loc == name->fullName.dcNum){ - name->cnEntry.data.data - = &name->fullName.fullName[name->fullName.cIdx]; - name->cnEntry.data.length = name->fullName.cLen; - name->cnEntry.nid = ASN_COUNTRY_NAME; - } - else if (name->fullName.dcIdx[loc] >= 0) { - name->cnEntry.data.data - = &name->fullName.fullName[name->fullName.dcIdx[loc]]; - name->cnEntry.data.length = name->fullName.dcLen[loc]; - name->cnEntry.nid = ASN_DOMAIN_COMPONENT; - } - else { - WOLFSSL_MSG("loc passed in is not in range of parsed DN's"); - return NULL; - } - } - name->cnEntry.data.type = CTC_UTF8; - /* common name index case */ - } else if (loc == name->fullName.cnIdx && name->x509 != NULL) { - /* get CN shortcut from x509 since it has null terminator */ - name->cnEntry.data.data = name->x509->subjectCN; - name->cnEntry.data.length = name->fullName.cnLen; - name->cnEntry.data.type = CTC_UTF8; - name->cnEntry.nid = ASN_COMMON_NAME; - name->cnEntry.set = 1; - } else { - WOLFSSL_MSG("loc passed in is not in range of parsed DN's"); + else { return NULL; } } @@ -46340,38 +46303,6 @@ WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl) #endif /* NO_SESSION_CACHE */ -int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen, - unsigned int flags, char **peername) -{ - int ret; - DecodedCert dCert; - - WOLFSSL_ENTER("wolfSSL_X509_check_host"); - - /* flags and peername not needed for Nginx. */ - (void)flags; - (void)peername; - - if (flags == WOLFSSL_NO_WILDCARDS) { - WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented"); - return WOLFSSL_FAILURE; - } - - InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL); - ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL); - if (ret != 0) { - FreeDecodedCert(&dCert); - return WOLFSSL_FAILURE; - } - - ret = CheckHostName(&dCert, (char *)chk, chklen); - FreeDecodedCert(&dCert); - if (ret != 0) - return WOLFSSL_FAILURE; - return WOLFSSL_SUCCESS; -} - -#ifndef NO_BIO int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, char *buf, int size) { @@ -51361,7 +51292,7 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, return WOLFSSL_FAILURE; } - if (wolfSSL_X509_resign_cert(req, der, sizeof(der), derSz, + if (wolfSSL_X509_resign_cert(req, 1, der, sizeof(der), derSz, (WOLFSSL_EVP_MD*)md, pkey) <= 0) { return WOLFSSL_FAILURE; } diff --git a/tests/api.c b/tests/api.c index 24278065c..0687d3369 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38827,12 +38827,12 @@ static void test_wolfSSL_ASN1_get_object(void) /* Read a couple TLV triplets and make sure they match the expected values */ AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, len) & 0x80, 0); - AssertIntEQ(asnLen, 831); + AssertIntEQ(asnLen, 863); AssertIntEQ(tag, 0x10); AssertIntEQ(class, 0); AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); - AssertIntEQ(asnLen, 741); + AssertIntEQ(asnLen, 772); AssertIntEQ(tag, 0x10); AssertIntEQ(class, 0); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 0b097c1ca..faa2abf73 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -411,6 +411,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID #define X509_get_issuer_name wolfSSL_X509_get_issuer_name #define X509_issuer_name_hash wolfSSL_X509_issuer_name_hash +#define X509_subject_name_hash wolfSSL_X509_subject_name_hash #define X509_get_subject_name wolfSSL_X509_get_subject_name #define X509_REQ_get_subject_name wolfSSL_X509_get_subject_name #define X509_get_pubkey wolfSSL_X509_get_pubkey From 2a20896e44db5f8da74fb570ec7fbcc736a79f26 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 4 Sep 2020 15:26:32 +0200 Subject: [PATCH 24/53] Add CRL loading to wolfSSL_PEM_X509_INFO_read_bio --- src/ssl.c | 358 +++++++++++++++++++++++++++++++++------- wolfcrypt/src/asn.c | 20 ++- wolfssl/openssl/ssl.h | 2 +- wolfssl/ssl.h | 7 + wolfssl/wolfcrypt/asn.h | 3 + 5 files changed, 318 insertions(+), 72 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5db86f8b1..3de00696b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18031,6 +18031,7 @@ static WOLFSSL_X509* wolfSSL_X509_X509_REQ_d2i(WOLFSSL_X509** x509, const byte* in, int len, int req) { WOLFSSL_X509 *newX509 = NULL; + int type = req ? CERTREQ_TYPE : CERT_TYPE; WOLFSSL_ENTER("wolfSSL_X509_d2i"); @@ -18058,7 +18059,7 @@ static WOLFSSL_X509* wolfSSL_X509_X509_REQ_d2i(WOLFSSL_X509** x509, #ifdef WOLFSSL_CERT_REQ cert->isCSR = req; #endif - if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) { + if (ParseCertRelative(cert, type, 0, NULL) == 0) { newX509 = wolfSSL_X509_new(); if (newX509 != NULL) { if (CopyDecodedToX509(newX509, cert) != 0) { @@ -20388,9 +20389,12 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) } #endif /* !NO_FILESYSTEM */ -WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( - const unsigned char* buf, int sz, int format) +#endif /* NO_FILESYSTEM */ + +static WOLFSSL_X509* wolfSSL_X509_X509_REQ_load_certificate_buffer( + const unsigned char* buf, int sz, int format, int type) { + int ret; WOLFSSL_X509* x509 = NULL; DerBuffer* der = NULL; @@ -20399,7 +20403,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( if (format == WOLFSSL_FILETYPE_PEM) { #ifdef WOLFSSL_PEM_TO_DER - if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, NULL, NULL) != 0) { + if (PemToDer(buf, sz, type, &der, NULL, NULL, NULL) != 0) { FreeDer(&der); } #else @@ -20407,7 +20411,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( #endif } else { - ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL); + ret = AllocDer(&der, (word32)sz, type, NULL); if (ret == 0) { XMEMCPY(der->buffer, buf, sz); } @@ -20429,7 +20433,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( #endif { InitDecodedCert(cert, der->buffer, der->length, NULL); - if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) { + if (ParseCertRelative(cert, type, 0, NULL) == 0) { x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL, DYNAMIC_TYPE_X509); if (x509 != NULL) { @@ -20453,7 +20457,23 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( return x509; } -#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || SESSION_CERTS */ +WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( + const unsigned char* buf, int sz, int format) +{ + return wolfSSL_X509_X509_REQ_load_certificate_buffer(buf, sz, + format, CERT_TYPE); +} + +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer( + const unsigned char* buf, int sz, int format) +{ + return wolfSSL_X509_X509_REQ_load_certificate_buffer(buf, sz, + format, CERTREQ_TYPE); +} +#endif + +#endif /* KEEP_PEER_CERT || SESSION_CERTS */ /* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function KEEP_OUR_CERT is to insure ability for returning ssl certificate */ @@ -40026,22 +40046,20 @@ cleanup: return XSTRNCMP(_x, _y, x->sz); /* y sz is the same */ } - #ifndef NO_BIO - - WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, - pem_password_cb *cb, void *u) + static WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_X509_REQ(WOLFSSL_BIO *bp, + WOLFSSL_X509 **x, pem_password_cb *cb, void *u, int type) { WOLFSSL_X509* x509 = NULL; #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM) unsigned char* pem = NULL; int pemSz; - long i = 0, l; + long i = 0, l, footerSz; const char* footer = NULL; WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509"); - if (bp == NULL) { + if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) { WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG); return NULL; } @@ -40059,21 +40077,27 @@ cleanup: return NULL; i = 0; - if (wc_PemGetHeaderFooter(CERT_TYPE, NULL, &footer) != 0) { + if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) { XFREE(pem, 0, DYNAMIC_TYPE_PEM); return NULL; } + footerSz = XSTRLEN(footer); /* TODO: Inefficient - * reading in one byte at a time until see "END CERTIFICATE" + * reading in one byte at a time until see the footer */ while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) { i++; - if (i > 26 && XMEMCMP((char *)&pem[i-26], footer, 25) == 0) { - if (pem[i-1] == '\r') { - /* found \r , Windows line ending is \r\n so try to read one - * more byte for \n, ignoring return value */ - (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1); + if (i > footerSz && XMEMCMP((char *)&pem[i-footerSz], footer, + footerSz) == 0) { + if (wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) { + /* attempt to read newline following footer */ + i++; + if (pem[i-1] == '\r') { + /* found \r , Windows line ending is \r\n so try to read one + * more byte for \n, ignoring return value */ + (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1); + } } break; } @@ -40083,8 +40107,14 @@ cleanup: WOLFSSL_ERROR(ASN_NO_PEM_HEADER); #endif pemSz = (int)i; - x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz, - WOLFSSL_FILETYPE_PEM); + #ifdef WOLFSSL_CERT_REQ + if (type == CERTREQ_TYPE) + x509 = wolfSSL_X509_REQ_load_certificate_buffer(pem, pemSz, + WOLFSSL_FILETYPE_PEM); + else + #endif + x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz, + WOLFSSL_FILETYPE_PEM); if (x != NULL) { *x = x509; @@ -40101,6 +40131,21 @@ cleanup: return x509; } + + WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, + pem_password_cb *cb, void *u) + { + return wolfSSL_PEM_read_bio_X509_X509_REQ(bp, x, cb, u, CERT_TYPE); + } + +#ifdef WOLFSSL_CERT_REQ + WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, + pem_password_cb *cb, void *u) + { + return wolfSSL_PEM_read_bio_X509_X509_REQ(bp, x, cb, u, CERTREQ_TYPE); + } +#endif + WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp, WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u) { @@ -40691,8 +40736,8 @@ err: { if (xPkey != NULL) { wolfSSL_EVP_PKEY_free(xPkey->dec_pkey); + XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY); } - XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY); } @@ -40736,6 +40781,155 @@ err: return wolfSSL_X509_PKEY_set(info->x_pkey, x509); } + /** + * This read one structure from bio and returns the read structure + * in the appropriate output parameter (x509, crl, x_pkey). The + * output parameters must be set to NULL. + * @param bio Input for reading structures + * @param cb Password callback + * @param x509 Output + * @param crl Output + * @param x_pkey Output + * @return WOLFSSL_SUCCESSS on success and WOLFSSL_FAILURE otherwise + */ + static int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio( + WOLFSSL_BIO* bio, pem_password_cb* cb, + WOLFSSL_X509** x509, WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey) + { + +#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM) + char* pem = NULL; + long i = 0, l; + const char* header = NULL; + const char* headerEnd = NULL; + const char* footer = NULL; + const char* footerEnd = NULL; + DerBuffer* der = NULL; + + (void)cb; + + if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) { + WOLFSSL_MSG("Bad input parameter or output parameters " + "not set to a NULL value."); + return WOLFSSL_FAILURE; + } + + if ((l = wolfSSL_BIO_get_len(bio)) <= 0) { + #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) + /* No certificate in buffer */ + WOLFSSL_ERROR(ASN_NO_PEM_HEADER); + #endif + return WOLFSSL_FAILURE; + } + + pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM); + if (pem == NULL) + return WOLFSSL_FAILURE; + + if (wolfSSL_BIO_read(bio, &pem[i], pem_struct_min_sz) != + pem_struct_min_sz) { + goto err; + } + i += pem_struct_min_sz; + + /* Read the header and footer */ + while ((l = wolfSSL_BIO_read(bio, &pem[i], 1)) == 1) { + i++; + if (!header) + header = XSTRNSTR(pem, "-----", i); + else if (header) { + if (!headerEnd) { + headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----"), + "-----", i - (header - pem)); + if (headerEnd) { + headerEnd += XSTR_SIZEOF("-----"); + /* Read in the newline */ + (void)wolfSSL_BIO_read(bio, &pem[i], 1); + i++; + if (*headerEnd != '\n' && *headerEnd != '\r') { + WOLFSSL_MSG("Missing newline after header"); + goto err; + } + } + } + else if (!footer) { + footer = XSTRNSTR(headerEnd, "-----END ", + i - (headerEnd - pem)); + } + else if (!footerEnd) { + footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"), + "-----", i - + (footer + XSTR_SIZEOF("-----") - pem)); + if (footerEnd) { + footerEnd += XSTR_SIZEOF("-----"); + /* Now check that footer matches header */ + if (XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "), + footer + XSTR_SIZEOF("-----END "), + headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) + != 0) { + WOLFSSL_MSG("Header and footer don't match"); + goto err; + } + /* header and footer match */ + break; + } + } + else { + break; + } + } + } + if (!footerEnd) /* Only check footerEnd since it is set last */ + WOLFSSL_ERROR(ASN_NO_PEM_HEADER); + else { + if (headerEnd - header == + XSTR_SIZEOF("-----BEGIN CERTIFICATE-----") && + XMEMCMP(header, "-----BEGIN CERTIFICATE-----", + XSTR_SIZEOF("-----BEGIN CERTIFICATE-----")) == 0) { + /* We have a certificate */ + WOLFSSL_MSG("Parsing x509 cert"); + *x509 = wolfSSL_X509_load_certificate_buffer( + (const unsigned char*) header, + footerEnd - header, WOLFSSL_FILETYPE_PEM); + if (!*x509) { + WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error"); + goto err; + } + } + else if (headerEnd - header == + XSTR_SIZEOF("-----BEGIN X509 CRL-----") && + XMEMCMP(header, "-----BEGIN X509 CRL-----", + XSTR_SIZEOF("-----BEGIN X509 CRL-----")) == 0) { + /* We have a crl */ + WOLFSSL_MSG("Parsing crl"); + if((PemToDer((const unsigned char*) header, footerEnd - header, + CRL_TYPE, &der, NULL, NULL, NULL)) < 0) { + WOLFSSL_MSG("PemToDer error"); + goto err; + } + *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length); + if (!*crl) { + WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error"); + goto err; + } + } + else { + /* TODO support WOLFSSL_X509_PKEY as well */ + WOLFSSL_MSG("Unsupported PEM structure"); + goto err; + } + } + + XFREE(pem, 0, DYNAMIC_TYPE_PEM); + return WOLFSSL_SUCCESS; +err: + if (pem) + XFREE(pem, 0, DYNAMIC_TYPE_PEM); + if (der) + FreeDer(&der); + return WOLFSSL_FAILURE; +#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */ + } /* * bio WOLFSSL_BIO to read certificates from @@ -40749,44 +40943,74 @@ err: WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, pem_password_cb* cb, void* u) { - WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk; - WOLFSSL_X509* x509 = NULL; + WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL; int ret = WOLFSSL_SUCCESS; + (void)u; + WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio"); - /* attempt to used passed in stack or create a new one */ - if (sk != NULL) { - localSk = sk; - } - else { - localSk = wolfSSL_sk_X509_INFO_new_null(); - } - if (localSk == NULL) { - WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", MEMORY_E); - return NULL; - } - /* parse through BIO and push new info's found onto stack */ - do { - x509 = wolfSSL_PEM_read_bio_X509(bio, NULL, cb, u); - if (x509 != NULL) { + while (1) { + WOLFSSL_X509 *x509 = NULL; + WOLFSSL_X509_CRL *crl = NULL; + WOLFSSL_X509_PKEY *x_pkey = NULL; + + if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb, + &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) { WOLFSSL_X509_INFO* current; current = wolfSSL_X509_INFO_new(); if (current == NULL) { WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", MEMORY_E); + wolfSSL_sk_free(localSk); return NULL; } - ret = wolfSSL_X509_INFO_set(current, x509); - if (ret != WOLFSSL_SUCCESS) { - wolfSSL_X509_free(x509); + if (x509) { + ret = wolfSSL_X509_INFO_set(current, x509); + } + else if (crl) { + current->crl = crl; + ret = WOLFSSL_SUCCESS; + } + else if (x_pkey) { + current->x_pkey = x_pkey; + ret = WOLFSSL_SUCCESS; } else { + WOLFSSL_MSG("No output parameters set"); + WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", WOLFSSL_FAILURE); + wolfSSL_sk_free(localSk); + return NULL; + } + if (ret != WOLFSSL_SUCCESS) { + wolfSSL_X509_free(x509); + wolfSSL_X509_CRL_free(crl); + wolfSSL_X509_PKEY_free(x_pkey); + } + else { + if (!localSk) { + /* attempt to used passed in stack + * or create a new one */ + if (sk != NULL) { + localSk = sk; + } + else { + localSk = wolfSSL_sk_X509_INFO_new_null(); + } + if (localSk == NULL) { + WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", + MEMORY_E); + return NULL; + } + } wolfSSL_sk_X509_INFO_push(localSk, current); } } - } while (x509 != NULL && ret == WOLFSSL_SUCCESS); + else { + break; + } + } WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret); return localSk; } @@ -50230,11 +50454,13 @@ void wolfSSL_PKCS7_free(PKCS7* pkcs7) XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7); } } + void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7) { wolfSSL_PKCS7_free(p7); return; } + PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len) { WOLFSSL_PKCS7* pkcs7 = NULL; @@ -50242,7 +50468,7 @@ PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len) WOLFSSL_ENTER("wolfSSL_d2i_PKCS7"); - if (in == NULL) + if (in == NULL || *in == NULL) return NULL; if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL) @@ -50260,10 +50486,13 @@ PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len) return NULL; } XMEMCPY(pkcs7->data, *in, pkcs7->len); - *in += pkcs7->len; - + if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len) != 0) { + wolfSSL_PKCS7_free((PKCS7*)pkcs7); + return NULL; + } if (p7 != NULL) *p7 = (PKCS7*)pkcs7; + *in += pkcs7->len; return (PKCS7*)pkcs7; } @@ -50374,7 +50603,7 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, WOLFSSL_BIO* out) { int ret; - PKCS7* p7; + WOLFSSL_PKCS7* p7; WC_RNG rng; byte cleanRng = 0; @@ -50385,9 +50614,12 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, return WOLFSSL_FAILURE; } - p7 = &((WOLFSSL_PKCS7*)pkcs7)->pkcs7; + p7 = (WOLFSSL_PKCS7*)pkcs7; - if (p7->certList) { + /* take ownership of certs */ + p7->certs = certs; + + if (pkcs7->certList) { WOLFSSL_MSG("wolfSSL_PKCS7_encode_certs called multiple times on same " "struct"); return WOLFSSL_FAILURE; @@ -50395,23 +50627,23 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, if (certs) { /* Save some of the values */ - int hashOID = p7->hashOID; - byte version = p7->version; + int hashOID = pkcs7->hashOID; + byte version = pkcs7->version; if (!certs->data.x509 || !certs->data.x509->derCert) { WOLFSSL_MSG("Missing cert"); return WOLFSSL_FAILURE; } - if (wc_PKCS7_InitWithCert(p7, certs->data.x509->derCert->buffer, + if (wc_PKCS7_InitWithCert(pkcs7, certs->data.x509->derCert->buffer, certs->data.x509->derCert->length) != 0) { WOLFSSL_MSG("wc_PKCS7_InitWithCert error"); return WOLFSSL_FAILURE; } certs = certs->next; - p7->hashOID = hashOID; - p7->version = version; + pkcs7->hashOID = hashOID; + pkcs7->version = version; } /* Add the certs to the PKCS7 struct */ @@ -50420,7 +50652,7 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, WOLFSSL_MSG("Missing cert"); return WOLFSSL_FAILURE; } - if (wc_PKCS7_AddCertificate(p7, certs->data.x509->derCert->buffer, + if (wc_PKCS7_AddCertificate(pkcs7, certs->data.x509->derCert->buffer, certs->data.x509->derCert->length) != 0) { WOLFSSL_MSG("wc_PKCS7_AddCertificate error"); return WOLFSSL_FAILURE; @@ -50428,25 +50660,25 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, certs = certs->next; } - if (wc_PKCS7_SetSignerIdentifierType(p7, DEGENERATE_SID) != 0) { + if (wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID) != 0) { WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error"); return WOLFSSL_FAILURE; } - if (!p7->rng) { + if (!pkcs7->rng) { if (wc_InitRng(&rng) != 0) { WOLFSSL_MSG("wc_InitRng error"); return WOLFSSL_FAILURE; } - p7->rng = &rng; + pkcs7->rng = &rng; cleanRng = 1; } - ret = wolfSSL_i2d_PKCS7_bio(out, p7); + ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7); if (cleanRng) { wc_FreeRng(&rng); - p7->rng = NULL; + pkcs7->rng = NULL; } return ret; @@ -50469,10 +50701,10 @@ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) if (p7->certs) return p7->certs; - ret = wolfSSL_sk_X509_new(); - for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) { WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i], p7->pkcs7.certSz[i]); + if (!ret) + ret = wolfSSL_sk_X509_new(); if (x509) { if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) { wolfSSL_X509_free(x509); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index d686dfb39..d56cbd5c2 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -9481,6 +9481,11 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) return BAD_FUNC_ARG; } +#ifdef WOLFSSL_CERT_REQ + if (type == CERTREQ_TYPE) + cert->isCSR = 1; +#endif + if (cert->sigCtx.state == SIG_STATE_BEGIN) { cert->badDate = 0; cert->criticalExt = 0; @@ -10128,8 +10133,9 @@ void wc_FreeDer(DerBuffer** pDer) #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM) -/* Note: If items added make sure MAX_X509_HEADER_SZ is - updated to reflect maximum length */ +/* Note: If items added make sure MAX_X509_HEADER_SZ is + updated to reflect maximum length and pem_struct_min_sz + to reflect minimum size */ wcchar BEGIN_CERT = "-----BEGIN CERTIFICATE-----"; wcchar END_CERT = "-----END CERTIFICATE-----"; #ifdef WOLFSSL_CERT_REQ @@ -10172,11 +10178,9 @@ wcchar END_PUB_KEY = "-----END PUBLIC KEY-----"; wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----"; wcchar END_EDDSA_PRIV = "-----END EDDSA PRIVATE KEY-----"; #endif -#ifdef HAVE_CRL - const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----"; - wcchar END_CRL = "-----END X509 CRL-----"; -#endif +const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----" + "-----END X509 CRL-----"); static WC_INLINE char* SkipEndOfLineChars(char* line, const char* endOfLine) { @@ -10702,8 +10706,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } } else #ifdef HAVE_CRL - if ((type == CRL_TYPE) && (header != BEGIN_CRL)) { - header = BEGIN_CRL; footer = END_CRL; + if ((type == CRL_TYPE) && (header != BEGIN_X509_CRL)) { + header = BEGIN_X509_CRL; footer = END_X509_CRL; } else #endif { diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index faa2abf73..ee4aecfa1 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -369,7 +369,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define i2d_X509 wolfSSL_i2d_X509 #define d2i_X509 wolfSSL_d2i_X509 #define PEM_read_bio_X509 wolfSSL_PEM_read_bio_X509 -#define PEM_read_bio_X509_REQ wolfSSL_PEM_read_bio_X509 +#define PEM_read_bio_X509_REQ wolfSSL_PEM_read_bio_X509_REQ #define PEM_read_bio_X509_CRL wolfSSL_PEM_read_bio_X509_CRL #define PEM_read_bio_X509_AUX wolfSSL_PEM_read_bio_X509_AUX #define PEM_read_X509 wolfSSL_PEM_read_X509 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c09990a12..cef18b570 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2221,6 +2221,10 @@ WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509* #endif WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( const unsigned char* buf, int sz, int format); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer( + const unsigned char* buf, int sz, int format); +#endif #ifdef WOLFSSL_SEP WOLFSSL_API unsigned char* @@ -3488,6 +3492,9 @@ WOLFSSL_API int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX*, int); WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +#ifdef WOLFSSL_CERT_REQ +WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +#endif WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp, WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index c99608915..371accac2 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -143,6 +143,9 @@ enum DN_Tags { ASN_DOMAIN_COMPONENT = 0x19 /* DC */ }; +/* This is the size of the smallest possible PEM header and footer */ +extern const int pem_struct_min_sz; + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) typedef struct WOLFSSL_ObjectInfo { int nid; From b808124a474065fe965e2a1cb852749c958bb486 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 10 Sep 2020 09:40:40 +0200 Subject: [PATCH 25/53] Add DSA support to ConfirmSignature and add DSAwithSHA256 --- src/ssl.c | 4 ++ wolfcrypt/src/asn.c | 109 ++++++++++++++++++++++++++++++--- wolfssl/wolfcrypt/asn.h | 7 ++- wolfssl/wolfcrypt/asn_public.h | 1 + 4 files changed, 110 insertions(+), 11 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 3de00696b..b308af176 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -29981,6 +29981,8 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { #ifndef NO_DSA #ifndef NO_SHA { CTC_SHAwDSA, CTC_SHAwDSA, oidSigType, "DSA-SHA1", "dsaWithSHA1"}, + { CTC_SHA256wDSA, CTC_SHA256wDSA, oidSigType, "dsa_with_SHA256", + "dsa_with_SHA256"}, #endif #endif /* NO_DSA */ #ifndef NO_RSA @@ -47527,6 +47529,8 @@ int oid2nid(word32 oid, int grp) #ifndef NO_DSA case CTC_SHAwDSA: return CTC_SHAwDSA; + case CTC_SHA256wDSA: + return CTC_SHA256wDSA; #endif /* NO_DSA */ #ifndef NO_RSA case CTC_MD2wRSA: diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index d56cbd5c2..7334ec123 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -524,6 +524,7 @@ static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx) #if !defined(NO_DSA) && !defined(NO_SHA) static const char sigSha1wDsaName[] = "SHAwDSA"; +static const char sigSha256wDsaName[] = "SHA256wDSA"; #endif /* NO_DSA */ #ifndef NO_RSA #ifdef WOLFSSL_MD2 @@ -577,6 +578,8 @@ const char* GetSigName(int oid) { #if !defined(NO_DSA) && !defined(NO_SHA) case CTC_SHAwDSA: return sigSha1wDsaName; + case CTC_SHA256wDSA: + return sigSha256wDsaName; #endif /* NO_DSA && NO_SHA */ #ifndef NO_RSA #ifdef WOLFSSL_MD2 @@ -1469,6 +1472,7 @@ static word32 SetBitString16Bit(word16 val, byte* output) /* sigType */ #if !defined(NO_DSA) && !defined(NO_SHA) static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3}; + static const byte sigSha256wDsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 2}; #endif /* NO_DSA */ #ifndef NO_RSA #ifdef WOLFSSL_MD2 @@ -1759,6 +1763,10 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) oid = sigSha1wDsaOid; *oidSz = sizeof(sigSha1wDsaOid); break; + case CTC_SHA256wDSA: + oid = sigSha256wDsaOid; + *oidSz = sizeof(sigSha256wDsaOid); + break; #endif /* NO_DSA */ #ifndef NO_RSA #ifdef WOLFSSL_MD2 @@ -7015,10 +7023,10 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST); sigCtx->digest = NULL; } -#ifndef NO_RSA - if (sigCtx->plain) { - XFREE(sigCtx->plain, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE); - sigCtx->plain = NULL; +#if !defined(NO_RSA) && !defined(NO_DSA) + if (sigCtx->sigCpy) { + XFREE(sigCtx->sigCpy, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE); + sigCtx->sigCpy = NULL; } #endif #ifndef NO_ASN_CRYPT @@ -7030,6 +7038,12 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA); break; #endif /* !NO_RSA */ + #ifndef NO_DSA + case DSAk: + wc_FreeDsaKey(sigCtx->key.dsa); + XFREE(sigCtx->key.dsa, sigCtx->heap, DYNAMIC_TYPE_DSA); + break; + #endif #ifdef HAVE_ECC case ECDSAk: wc_ecc_free(sigCtx->key.ecc); @@ -7110,6 +7124,7 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID, #ifndef NO_SHA256 case CTC_SHA256wRSA: case CTC_SHA256wECDSA: + case CTC_SHA256wDSA: if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) { *typeH = SHA256h; *digestSz = WC_SHA256_DIGEST_SIZE; @@ -7217,9 +7232,9 @@ static int ConfirmSignature(SignatureCtx* sigCtx, sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), sigCtx->heap, DYNAMIC_TYPE_RSA); - sigCtx->plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, + sigCtx->sigCpy = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE); - if (sigCtx->key.rsa == NULL || sigCtx->plain == NULL) { + if (sigCtx->key.rsa == NULL || sigCtx->sigCpy == NULL) { ERROR_OUT(MEMORY_E, exit_cs); } if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap, @@ -7235,7 +7250,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, WOLFSSL_MSG("ASN Key decode error RSA"); goto exit_cs; } - XMEMCPY(sigCtx->plain, sig, sigSz); + XMEMCPY(sigCtx->sigCpy, sig, sigSz); sigCtx->out = NULL; #ifdef WOLFSSL_ASYNC_CRYPT @@ -7244,6 +7259,59 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* !NO_RSA */ + #ifndef NO_DSA + case DSAk: + { + word32 idx = 0; + mp_int r, s; + + if (sigSz < DSA_SIG_SIZE) { + WOLFSSL_MSG("Verify Signature is too small"); + ERROR_OUT(BUFFER_E, exit_cs); + } + sigCtx->key.dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), + sigCtx->heap, DYNAMIC_TYPE_DSA); + sigCtx->sigCpy = (byte*)XMALLOC(sigSz, + sigCtx->heap, DYNAMIC_TYPE_SIGNATURE); + if (sigCtx->key.dsa == NULL || sigCtx->sigCpy == NULL) { + ERROR_OUT(MEMORY_E, exit_cs); + } + if ((ret = wc_InitDsaKey_h(sigCtx->key.dsa, sigCtx->heap)) != 0) { + WOLFSSL_MSG("wc_InitDsaKey_h error"); + goto exit_cs; + } + if ((ret = wc_DsaPublicKeyDecode(key, &idx, sigCtx->key.dsa, + keySz)) != 0) { + WOLFSSL_MSG("ASN Key decode error RSA"); + goto exit_cs; + } + if (sigSz != DSA_SIG_SIZE) { + /* Try to parse it as the contents of a bitstring */ + idx = 0; + if (DecodeECC_DSA_Sig(sig + idx, sigSz - idx, + &r, &s) != 0) { + WOLFSSL_MSG("DSA Sig is in unrecognized or " + "incorrect format"); + ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs); + } + if (mp_to_unsigned_bin_len(&r, sigCtx->sigCpy, + DSA_HALF_SIZE) != MP_OKAY || + mp_to_unsigned_bin_len(&s, + sigCtx->sigCpy + DSA_HALF_SIZE, + DSA_HALF_SIZE) != MP_OKAY) { + WOLFSSL_MSG("DSA Sig is in unrecognized or " + "incorrect format"); + ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs); + } + mp_free(&r); + mp_free(&s); + } + else { + XMEMCPY(sigCtx->sigCpy, sig, DSA_SIG_SIZE); + } + break; + } + #endif /* !NO_DSA */ #ifdef HAVE_ECC case ECDSAk: { @@ -7351,7 +7419,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, #ifdef HAVE_PK_CALLBACKS if (sigCtx->pkCbRsa) { ret = sigCtx->pkCbRsa( - sigCtx->plain, sigSz, &sigCtx->out, + sigCtx->sigCpy, sigSz, &sigCtx->out, key, keySz, sigCtx->pkCtxRsa); } @@ -7361,7 +7429,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, #ifdef WOLFSSL_RENESAS_TSIP_TLS if (rsaKeyIdx != NULL) { - ret = tsip_tls_CertVerify(buf, bufSz, sigCtx->plain, + ret = tsip_tls_CertVerify(buf, bufSz, sigCtx->sigCpy, sigSz, sigCtx->pubkey_n_start - sigCtx->certBegin, sigCtx->pubkey_n_len - 1, @@ -7378,12 +7446,20 @@ static int ConfirmSignature(SignatureCtx* sigCtx, } } else #endif - ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz, + ret = wc_RsaSSL_VerifyInline(sigCtx->sigCpy, sigSz, &sigCtx->out, sigCtx->key.rsa); } break; } #endif /* !NO_RSA */ + #ifndef NO_DSA + case DSAk: + { + ret = wc_DsaVerify(sigCtx->digest, sigCtx->sigCpy, + sigCtx->key.dsa, &sigCtx->verify); + break; + } + #endif /* !NO_DSA */ #if defined(HAVE_ECC) case ECDSAk: { @@ -7482,6 +7558,19 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* NO_RSA */ + #ifndef NO_DSA + case DSAk: + { + if (sigCtx->verify == 1) { + ret = 0; + } + else { + WOLFSSL_MSG("DSA Verify didn't match"); + ret = ASN_SIG_CONFIRM_E; + } + break; + } + #endif /* !NO_DSA */ #ifdef HAVE_ECC case ECDSAk: { diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 371accac2..f7132f64b 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -677,7 +677,9 @@ struct SignatureCtx { byte* digest; #ifndef NO_RSA byte* out; - byte* plain; +#endif +#if !defined(NO_RSA) && !defined(NO_DSA) + byte* sigCpy; #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) int verify; @@ -686,6 +688,9 @@ struct SignatureCtx { #ifndef NO_RSA struct RsaKey* rsa; #endif + #ifndef NO_DSA + struct DsaKey* dsa; + #endif #ifdef HAVE_ECC struct ecc_key* ecc; #endif diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index e0024c922..480b64f64 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -126,6 +126,7 @@ enum CertType { /* Signature type, by OID sum */ enum Ctc_SigType { CTC_SHAwDSA = 517, + CTC_SHA256wDSA = 416, CTC_MD2wRSA = 646, CTC_MD5wRSA = 648, CTC_SHAwRSA = 649, From 6a635b339cd996b3d0f16abe41637a7b45b7888b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 10 Sep 2020 14:38:26 +0200 Subject: [PATCH 26/53] Fixes - Fix challengePw copy in ReqCertFromX509 - Proper header length in wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio - Special case for extended key usage in wolfSSL_OBJ_cmp - Numerical input in wolfSSL_OBJ_txt2obj can just be encoded with EncodePolicyOID. Searching for the sum can return wrong values since they are not unique. --- src/ssl.c | 69 ++++++++++++++++++++++++++++++++++++++++++----------- tests/api.c | 24 +++++++++++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b308af176..f0f568fe1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -39363,10 +39363,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) /* Extended Key Usage not supported. */ #endif #ifdef WOLFSSL_CERT_REQ - if (XSTRLEN(cert->challengePw) > 0) { - XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE); - cert->challengePwPrintableString = 1; - } + XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE); + cert->challengePwPrintableString = req->challengePw[0] != 0; #endif } @@ -40842,7 +40840,7 @@ err: else if (header) { if (!headerEnd) { headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----"), - "-----", i - (header - pem)); + "-----", i - (header + XSTR_SIZEOF("-----") - pem)); if (headerEnd) { headerEnd += XSTR_SIZEOF("-----"); /* Read in the newline */ @@ -40881,8 +40879,11 @@ err: } } } - if (!footerEnd) /* Only check footerEnd since it is set last */ + if (!footerEnd) { + /* Only check footerEnd since it is set last */ WOLFSSL_ERROR(ASN_NO_PEM_HEADER); + goto err; + } else { if (headerEnd - header == XSTR_SIZEOF("-----BEGIN CERTIFICATE-----") && @@ -42034,6 +42035,33 @@ err: a->objSz == b->objSz) { return XMEMCMP(a->obj, b->obj, a->objSz); } + else if (a != NULL && b != NULL && a->objSz != b->objSz && + (a->type == EXT_KEY_USAGE_OID + || b->type == EXT_KEY_USAGE_OID)) { + /* Special case for EXT_KEY_USAGE_OID so that + * cmp will be treated as a substring search */ + /* Used in libest to check for id-kp-cmcRA in + * EXT_KEY_USAGE extension */ + unsigned int idx; + const byte* s; /* shorter */ + unsigned int sLen; + const byte* l; /* longer */ + unsigned int lLen; + if (a->objSz > b->objSz) { + s = b->obj; sLen = b->objSz; + l = a->obj; lLen = a->objSz; + } + else { + s = a->obj; sLen = a->objSz; + l = b->obj; lLen = b->objSz; + } + for (idx = 0; idx <= lLen - sLen; idx++) { + if (XMEMCMP(l + idx, s, sLen) == 0) { + /* Found substring */ + return 0; + } + } + } return WOLFSSL_FATAL_ERROR; } @@ -42122,7 +42150,7 @@ err: int nid = NID_undef; unsigned int outSz = MAX_OID_SZ; unsigned char out[MAX_OID_SZ]; - unsigned int sum = 0; + WOLFSSL_ASN1_OBJECT* obj; WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj"); @@ -42132,9 +42160,26 @@ err: /* If s is numerical value, try to sum oid */ ret = EncodePolicyOID(out, &outSz, s, NULL); if (ret == 0) { - for (i = 0; i < (int)outSz; i++) { - sum += out[i]; + /* If numerical encode succeeded then just + * create object from that because sums are + * not unique and can cause confusion. */ + obj = wolfSSL_ASN1_OBJECT_new(); + if (obj == NULL) { + WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); + return NULL; } + obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; + obj->obj = (byte*)XMALLOC(1 + MAX_LENGTH_SZ + outSz, NULL, + DYNAMIC_TYPE_ASN1); + if (obj->obj == NULL) { + wolfSSL_ASN1_OBJECT_free(obj); + return NULL; + } + obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ; + i = SetObjectId(outSz, (byte*)obj->obj); + XMEMCPY((byte*)obj->obj + i, out, outSz); + obj->objSz = i + outSz; + return obj; } len = (int)XSTRLEN(s); @@ -42144,11 +42189,7 @@ err: for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) { /* Short name, long name, and numerical value are interpreted */ if (no_name == 0 && ((XSTRNCMP(s, wolfssl_object_info[i].sName, len) == 0) || - (XSTRNCMP(s, wolfssl_object_info[i].lName, len) == 0) || - (wolfssl_object_info[i].id == (int)sum))) - nid = wolfssl_object_info[i].nid; - /* Only numerical value is interpreted */ - else if (no_name == 1 && wolfssl_object_info[i].id == (int)sum) + (XSTRNCMP(s, wolfssl_object_info[i].lName, len) == 0))) nid = wolfssl_object_info[i].nid; } diff --git a/tests/api.c b/tests/api.c index 0687d3369..0b0b40b9b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -37890,6 +37890,13 @@ static void test_wolfSSL_d2i_X509_REQ(void) { const char* csrFile = "./certs/csr.signed.der"; const char* csrPopFile = "./certs/csr.attr.der"; + /* ./certs/csr.dsa.pem is generated using + * openssl req -newkey dsa:certs/dsaparams.pem \ + * -keyout certs/csr.dsa.key.pem -keyform PEM -out certs/csr.dsa.pem \ + * -outform PEM + * with the passphrase "wolfSSL" + */ + const char* csrDsaFile = "./certs/csr.dsa.pem"; BIO* bio = NULL; X509* req = NULL; EVP_PKEY *pub_key = NULL; @@ -37930,6 +37937,23 @@ static void test_wolfSSL_d2i_X509_REQ(void) */ AssertIntGE(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1), 0); + X509_free(req); + BIO_free(bio); + } + { + AssertNotNull(bio = BIO_new_file(csrDsaFile, "rb")); + AssertNotNull(PEM_read_bio_X509_REQ(bio, &req, NULL, NULL)); + + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + X509_free(req); BIO_free(bio); } From 65c6a71bde0f0548b82658e0dff3128b1632d081 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 14 Sep 2020 09:24:02 +0200 Subject: [PATCH 27/53] Init wolfSSL_X509_REQ_add_extensions --- src/ssl.c | 57 +++++++++++++++++++++++++++++--- wolfcrypt/src/asn.c | 73 +++++++++++++++++++++++++++-------------- wolfssl/ssl.h | 2 +- wolfssl/wolfcrypt/asn.h | 3 +- 4 files changed, 104 insertions(+), 31 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index f0f568fe1..7357b5bce 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -51586,14 +51586,61 @@ int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, return WOLFSSL_FAILURE; } -#ifndef NO_WOLFSSL_STUB int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, - WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext) + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk) { - (void)req; - (void)ext; - return WOLFSSL_FAILURE; + if (!req || !ext_sk) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + while (ext_sk) { + WOLFSSL_X509_EXTENSION* ext = ext_sk->data.ext; + + switch (ext->obj->type) { + case NID_subject_alt_name: + { + WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk; + while (gns) { + WOLFSSL_GENERAL_NAME* gn = gns->data.gn; + if (!gn || !gn->d.ia5 || + wolfSSL_X509_add_altname_ex(req, gn->d.ia5->data, + gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Subject alternative name missing extension"); + return WOLFSSL_FAILURE; + } + gns = gns->next; + } + req->subjAltNameSet = 1; + req->subjAltNameCrit = ext->crit; + break; + } + case NID_key_usage: + if (ext && ext->value.data && + ext->value.length == sizeof(word16)) { + req->keyUsage = *(word16*)ext->value.data; + req->keyUsageCrit = ext->crit; + } + break; + case NID_basic_constraints: + if (ext->obj) { + req->isCa = ext->obj->ca; + req->basicConstCrit = ext->crit; + if (ext->obj->pathlen) + req->pathLength = ext->obj->pathlen->length; + } + break; + default: + WOLFSSL_MSG("Unsupported extension to add"); + return WOLFSSL_FAILURE; + } + + ext_sk = ext_sk->next; + } + + return WOLFSSL_SUCCESS; } +#ifndef NO_WOLFSSL_STUB int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, const char *attrname, int type, const unsigned char *bytes, int len) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 7334ec123..dc44a3b8b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8882,18 +8882,23 @@ static int DecodeCertExtensions(DecodedCert* cert) if (input == NULL || sz == 0) return BAD_FUNC_ARG; - if (GetASNTag(input, &idx, &tag, sz) < 0) { - return ASN_PARSE_E; - } +#ifdef WOLFSSL_CERT_REQ + if (!cert->isCSR) +#endif + { /* Not included in CSR */ + if (GetASNTag(input, &idx, &tag, sz) < 0) { + return ASN_PARSE_E; + } - if (tag != ASN_EXTENSIONS) { - WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); - return ASN_PARSE_E; - } + if (tag != ASN_EXTENSIONS) { + WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); + return ASN_PARSE_E; + } - if (GetLength(input, &idx, &length, sz) < 0) { - WOLFSSL_MSG("\tfail: invalid length"); - return ASN_PARSE_E; + if (GetLength(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: invalid length"); + return ASN_PARSE_E; + } } if (GetSequence(input, &idx, &length, sz) < 0) { @@ -9626,27 +9631,33 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) WOLFSSL_MSG("attr GetSet error"); return ASN_PARSE_E; } - /* For now all supported attributes have the type value - * of ASN_PRINTABLE_STRING or ASN_UTF8STRING but as more - * attributes are supported then this will have to be done - * on a per attribute basis. */ - if (GetHeader(cert->source, &tag, - &cert->srcIdx, &len, attrMaxIdx, 1) < 0) { - WOLFSSL_MSG("attr GetHeader error"); - return ASN_PARSE_E; - } - if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING && - tag != ASN_IA5_STRING) { - WOLFSSL_MSG("Unsupported attribute value format"); - return ASN_PARSE_E; - } switch (oid) { case CHALLENGE_PASSWORD_OID: + if (GetHeader(cert->source, &tag, + &cert->srcIdx, &len, attrMaxIdx, 1) < 0) { + WOLFSSL_MSG("attr GetHeader error"); + return ASN_PARSE_E; + } + if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING && + tag != ASN_IA5_STRING) { + WOLFSSL_MSG("Unsupported attribute value format"); + return ASN_PARSE_E; + } cert->cPwd = (char*)cert->source + cert->srcIdx; cert->cPwdLen = len; cert->srcIdx += len; break; case SERIAL_NUMBER_OID: + if (GetHeader(cert->source, &tag, + &cert->srcIdx, &len, attrMaxIdx, 1) < 0) { + WOLFSSL_MSG("attr GetHeader error"); + return ASN_PARSE_E; + } + if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING && + tag != ASN_IA5_STRING) { + WOLFSSL_MSG("Unsupported attribute value format"); + return ASN_PARSE_E; + } cert->sNum = (char*)cert->source + cert->srcIdx; cert->sNumLen = len; cert->srcIdx += len; @@ -9655,6 +9666,20 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) cert->serialSz = cert->sNumLen; } break; + case EXTENSION_REQUEST_OID: + /* save extensions */ + cert->extensions = &cert->source[cert->srcIdx]; + cert->extensionsSz = len; + cert->extensionsIdx = cert->srcIdx; /* for potential later use */ + + if ((ret = DecodeCertExtensions(cert)) < 0) { + if (ret == ASN_CRIT_EXT_E) + cert->criticalExt = ret; + else + return ret; + } + cert->srcIdx += len; + break; default: WOLFSSL_MSG("Unsupported attribute type"); return ASN_PARSE_E; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index cef18b570..be30dff38 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3596,7 +3596,7 @@ WOLFSSL_API int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, WOLFSSL_API int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, WOLFSSL_EVP_MD_CTX* md_ctx); WOLFSSL_API int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, - WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext); + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk); WOLFSSL_API int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req, WOLFSSL_X509_NAME *name); WOLFSSL_API int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index f7132f64b..b6d1e836c 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -599,9 +599,10 @@ enum KeyIdType { #endif #ifdef WOLFSSL_CERT_REQ -enum CsrAttyType { +enum CsrAttrType { CHALLENGE_PASSWORD_OID = 659, SERIAL_NUMBER_OID = 94, + EXTENSION_REQUEST_OID = 666, }; #endif From 78a20ec3ae3e97d3538f5bcf23f47577f96fd488 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 14 Sep 2020 17:05:25 +0200 Subject: [PATCH 28/53] Extension manipulation --- configure.ac | 2 +- src/internal.c | 1 + src/ssl.c | 207 +++++++++++++++++++++++++++--------------- wolfcrypt/src/asn.c | 25 +++++ wolfssl/internal.h | 1 + wolfssl/openssl/ssl.h | 2 +- wolfssl/ssl.h | 1 + 7 files changed, 163 insertions(+), 76 deletions(-) diff --git a/configure.ac b/configure.ac index 51b6a04c2..842fe1563 100644 --- a/configure.ac +++ b/configure.ac @@ -4250,7 +4250,7 @@ AC_ARG_ENABLE([libest], if test "$ENABLED_LIBEST" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DHAVE_LIBEST" + AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DHAVE_LIBEST -DWOLFSSL_ALT_NAMES" # Requires opensslextra and opensslall if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" diff --git a/src/internal.c b/src/internal.c index 62bbeaa8c..365d13174 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9568,6 +9568,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) x509->subjectCN[0] = '\0'; #ifdef WOLFSSL_CERT_REQ + x509->isCSR = dCert->isCSR; /* CSR attributes */ if (dCert->cPwd) { if (dCert->cPwdLen < CTC_NAME_SIZE) { diff --git a/src/ssl.c b/src/ssl.c index 7357b5bce..0ad142dca 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8065,7 +8065,8 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert) } InitDecodedCert(&cert, rawCert, (word32)outSz, 0); - if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) { + if (ParseCert(&cert, passedCert->isCSR ? CERTREQ_TYPE : CA_TYPE, + NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); return WOLFSSL_FAILURE; } @@ -8079,16 +8080,18 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert) return WOLFSSL_FAILURE; } - if (input[idx++] != ASN_EXTENSIONS) { - WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); - FreeDecodedCert(&cert); - return WOLFSSL_FAILURE; - } + if (!passedCert->isCSR) { + if (input[idx++] != ASN_EXTENSIONS) { + WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } - if (GetLength(input, &idx, &length, sz) < 0) { - WOLFSSL_MSG("\tfail: invalid length"); - FreeDecodedCert(&cert); - return WOLFSSL_FAILURE; + if (GetLength(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: invalid length"); + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } } if (GetSequence(input, &idx, &length, sz) < 0) { @@ -8295,6 +8298,17 @@ const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x) return x509->ext_sk_full; } +/** + * Caller is responsible for freeing the returned stack. + */ +const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x) +{ + const WOLFSSL_STACK *ret = wolfSSL_X509_get0_extensions(x); + if (x) + ((WOLFSSL_X509*)x)->ext_sk_full = NULL; + return ret; +} + /* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509. * * x509 : The X509 structure to look for the extension. @@ -8389,7 +8403,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) InitDecodedCert( &cert, rawCert, (word32)outSz, 0); - if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) { + if (ParseCert(&cert, x509->isCSR ? CERTREQ_TYPE : CA_TYPE, + NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); wolfSSL_X509_EXTENSION_free(ext); return NULL; @@ -8405,18 +8420,20 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) return NULL; } - if (input[idx++] != ASN_EXTENSIONS) { - WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); - wolfSSL_X509_EXTENSION_free(ext); - FreeDecodedCert(&cert); - return NULL; - } + if (!x509->isCSR) { + if (input[idx++] != ASN_EXTENSIONS) { + WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); + wolfSSL_X509_EXTENSION_free(ext); + FreeDecodedCert(&cert); + return NULL; + } - if (GetLength(input, &idx, &length, sz) < 0) { - WOLFSSL_MSG("\tfail: invalid length"); - wolfSSL_X509_EXTENSION_free(ext); - FreeDecodedCert(&cert); - return NULL; + if (GetLength(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: invalid length"); + wolfSSL_X509_EXTENSION_free(ext); + FreeDecodedCert(&cert); + return NULL; + } } if (GetSequence(input, &idx, &length, sz) < 0) { @@ -9299,7 +9316,8 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) InitDecodedCert( &cert, rawCert, (word32)outSz, 0); - if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) { + if (ParseCert(&cert, x509->isCSR ? CERTREQ_TYPE : CA_TYPE, + NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); return WOLFSSL_FATAL_ERROR; } @@ -9313,16 +9331,18 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) return WOLFSSL_FATAL_ERROR; } - if (input[idx++] != ASN_EXTENSIONS) { - WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); - FreeDecodedCert(&cert); - return WOLFSSL_FATAL_ERROR; - } + if (!x509->isCSR) { + if (input[idx++] != ASN_EXTENSIONS) { + WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); + FreeDecodedCert(&cert); + return WOLFSSL_FATAL_ERROR; + } - if (GetLength(input, &idx, &length, sz) < 0) { - WOLFSSL_MSG("\tfail: invalid length"); - FreeDecodedCert(&cert); - return WOLFSSL_FATAL_ERROR; + if (GetLength(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: invalid length"); + FreeDecodedCert(&cert); + return WOLFSSL_FATAL_ERROR; + } } if (GetSequence(input, &idx, &length, sz) < 0) { @@ -9892,16 +9912,59 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type) } -#ifndef NO_WOLFSSL_STUB int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc) { - WOLFSSL_STUB("wolfSSL_X509_add_ext"); - (void)x509; - (void)ext; - (void)loc; - return WOLFSSL_FAILURE; + WOLFSSL_ENTER("wolfSSL_X509_add_ext"); + + if (!x509 || !ext || !ext->obj || loc >= 0) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + switch (ext->obj->type) { + case NID_subject_alt_name: + { + WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk; + while (gns) { + WOLFSSL_GENERAL_NAME* gn = gns->data.gn; + if (!gn || !gn->d.ia5 || + wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data, + gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Subject alternative name missing extension"); + return WOLFSSL_FAILURE; + } + gns = gns->next; + } + x509->subjAltNameSet = 1; + x509->subjAltNameCrit = ext->crit; + break; + } + case NID_key_usage: + if (ext && ext->value.data && + ext->value.length == sizeof(word16)) { + x509->keyUsage = *(word16*)ext->value.data; + x509->keyUsageCrit = ext->crit; + x509->keyUsageSet = 1; + } + break; + case NID_basic_constraints: + if (ext->obj) { + x509->isCa = ext->obj->ca; + x509->basicConstCrit = ext->crit; + if (ext->obj->pathlen) + x509->pathLength = ext->obj->pathlen->length; + x509->basicConstSet = 1; + } + break; + default: + WOLFSSL_MSG("Unsupported extension to add"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; } +#ifndef NO_WOLFSSL_STUB WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc) { WOLFSSL_STUB("wolfSSL_X509_delete_ext"); @@ -39366,6 +39429,10 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE); cert->challengePwPrintableString = req->challengePw[0] != 0; #endif + #ifdef WOLFSSL_ALT_NAMES + cert->altNamesSz = FlattenAltNames(cert->altNames, + sizeof(cert->altNames), req->altNames); + #endif /* WOLFSSL_ALT_NAMES */ } return ret; @@ -51586,6 +51653,31 @@ int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, return WOLFSSL_FAILURE; } +static int wolfSSL_regen_X509_REQ_der_buffer(WOLFSSL_X509* x509) +{ + byte der[4096]; + int derSz = sizeof(der); + + if (wolfSSL_X509_make_der(x509, 1, der, &derSz, 0) != + WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Unable to make DER for X509 REQ"); + return WOLFSSL_FAILURE; + } + + FreeDer(&x509->derCert); + + /* store cert for potential retrieval */ + if (AllocDer(&x509->derCert, derSz, CERT_TYPE, x509->heap) == 0) { + XMEMCPY(x509->derCert->buffer, der, derSz); + } + else { + WOLFSSL_MSG("Failed to allocate DER buffer for X509"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk) { @@ -51597,48 +51689,15 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, while (ext_sk) { WOLFSSL_X509_EXTENSION* ext = ext_sk->data.ext; - switch (ext->obj->type) { - case NID_subject_alt_name: - { - WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk; - while (gns) { - WOLFSSL_GENERAL_NAME* gn = gns->data.gn; - if (!gn || !gn->d.ia5 || - wolfSSL_X509_add_altname_ex(req, gn->d.ia5->data, - gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Subject alternative name missing extension"); - return WOLFSSL_FAILURE; - } - gns = gns->next; - } - req->subjAltNameSet = 1; - req->subjAltNameCrit = ext->crit; - break; - } - case NID_key_usage: - if (ext && ext->value.data && - ext->value.length == sizeof(word16)) { - req->keyUsage = *(word16*)ext->value.data; - req->keyUsageCrit = ext->crit; - } - break; - case NID_basic_constraints: - if (ext->obj) { - req->isCa = ext->obj->ca; - req->basicConstCrit = ext->crit; - if (ext->obj->pathlen) - req->pathLength = ext->obj->pathlen->length; - } - break; - default: - WOLFSSL_MSG("Unsupported extension to add"); + if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_X509_add_ext error"); return WOLFSSL_FAILURE; } ext_sk = ext_sk->next; } - return WOLFSSL_SUCCESS; + return wolfSSL_regen_X509_REQ_der_buffer(req); } #ifndef NO_WOLFSSL_STUB int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index dc44a3b8b..1fe8c09d8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -14259,6 +14259,20 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, else der->caSz = 0; +#ifdef WOLFSSL_ALT_NAMES + /* Alternative Name */ + if (cert->altNamesSz) { + der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames), + cert->altNames, cert->altNamesSz); + if (der->altNamesSz <= 0) + return ALT_NAME_E; + + der->extensionsSz += der->altNamesSz; + } + else + der->altNamesSz = 0; +#endif + #ifdef WOLFSSL_CERT_EXT /* SKID */ if (cert->skidSz) { @@ -14320,6 +14334,17 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, return EXTENSIONS_E; } +#ifdef WOLFSSL_ALT_NAMES + /* put Alternative Names */ + if (der->altNamesSz) { + ret = SetExtensions(der->extensions, sizeof(der->extensions), + &der->extensionsSz, + der->altNames, der->altNamesSz); + if (ret <= 0) + return EXTENSIONS_E; + } +#endif + #ifdef WOLFSSL_CERT_EXT /* put SKID */ if (der->skidSz) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 53d2c1545..fc42030de 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3760,6 +3760,7 @@ struct WOLFSSL_X509 { byte authKeyIdSet:1; byte authKeyIdCrit:1; byte issuerSet:1; + byte isCSR:1; #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ byte serial[EXTERNAL_SERIAL_SIZE]; char subjectCN[ASN_NAME_MAX]; /* common name short cut */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index ee4aecfa1..6665aaf47 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -406,7 +406,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509V3_EXT_i2d wolfSSL_X509V3_EXT_i2d #define X509_get0_extensions wolfSSL_X509_get0_extensions #define X509_get_extensions wolfSSL_X509_get0_extensions -#define X509_REQ_get_extensions wolfSSL_X509_get0_extensions +#define X509_REQ_get_extensions wolfSSL_X509_REQ_get_extensions #define X509_get_ext wolfSSL_X509_get_ext #define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID #define X509_get_issuer_name wolfSSL_X509_get_issuer_name diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index be30dff38..81482cec2 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3429,6 +3429,7 @@ WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx, #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) WOLFSSL_API int wolfSSL_X509_cmp(const WOLFSSL_X509* a, const WOLFSSL_X509* b); WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x); +WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x, int loc); WOLFSSL_API int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, const WOLFSSL_ASN1_OBJECT *obj, int lastpos); From 2a9bb906a9afd86048494f2d2af92eec89244c54 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 15 Sep 2020 12:04:48 +0200 Subject: [PATCH 29/53] Implement wolfSSL_BIO_*_connect and wolfSSL_BIO_set_conn_port Forgot to commit csr.dsa.pem for api.c --- certs/csr.dsa.pem | 15 +++++++++++++ src/ssl.c | 52 +++++++++++++++++++++++++++++++++++++++++++ wolfssl/openssl/ssl.h | 6 ++--- wolfssl/ssl.h | 6 +++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 certs/csr.dsa.pem diff --git a/certs/csr.dsa.pem b/certs/csr.dsa.pem new file mode 100644 index 000000000..96bb67aa8 --- /dev/null +++ b/certs/csr.dsa.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICSjCCAgcCAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx +ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAbcwggEsBgcqhkjO +OAQBMIIBHwKBgQDN3iVogFMN5XfW0pA5P5CiPzOUbuhPK2OrMKsVuhHqil2NzLjU +odXBR51ac2piSdEGB2f2L6M5vU4NtNMiI4TskyZaSe58iUhmTejo2FD7pXGfIhjl +5gtGh2buUo9GT7UDzu3jvuW1gdJZ6cCtTdBNJve6UOjJj/4kGT0up1I8bQIVAPtH +++yBIMgc6Uq6BG8Zm5TugmfTAoGBAJuVu4XFWEoynKpEhdZo3D4U9M5to0k46tZh +SJJaQJVJOKrhOSloWEeKSwHhLo5sY29AylA/jAuZ5HJCuLHCJkjxnIPGNy5arhEJ +2fOtH2+trVDjeDLm3o6qv9EAn7MCEhmiFewUGFwOJs75rsx7tdEm/IX+FJO2nX12 +4zWXHt7EA4GEAAKBgHFJ1dk2HPSn5Nh8tybEFs1iP/NE9Pa+2Qmea/Z/uRToZ2Uv +dM1qRagMyJfEco8fLcL1mkFH+U+HYt5Y7/rK5bD1zCYklqvMgckgHv4tRO9FKhpo +3EDe9oMz3325wzakq69O5ZfvCD4PDA3crrZaGc0ahXF7nYnNErdyhYrNkPgJoAAw +CwYJYIZIAWUDBAMCAzAAMC0CFQCLSYH6QBDBF2c0ii0bvXXzM5qJIwIUUlCx5kp7 +/DnfWP/hdw9xNrbD4jc= +-----END CERTIFICATE REQUEST----- diff --git a/src/ssl.c b/src/ssl.c index 0ad142dca..ecf8976e5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15609,6 +15609,58 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return bio; } + WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str) + { + WOLFSSL_BIO *bio; + WOLFSSL_ENTER("wolfSSL_BIO_new_connect"); + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket()); + if (bio) { + bio->ip = str; + bio->type = WOLFSSL_BIO_SOCKET; + } + return bio; + } + + long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port) + { + int p; + WOLFSSL_ENTER("wolfSSL_BIO_set_conn_port"); + + if (!b || !port) { + WOLFSSL_ENTER("Bad parameter"); + return WOLFSSL_FAILURE; + } + + p = XATOI(port); + if (!p || p < 0) { + WOLFSSL_ENTER("Port parsing error"); + return WOLFSSL_FAILURE; + } + + b->port = (word16)p; + return WOLFSSL_SUCCESS; + } + + long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b) + { + SOCKET_T sfd = SOCKET_INVALID; + WOLFSSL_ENTER("wolfSSL_BIO_do_connect"); + + if (!b) { + WOLFSSL_ENTER("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (wolfIO_TcpConnect(&sfd, b->ip, b->port, 0) < 0 ) { + WOLFSSL_ENTER("wolfIO_TcpConnect error"); + return WOLFSSL_FAILURE; + } + + b->num = sfd; + b->shutdown = BIO_CLOSE; + return WOLFSSL_SUCCESS; + } + int wolfSSL_BIO_eof(WOLFSSL_BIO* b) { diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 6665aaf47..49189d057 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -657,9 +657,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_f_ssl wolfSSL_BIO_f_ssl #define BIO_new_socket wolfSSL_BIO_new_socket #ifndef NO_WOLFSSL_STUB -#define BIO_new_connect(...) NULL -#define BIO_set_conn_port(...) 0 -#define BIO_do_connect(...) 0 +#define BIO_new_connect wolfSSL_BIO_new_connect +#define BIO_set_conn_port wolfSSL_BIO_set_conn_port +#define BIO_do_connect wolfSSL_BIO_do_connect #endif #define SSL_set_bio wolfSSL_set_bio #define BIO_set_ssl wolfSSL_BIO_set_ssl diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 81482cec2..79e230a53 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -492,6 +492,8 @@ struct WOLFSSL_BIO { void* heap; /* user heap hint */ void* ptr; /* WOLFSSL, file descriptor, MD, or mem buf */ void* usrCtx; /* user set pointer */ + const char* ip; /* IP address for wolfIO_TcpConnect */ + word16 port; /* Port for wolfIO_TcpConnect */ char* infoArg; /* BIO callback argument */ wolf_bio_info_cb infoCb; /* BIO callback */ int wrSz; /* write buffer size (mem) */ @@ -1294,6 +1296,10 @@ WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void); +WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str); +WOLFSSL_API long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port); +WOLFSSL_API long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b); + WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, void *parg); WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg); From c405c3477fafa28aed13616f311be257eab5881d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 17 Sep 2020 13:45:25 +0200 Subject: [PATCH 30/53] Protect against invalid write in RsaPad_PSS --- configure.ac | 1 + wolfcrypt/src/rsa.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/configure.ac b/configure.ac index 842fe1563..20704a3a2 100644 --- a/configure.ac +++ b/configure.ac @@ -4251,6 +4251,7 @@ AC_ARG_ENABLE([libest], if test "$ENABLED_LIBEST" = "yes" then AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DHAVE_LIBEST -DWOLFSSL_ALT_NAMES" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PSS_SALT_LEN_DISCOVER" # Requires opensslextra and opensslall if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 58e24fb6c..726c41f7b 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1252,6 +1252,11 @@ static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock, m += inputLen; o = 0; if (saltLen > 0) { + if (pkcsBlockLen < RSA_PSS_PAD_SZ + inputLen + saltLen) { + WOLFSSL_MSG("RSA-PSS Output buffer too short. " + "Recommend using WOLFSSL_PSS_SALT_LEN_DISCOVER"); + return PSS_SALTLEN_E; + } ret = wc_RNG_GenerateBlock(rng, salt, saltLen); if (ret == 0) { XMEMCPY(m, salt, saltLen); From acf3156faca7ecf1bfc520a94eb06b5663e795f5 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 18 Sep 2020 18:40:30 +0200 Subject: [PATCH 31/53] Dynamically allocate memory in wolfSSL_i2d_PKCS7_bio --- src/ssl.c | 18 ++++++++++++++++-- wolfcrypt/src/pkcs7.c | 21 ++++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ecf8976e5..d8eed8e49 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -50697,7 +50697,7 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) { - byte output[4096]; + byte* output; int len; WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio"); @@ -50706,16 +50706,30 @@ int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) return WOLFSSL_FAILURE; } - if ((len = wc_PKCS7_EncodeSignedData(p7, output, sizeof(output))) < 0) { + if ((len = wc_PKCS7_EncodeSignedData(p7, NULL, 0)) < 0) { WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); return WOLFSSL_FAILURE; } + output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!output) { + WOLFSSL_MSG("malloc error"); + return WOLFSSL_FAILURE; + } + + if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) { + WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); + XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_write(bio, output, len) <= 0) { WOLFSSL_MSG("wolfSSL_BIO_write error"); + XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FAILURE; } + XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_SUCCESS; } diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 78a368ef0..b11660029 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2235,6 +2235,7 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7, /* build PKCS#7 signedData content type */ +/* To get the output size then set output = 0 and *outputSz = 0 */ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz, byte* output2, word32* output2Sz) @@ -2270,7 +2271,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, byte signingTime[MAX_TIME_STRING_SZ]; if (pkcs7 == NULL || pkcs7->hashOID == 0 || - output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 || + outputSz == NULL || hashSz == 0 || hashBuf == NULL) { return BAD_FUNC_ARG; } @@ -2511,6 +2512,11 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif + if (*outputSz == 0 && *output2Sz == 0) { + *outputSz = totalSz; + *output2Sz = total2Sz; + return 0; + } return BUFFER_E; } @@ -2528,6 +2534,19 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + if (*outputSz == 0) { + *outputSz = totalSz; + return totalSz; + } + return BUFFER_E; + } + + if (output == NULL) { + if (pkcs7->signedAttribsSz != 0) + XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + #ifdef WOLFSSL_SMALL_STACK + XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return BUFFER_E; } From 911d5968b42b3469de103dd57b9c1320d6ef9f16 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 21 Sep 2020 13:48:53 +0200 Subject: [PATCH 32/53] Store more certs in PKCS7 struct --- src/ssl.c | 7 ++++++- wolfssl/wolfcrypt/pkcs7.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index d8eed8e49..c0818259a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25188,7 +25188,12 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) ctx->store->verify_cb(0, ctx); #endif } - return ret; + + /* OpenSSL returns 0 when a chain can't be built */ + if (ret == ASN_NO_SIGNER_E) + return WOLFSSL_FAILURE; + else + return ret; } return WOLFSSL_FATAL_ERROR; } diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index ea6b40ddb..31a4fc12d 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -48,7 +48,7 @@ /* Max number of certificates that PKCS7 structure can parse */ #ifndef MAX_PKCS7_CERTS - #define MAX_PKCS7_CERTS 4 + #define MAX_PKCS7_CERTS 15 #endif #ifndef MAX_ORI_TYPE_SZ From cd20512b900646c2f17a07c62d75c369460318f1 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 30 Sep 2020 20:23:36 +0200 Subject: [PATCH 33/53] wolfSSL_X509_REQ_add1_attr_by_txt for libest --- src/ssl.c | 51 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index c0818259a..bc24aeedc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -51770,21 +51770,46 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, return wolfSSL_regen_X509_REQ_der_buffer(req); } -#ifndef NO_WOLFSSL_STUB + int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, const char *attrname, int type, const unsigned char *bytes, int len) { WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt"); - WOLFSSL_STUB("wolfSSL_X509_REQ_add1_attr_by_txt"); - (void)req; - (void)attrname; - (void)type; - (void)bytes; - (void)len; + + if (!req || !attrname || !bytes || type != MBSTRING_ASC) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (len < 0) { + len = XSTRLEN((char*)bytes); + } + + /* For now just pretend that we support this for libest testing */ + if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") && + XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) { + /* MAC Address */ + } + else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") && + XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) { + /* ecPublicKey */ + } + else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") && + XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) { + /* ecdsa-with-SHA384 */ + } + else { + return WOLFSSL_FAILURE; + } + + /* return error if not built for libest */ +#ifdef HAVE_LIBEST + return WOLFSSL_SUCCESS; +#else return WOLFSSL_FAILURE; +#endif } -#endif /* NO_WOLFSSL_STUB */ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, int nid, int type, @@ -51830,6 +51855,16 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, return WOLFSSL_FAILURE; } break; + case NID_serialNumber: + if (len < 0) + len = XSTRLEN((char*)bytes); + if (len + 1 > EXTERNAL_SERIAL_SIZE) { + WOLFSSL_MSG("SerialNumber too long"); + return WOLFSSL_FAILURE; + } + XMEMCPY(req->serial, bytes, len); + req->serialSz = len; + break; default: WOLFSSL_MSG("Unsupported attribute"); return WOLFSSL_FAILURE; From cb84213ffd7cc2dc0d6cad36d7df1d9c71748e82 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 5 Oct 2020 20:42:26 +0200 Subject: [PATCH 34/53] Support more extensions --- src/ssl.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index bc24aeedc..be021bad2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -9911,6 +9911,33 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type) return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type); } +/** + * @param str String to copy + * @param buf Output buffer. If this contains a pointer then it is free'd + * with the DYNAMIC_TYPE_X509_EXT hint. + * @param len Output length + * @return WOLFSSL_SUCCESS on sucess and WOLFSSL_FAILURE on error + */ +static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf, + word32* len, void* heap) { + if (!str || !buf || !len) { + return WOLFSSL_FAILURE; + } + if (str->data && str->length > 0) { + if (*buf) + XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT); + *len = 0; + *buf = (byte*)XMALLOC(str->length, heap, + DYNAMIC_TYPE_X509_EXT); + if (!*buf) { + WOLFSSL_MSG("malloc error"); + return WOLFSSL_FAILURE; + } + *len = str->length; + XMEMCPY(*buf, str->data, str->length); + } + return WOLFSSL_SUCCESS; +} int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc) { @@ -9922,6 +9949,22 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int lo } switch (ext->obj->type) { + case NID_authority_key_identifier: + if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId, + &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("asn1_string_copy_to_buffer error"); + return WOLFSSL_FAILURE; + } + x509->authKeyIdCrit = ext->crit; + break; + case NID_subject_key_identifier: + if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId, + &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("asn1_string_copy_to_buffer error"); + return WOLFSSL_FAILURE; + } + x509->subjKeyIdCrit = ext->crit; + break; case NID_subject_alt_name: { WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk; @@ -50670,6 +50713,7 @@ PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len) PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) { WOLFSSL_PKCS7* pkcs7; + int ret; WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_bio"); @@ -50686,10 +50730,12 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) return NULL; } - if (wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len) != pkcs7->len) { + if ((ret = wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len)) <= 0) { wolfSSL_PKCS7_free((PKCS7*)pkcs7); return NULL; } + /* pkcs7->len may change if using b64 for example */ + pkcs7->len = ret; if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len) != 0) { return NULL; From 2197748a51e855524bbaafb3c4e56c97fc55a746 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 6 Oct 2020 17:06:38 +0200 Subject: [PATCH 35/53] Implement wolfSSL_X509_check_private_key --- src/ssl.c | 48 +++++++++++++++++++++++++++++++++++++++++------- tests/api.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index be021bad2..6b1ea17f5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42326,7 +42326,7 @@ err: /* If s is numerical value, try to sum oid */ ret = EncodePolicyOID(out, &outSz, s, NULL); - if (ret == 0) { + if (ret == 0 && outSz > 0) { /* If numerical encode succeeded then just * create object from that because sums are * not unique and can cause confusion. */ @@ -42448,15 +42448,49 @@ err: #ifdef OPENSSL_EXTRA -#ifndef NO_WOLFSSL_STUB int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key) { - (void) x509; - (void) key; - WOLFSSL_ENTER("wolfSSL_X509_check_private_key"); - WOLFSSL_STUB("X509_check_private_key"); + DecodedCert dc; + byte* der; + int derSz; + int ret; - return WOLFSSL_SUCCESS; + WOLFSSL_ENTER("wolfSSL_X509_check_private_key"); + + if (!x509 || !key) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + der = (byte*)wolfSSL_X509_get_der(x509, &derSz); + if (der == NULL) { + WOLFSSL_MSG("wolfSSL_X509_get_der error"); + return WOLFSSL_FAILURE; + } + + InitDecodedCert(&dc, der, derSz, x509->heap); + + if (ParseCertRelative(&dc, CERT_TYPE, NO_VERIFY, NULL) != 0) { + FreeDecodedCert(&dc); + return WOLFSSL_FAILURE; + } + + der = (byte*)key->pkey.ptr; + derSz = key->pkey_sz; + ret = wc_CheckPrivateKey(der, derSz, &dc); + FreeDecodedCert(&dc); + return ret == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + } + +#ifndef NO_WOLFSSL_STUB + WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( + WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk) + { + (void) sk; + WOLFSSL_ENTER("wolfSSL_dup_CA_list"); + WOLFSSL_STUB("SSL_dup_CA_list"); + + return NULL; } #endif diff --git a/tests/api.c b/tests/api.c index 0b0b40b9b..513a1a1ad 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25924,6 +25924,38 @@ static void test_wolfSSL_certs(void) #endif /* OPENSSL_EXTRA && !NO_CERTS */ } +static void test_wolfSSL_X509_check_private_key(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) && \ + defined(USE_CERT_BUFFERS_2048) + X509* x509; + EVP_PKEY* pkey; + const byte* key; + + printf(testingFmt, "wolfSSL_X509_check_private_key()"); + + /* Check with correct key */ + AssertNotNull((x509 = X509_load_certificate_file(cliCertFile, + SSL_FILETYPE_PEM))); + key = client_key_der_2048; + AssertNotNull(d2i_PrivateKey(EVP_PKEY_RSA, &pkey, + &key, (long)sizeof_client_key_der_2048)); + AssertIntEQ(X509_check_private_key(x509, pkey), 1); + EVP_PKEY_free(pkey); + + /* Check with wrong key */ + key = server_key_der_2048; + AssertNotNull(d2i_PrivateKey(EVP_PKEY_RSA, &pkey, + &key, (long)sizeof_server_key_der_2048)); + AssertIntEQ(X509_check_private_key(x509, pkey), 0); + EVP_PKEY_free(pkey); + + + X509_free(x509); + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_ASN1_TIME_print(void) { @@ -39558,6 +39590,7 @@ void ApiTest(void) test_wolfSSL_X509_check_host(); test_wolfSSL_DES(); test_wolfSSL_certs(); + test_wolfSSL_X509_check_private_key(); test_wolfSSL_ASN1_TIME_print(); test_wolfSSL_ASN1_UTCTIME_print(); test_wolfSSL_ASN1_GENERALIZEDTIME_free(); From 031ca80fe74cdac9f087ffd095718c13857ec808 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 7 Oct 2020 19:16:17 +0200 Subject: [PATCH 36/53] Fix max SSL version handling for client Enable CRL when adding one to store --- src/crl.c | 11 +++++++++++ src/internal.c | 42 ++++++++++++++++++++++++++++++++++++++---- src/ssl.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/crl.c b/src/crl.c index 75861887b..b9448490c 100644 --- a/src/crl.c +++ b/src/crl.c @@ -703,6 +703,11 @@ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newc return WOLFSSL_FAILURE; } store->crl = store->cm->crl = crl; + if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_CertManagerEnableCRL error"); + return WOLFSSL_FAILURE; + } return WOLFSSL_SUCCESS; } @@ -730,6 +735,12 @@ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newc wc_UnLockMutex(&crl->crlLock); } + if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_CertManagerEnableCRL error"); + return WOLFSSL_FAILURE; + } + WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_crl", WOLFSSL_SUCCESS); return WOLFSSL_SUCCESS; diff --git a/src/internal.c b/src/internal.c index 365d13174..b72b5ccba 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5266,6 +5266,44 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->ctx = ctx; /* only for passing to calls, options could change */ ssl->version = ctx->method->version; +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) + ssl->options.mask = ctx->mask; +#endif +#ifdef OPENSSL_EXTRA + if (ssl->version.minor == TLSv1_3_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) { + WOLFSSL_MSG("\tOption set to not allow TLSv1.3, Downgrading"); + ssl->version.minor = TLSv1_2_MINOR; + } + if (ssl->version.minor == TLSv1_2_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) { + WOLFSSL_MSG("\tOption set to not allow TLSv1.2, Downgrading"); + ssl->version.minor = TLSv1_1_MINOR; + } + if (ssl->version.minor == TLSv1_1_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) { + WOLFSSL_MSG("\tOption set to not allow TLSv1.1, Downgrading"); + ssl->options.tls1_1 = 0; + ssl->version.minor = TLSv1_MINOR; + } + if (ssl->version.minor == TLSv1_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) { + WOLFSSL_MSG("\tOption set to not allow TLSv1, Downgrading"); + ssl->options.tls = 0; + ssl->options.tls1_1 = 0; + ssl->version.minor = SSLv3_MINOR; + } + if (ssl->version.minor == SSLv3_MINOR && + (ssl->options.mask & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) { + WOLFSSL_MSG("\tError, option set to not allow SSLv3"); + return VERSION_ERROR; + } + + if (ssl->version.minor < ssl->options.minDowngrade) { + WOLFSSL_MSG("\tversion below minimum allowed, fatal error"); + return VERSION_ERROR; + } +#endif #ifdef HAVE_ECC ssl->eccTempKeySz = ctx->eccTempKeySz; @@ -5274,10 +5312,6 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) ssl->pkCurveOID = ctx->pkCurveOID; #endif - -#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) - ssl->options.mask = ctx->mask; -#endif #ifdef OPENSSL_EXTRA ssl->CBIS = ctx->CBIS; #endif diff --git a/src/ssl.c b/src/ssl.c index 6b1ea17f5..dfd178a83 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16230,6 +16230,41 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) return BAD_FUNC_ARG; } + switch (version) { +#ifdef WOLFSSL_TLS13 + case TLS1_3_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2); + FALL_THROUGH; +#else + WOLFSSL_MSG("wolfSSL TLS1.3 support not compiled in"); + return WOLFSSL_FAILURE; +#endif + case TLS1_2_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1); + FALL_THROUGH; + case TLS1_1_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1); + FALL_THROUGH; + case TLS1_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3); + FALL_THROUGH; + case SSL3_VERSION: + FALL_THROUGH; + case SSL2_VERSION: + /* Nothing to do here */ + break; +#ifdef WOLFSSL_DTLS +#ifndef NO_OLD_TLS + case DTLS1_VERSION: +#endif + case DTLS1_2_VERSION: + break; +#endif + default: + WOLFSSL_MSG("Unrecognized protocol version"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; } @@ -16237,7 +16272,7 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) { WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version"); - if (!ctx) { + if (!ctx || !ctx->method) { WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; } @@ -16263,6 +16298,13 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) /* Nothing to do here */ #endif break; +#ifdef WOLFSSL_DTLS +#ifndef NO_OLD_TLS + case DTLS1_VERSION: +#endif + case DTLS1_2_VERSION: + break; +#endif default: WOLFSSL_MSG("Unrecognized protocol version"); return WOLFSSL_FAILURE; From 8edeaae3e2207894fe9553e02e3fcacfd71cdbc3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 9 Oct 2020 15:34:14 +0200 Subject: [PATCH 37/53] Add DSA support to x509 certs --- src/ssl.c | 24 ++++++++++- wolfcrypt/src/asn.c | 89 +++++++++++++++++++++++++++++++---------- wolfssl/wolfcrypt/asn.h | 3 +- 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index dfd178a83..32378861c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -31182,6 +31182,8 @@ WOLFSSL_DH* wolfSSL_DH_new(void) return NULL; } external->internal = key; + external->priv_key = wolfSSL_BN_new(); + external->pub_key = wolfSSL_BN_new(); return external; } @@ -31995,8 +31997,6 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, wolfSSL_BN_free(dh->p); wolfSSL_BN_free(dh->q); wolfSSL_BN_free(dh->g); - wolfSSL_BN_free(dh->pub_key); - wolfSSL_BN_free(dh->priv_key); dh->p = p; dh->q = q; @@ -39821,6 +39821,9 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) #endif #ifdef HAVE_ECC ecc_key ecc; + #endif + #ifndef NO_DSA + DsaKey dsa; #endif WC_RNG rng; word32 idx = 0; @@ -39878,6 +39881,21 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) } key = (void*)&ecc; } + #endif + #ifndef NO_DSA + if (x509->pubKeyOID == DSAk) { + type = DSA_TYPE; + ret = wc_InitDsaKey(&dsa); + if (ret != 0) + return ret; + ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, &dsa, + x509->pubKey.length); + if (ret != 0) { + wc_FreeDsaKey(&dsa); + return ret; + } + key = (void*)&dsa; + } #endif if (key == NULL) { WOLFSSL_MSG("No public key found for certificate"); @@ -51676,6 +51694,8 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) cert->pubKeyOID = RSAk; else if (pkey->type == EVP_PKEY_EC) cert->pubKeyOID = ECDSAk; + else if (pkey->type == EVP_PKEY_DSA) + cert->pubKeyOID = DSAk; else return WOLFSSL_FAILURE; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 1fe8c09d8..385b5d99d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13435,7 +13435,7 @@ int SetName(byte* output, word32 outputSz, CertName* name) /* encode info from cert into DER encoded format */ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, - WC_RNG* rng, const byte* ntruKey, word16 ntruSz, + WC_RNG* rng, const byte* ntruKey, word16 ntruSz, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key) { int ret; @@ -13445,7 +13445,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, /* make sure at least one key type is provided */ if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && - ed448Key == NULL && ntruKey == NULL) { + dsaKey == NULL && ed448Key == NULL && ntruKey == NULL) { return PUBLIC_KEY_E; } @@ -13493,6 +13493,15 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, } #endif +#ifndef NO_DSA + if (cert->keyType == DSA_KEY) { + if (dsaKey == NULL) + return PUBLIC_KEY_E; + der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey, + sizeof(der->publicKey), 1); + } +#endif + #ifdef HAVE_ED25519 if (cert->keyType == ED25519_KEY) { if (ed25519Key == NULL) @@ -13997,7 +14006,7 @@ int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, /* Make an x509 Certificate v3 any key type from cert input, write to buffer */ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, - const byte* ntruKey, word16 ntruSz, + DsaKey* dsaKey, const byte* ntruKey, word16 ntruSz, ed25519_key* ed25519Key, ed448_key* ed448Key) { int ret; @@ -14007,12 +14016,23 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, DerCert der[1]; #endif - if (derBuffer == NULL) { + if (derBuffer == NULL) return BAD_FUNC_ARG; - } - cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : - (ed25519Key ? ED25519_KEY : (ed448Key ? ED448_KEY : NTRU_KEY))); + if (eccKey) + cert->keyType = ECC_KEY; + else if (rsaKey) + cert->keyType = RSA_KEY; + else if (dsaKey) + cert->keyType = DSA_KEY; + else if (ed25519Key) + cert->keyType = ED25519_KEY; + else if (ed448Key) + cert->keyType = ED448_KEY; + else if (ntruKey) + cert->keyType = NTRU_KEY; + else + return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -14020,7 +14040,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, return MEMORY_E; #endif - ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz, + ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz, dsaKey, ed25519Key, ed448Key); if (ret == 0) { if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) @@ -14042,12 +14062,15 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, void* key, WC_RNG* rng) { RsaKey* rsaKey = NULL; + DsaKey* dsaKey = NULL; ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; + else if (keyType == DSA_TYPE) + dsaKey = (DsaKey*)key; else if (keyType == ECC_TYPE) eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) @@ -14055,14 +14078,14 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, else if (keyType == ED448_TYPE) ed448Key = (ed448_key*)key; - return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0, - ed25519Key, ed448Key); + return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey, + NULL, 0, ed25519Key, ed448Key); } /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng) { - return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0, + return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL, 0, NULL, NULL); } @@ -14072,7 +14095,7 @@ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, const byte* ntruKey, word16 keySz, WC_RNG* rng) { - return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, + return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, NULL, ntruKey, keySz, NULL, NULL); } @@ -14161,8 +14184,8 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, /* encode info from cert into DER encoded format */ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, - ecc_key* eccKey, ed25519_key* ed25519Key, - ed448_key* ed448Key) + DsaKey* dsaKey, ecc_key* eccKey, + ed25519_key* ed25519Key, ed448_key* ed448Key) { (void)eccKey; (void)ed25519Key; @@ -14172,7 +14195,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, return BAD_FUNC_ARG; if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && - ed448Key == NULL) { + dsaKey == NULL && ed448Key == NULL) { return PUBLIC_KEY_E; } @@ -14219,6 +14242,15 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, } #endif +#ifndef NO_DSA + if (cert->keyType == DSA_KEY) { + if (dsaKey == NULL) + return PUBLIC_KEY_E; + der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey, + sizeof(der->publicKey), 1); + } +#endif + #ifdef HAVE_ECC if (cert->keyType == ECC_KEY) { if (eccKey == NULL) @@ -14434,8 +14466,8 @@ static int WriteCertReqBody(DerCert* der, byte* buf) static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, - RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, - ed448_key* ed448Key) + RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey, + ed25519_key* ed25519Key, ed448_key* ed448Key) { int ret; #ifdef WOLFSSL_SMALL_STACK @@ -14444,8 +14476,18 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, DerCert der[1]; #endif - cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY : - (ed448Key ? ED448_KEY: RSA_KEY)); + if (eccKey) + cert->keyType = ECC_KEY; + else if (rsaKey) + cert->keyType = RSA_KEY; + else if (dsaKey) + cert->keyType = DSA_KEY; + else if (ed25519Key) + cert->keyType = ED25519_KEY; + else if (ed448Key) + cert->keyType = ED448_KEY; + else + return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, @@ -14454,7 +14496,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, return MEMORY_E; #endif - ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key, ed448Key); + ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key); if (ret == 0) { if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) @@ -14474,12 +14516,15 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, void* key) { RsaKey* rsaKey = NULL; + DsaKey* dsaKey = NULL; ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; + else if (keyType == DSA_TYPE) + dsaKey = (DsaKey*)key; else if (keyType == ECC_TYPE) eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) @@ -14487,14 +14532,14 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, else if (keyType == ED448_TYPE) ed448Key = (ed448_key*)key; - return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key, + return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key); } int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey) { - return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL, NULL); + return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL, NULL); } #endif /* WOLFSSL_CERT_REQ */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index b6d1e836c..af8faa95d 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1247,7 +1247,8 @@ enum cert_enums { NTRU_KEY = 11, ECC_KEY = 12, ED25519_KEY = 13, - ED448_KEY = 14 + ED448_KEY = 14, + DSA_KEY = 15 }; #endif /* WOLFSSL_CERT_GEN */ From 031ce6854686c4697b280294b527f08979ff9266 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 9 Oct 2020 20:30:30 +0200 Subject: [PATCH 38/53] Differentiate between server and client sessions This is important is the client and server share memory space. If a server and client both save the same session in SessionCache it may cause inconsistencies. The hash of the sessionID will be the same causing one of the sides to overwrite the other. A possible problem is that the peer certificate will be incorrect for one of the sides. --- src/ssl.c | 22 +++++++++++++++------- wolfssl/internal.h | 2 ++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 32378861c..b9ac91001 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13165,7 +13165,8 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret, } current = &SessionCache[row].Sessions[idx]; - if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) { + if (XMEMCMP(current->sessionID, id, ID_LEN) == 0 && + current->side == ssl->options.side) { WOLFSSL_MSG("Found a session match"); if (LowResTimer() < (current->bornOn + current->timeout)) { WOLFSSL_MSG("Session valid"); @@ -13250,6 +13251,7 @@ static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom) copyInto->namedGroup = copyFrom->namedGroup; copyInto->ticketSeen = copyFrom->ticketSeen; copyInto->ticketAdd = copyFrom->ticketAdd; + copyInto->side = copyFrom->side; XMEMCPY(©Into->ticketNonce, ©From->ticketNonce, sizeof(TicketNonce)); #ifdef WOLFSSL_EARLY_DATA @@ -13434,7 +13436,8 @@ int AddSession(WOLFSSL* ssl) } for (i=0; ioptions.side) { WOLFSSL_MSG("Session already exists. Overwriting."); overwrite = 1; idx = i; @@ -13451,6 +13454,8 @@ int AddSession(WOLFSSL* ssl) session = &SessionCache[row].Sessions[idx]; } + session->side = ssl->options.side; + #ifdef WOLFSSL_TLS13 if (ssl->options.tls1_3) { XMEMCPY(session->masterSecret, ssl->session.masterSecret, SECRET_LEN); @@ -29615,9 +29620,10 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) return BAD_FUNC_ARG; } - /* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */ - size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz + - SECRET_LEN + OPAQUE8_LEN; + /* side | bornOn | timeout | sessionID len | sessionID | masterSecret | + * haveEMS */ + size += OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + + sess->sessionIDSz + SECRET_LEN + OPAQUE8_LEN; #ifdef SESSION_CERTS /* Peer chain */ size += OPAQUE8_LEN; @@ -29669,6 +29675,7 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) return 0; data = *p; + data[idx++] = sess->side; c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN; c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN; data[idx++] = sess->sessionIDSz; @@ -29787,11 +29794,12 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, idx = 0; data = (byte*)*p; - /* bornOn | timeout | sessionID len */ - if (i < OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) { + /* side | bornOn | timeout | sessionID len */ + if (i < OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) { ret = BUFFER_ERROR; goto end; } + s->side = data[idx++]; ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN; ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN; s->sessionIDSz = data[idx++]; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fc42030de..086371fdb 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3238,6 +3238,8 @@ struct WOLFSSL_SESSION { #ifdef HAVE_EX_DATA WOLFSSL_CRYPTO_EX_DATA ex_data; #endif + byte side; /* Either WOLFSSL_CLIENT_END or + WOLFSSL_SERVER_END */ }; From f5c463148f2d0c0a2a535fad2bfd8f25452c31e5 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 13 Oct 2020 16:21:27 +0200 Subject: [PATCH 39/53] check null --- src/ssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index b9ac91001..e309c292a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42037,6 +42037,10 @@ err: int ret; WOLFSSL_ENTER("wolfSSL_CTX_use_certificate"); + if (!ctx || !x || !x->derCert) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } FreeDer(&ctx->certificate); /* Make sure previous is free'd */ ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE, From 7df8f2e2bbb169bc90ef957570ad03f67d11456e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 15 Oct 2020 21:19:20 +0200 Subject: [PATCH 40/53] Internal unit tests --- src/bio.c | 12 +- src/ssl.c | 124 +++++++++------- tests/NCONF_test.cnf | 19 +++ tests/TXT_DB.txt | 33 +++++ tests/api.c | 287 ++++++++++++++++++++++++++++++++++-- wolfssl/wolfcrypt/types.h | 2 +- wolfssl/wolfcrypt/wc_port.h | 3 + 7 files changed, 411 insertions(+), 69 deletions(-) create mode 100644 tests/NCONF_test.cnf create mode 100644 tests/TXT_DB.txt diff --git a/src/bio.c b/src/bio.c index 89a3e9d29..c5e335acb 100644 --- a/src/bio.c +++ b/src/bio.c @@ -229,7 +229,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) #ifndef NO_FILESYSTEM if (bio && bio->type == WOLFSSL_BIO_FILE) { - ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr); + if (bio->ptr) + ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr); + else + ret = XREAD(bio->num, buf, len); } #endif @@ -580,8 +583,11 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) } #ifndef NO_FILESYSTEM - if (bio->type == WOLFSSL_BIO_FILE) { - ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr); + if (bio && bio->type == WOLFSSL_BIO_FILE) { + if (bio->ptr) + ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr); + else + ret = XWRITE(bio->num, data, len); } #endif diff --git a/src/ssl.c b/src/ssl.c index e309c292a..7728bb19b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15739,13 +15739,6 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_ENTER("wolfSSL_BIO_set_fd"); if (b != NULL) { - if (b->type == WOLFSSL_BIO_FILE) { - b->ptr = XFDOPEN(fd, "rw"); - if (!b->ptr) { - WOLFSSL_MSG("Error opening file descriptor"); - return WOLFSSL_FAILURE; - } - } b->num = fd; b->shutdown = (byte)closeF; } @@ -15891,6 +15884,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (bio->ptr) { XFCLOSE((XFILE)bio->ptr); } + else { + XCLOSE(bio->num); + } } #endif @@ -19733,7 +19729,7 @@ int wolfSSL_NCONF_get_number(const CONF *conf, const char *group, char *str; WOLFSSL_ENTER("wolfSSL_NCONF_get_number"); - if (!conf || !group || !name || !result) { + if (!conf || !name || !result) { WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; } @@ -19803,7 +19799,8 @@ static char* expandValue(WOLFSSL_CONF *conf, const char* section, char prevValue; if (*startIdx == '{') { - /* First read the section. Ex: ${ENV::COUNT} */ + /* First read the section. + * format: ${section_name::var_name} */ s = ++startIdx; while (*strIdx && *strIdx != ':') strIdx++; if (!strIdx || s == strIdx || strIdx[1] != ':') { @@ -19812,10 +19809,10 @@ static char* expandValue(WOLFSSL_CONF *conf, const char* section, goto expand_cleanup; } *strIdx = '\0'; - *strIdx += 2; + strIdx += 2; startIdx = strIdx; } - while (*strIdx && (XISALPHA(*strIdx) || *strIdx == '_')) + while (*strIdx && (XISALNUM(*strIdx) || *strIdx == '_')) strIdx++; endIdx = strIdx; if (startIdx == endIdx) { @@ -19987,7 +19984,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) value = idx; /* Find end of value */ idx = maxIdx-1; - while (*idx == ' ' || *idx == '\t') + while (idx >= value && (*idx == ' ' || *idx == '\t')) idx--; valueLen = idx - value + 1; @@ -20041,6 +20038,7 @@ void wolfSSL_NCONF_free(WOLFSSL_CONF *conf) WOLFSSL_ENTER("wolfSSL_NCONF_free"); if (conf) { wolfSSL_sk_CONF_VALUE_free(conf->data); + XFREE(conf, NULL, DYNAMIC_TYPE_OPENSSL); } } @@ -21628,7 +21626,7 @@ error: return ret; } -long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db) +long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db) { const WOLF_STACK_OF(WOLFSSL_STRING)* data; long totalLen = 0; @@ -21743,10 +21741,9 @@ int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field, WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx, WOLFSSL_STRING *value) { - WOLF_STACK_OF(WOLFSSL_STRING)* data; WOLFSSL_ENTER("wolfSSL_TXT_DB_get_by_index"); - if (!db || idx < 0 || idx >= db->num_fields) { + if (!db || !db->data || idx < 0 || idx >= db->num_fields) { WOLFSSL_MSG("Bad parameter"); return NULL; } @@ -21756,17 +21753,22 @@ WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx, return NULL; } - /* Set the hash and comp functions */ - data = db->data; - while (data) { - if (data->comp != db->comp[idx] || data->hash_fn != db->hash_fn[idx]) { - data->comp = db->comp[idx]; - data->hash_fn = db->hash_fn[idx]; - data->hash = 0; + /* If first data struct has correct hash and cmp function then + * assume others do too */ + if (db->data->hash_fn != db->hash_fn[idx] || + db->data->comp != db->comp[idx]) { + /* Set the hash and comp functions */ + WOLF_STACK_OF(WOLFSSL_STRING)* data = db->data; + while (data) { + if (data->comp != db->comp[idx] || + data->hash_fn != db->hash_fn[idx]) { + data->comp = db->comp[idx]; + data->hash_fn = db->hash_fn[idx]; + data->hash = 0; + } + data= data->next; } - data= data->next; } - return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value); } #endif @@ -23357,9 +23359,11 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp, const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig) { + (void)sig; + WOLFSSL_ENTER("wolfSSL_X509_signature_print"); - if (!bp || !sigalg || !sig) { + if (!bp || !sigalg) { WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; } @@ -27704,7 +27708,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, * @param class Class of parsed ASN1 object * @param inLen Length of *in buffer * @return int Depends on which bits are set in the returned int: - * 0x80 an error occured during parsing + * 0x80 an error occurred during parsing * 0x20 parsed object is constructed * 0x01 the parsed object length is infinite */ @@ -50854,8 +50858,10 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7) int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) { - byte* output; + byte* output = NULL; int len; + WC_RNG rng; + int ret = WOLFSSL_FAILURE; WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio"); if (!bio || !p7) { @@ -50863,31 +50869,45 @@ int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) return WOLFSSL_FAILURE; } + if (!p7->rng) { + if (wc_InitRng(&rng) != 0) { + WOLFSSL_MSG("wc_InitRng error"); + return WOLFSSL_FAILURE; + } + p7->rng = &rng; + } + if ((len = wc_PKCS7_EncodeSignedData(p7, NULL, 0)) < 0) { WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); - return WOLFSSL_FAILURE; + goto cleanup; } output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (!output) { WOLFSSL_MSG("malloc error"); - return WOLFSSL_FAILURE; + goto cleanup; } if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) { WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); - XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + goto cleanup; } if (wolfSSL_BIO_write(bio, output, len) <= 0) { WOLFSSL_MSG("wolfSSL_BIO_write error"); - XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + goto cleanup; } - XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_SUCCESS; + ret = WOLFSSL_SUCCESS; +cleanup: + if (p7->rng == &rng) { + wc_FreeRng(&rng); + p7->rng = NULL; + } + if (output) { + XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + return ret; } int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, @@ -50934,14 +50954,19 @@ int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs, return WOLFSSL_SUCCESS; } +/** + * This API was added as a helper function for libest. It + * encodes a stack of certificates to pkcs7 format. + * @param pkcs7 PKCS7 parameter object + * @param certs WOLFSSL_STACK_OF(WOLFSSL_X509)* + * @param out Output bio + * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure + */ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, WOLFSSL_BIO* out) { int ret; WOLFSSL_PKCS7* p7; - WC_RNG rng; - byte cleanRng = 0; - WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs"); if (!pkcs7 || !certs || !out) { @@ -51000,26 +51025,18 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, return WOLFSSL_FAILURE; } - if (!pkcs7->rng) { - if (wc_InitRng(&rng) != 0) { - WOLFSSL_MSG("wc_InitRng error"); - return WOLFSSL_FAILURE; - } - pkcs7->rng = &rng; - cleanRng = 1; - } - ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7); - if (cleanRng) { - wc_FreeRng(&rng); - pkcs7->rng = NULL; - } - return ret; } #endif /* !NO_BIO */ +/** + * This API was added as a helper functio for libest. It + * extracts a stack of certificates from the pkcs7 object. + * @param pkcs7 PKCS7 parameter object + * @return WOLFSSL_STACK_OF(WOLFSSL_X509)* + */ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) { int i; @@ -51037,7 +51054,8 @@ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) return p7->certs; for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) { - WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i], p7->pkcs7.certSz[i]); + WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i], + p7->pkcs7.certSz[i]); if (!ret) ret = wolfSSL_sk_X509_new(); if (x509) { diff --git a/tests/NCONF_test.cnf b/tests/NCONF_test.cnf new file mode 100644 index 000000000..3852ec529 --- /dev/null +++ b/tests/NCONF_test.cnf @@ -0,0 +1,19 @@ +# +# This file is a sample configuration file that +# can be loaded with wolfSSL_NCONF_load +# + +dir = ./test-dir +port = 1234 + +[ section1 ] +file1 = ./test-dir/file1 # test comment +file1_copy = $dir/file1 +s1_dir = ./section1 # more comments + +[section2] + +fileName2 = file2 +file_list = ${section1::file1}:$dir/file2:${section1::s1_dir}:$fileName2 + +port = 4321 diff --git a/tests/TXT_DB.txt b/tests/TXT_DB.txt new file mode 100644 index 000000000..897332994 --- /dev/null +++ b/tests/TXT_DB.txt @@ -0,0 +1,33 @@ +# This file was generated by libest unit tests. + +V 211015165802Z 12F8 unknown /CN=TestCase9 +V 211015165748Z 12F6 unknown /CN=rsa doe +V 211015165732Z 12F4 unknown /CN=rsa doe +V 211015165716Z 12F2 unknown /CN=rsa doe +V 320926161828Z 12F0 unknown /CN=rsa doe +V 211014161800Z 12EE unknown /CN=us4880_test2 +V 320926161718Z 12EC unknown /CN=TEST16-CN +V 320926161653Z 12EA unknown /CN=TC4752-13 +V 320926161607Z 12E8 unknown /CN=TC4752-8 +V 320926161541Z 12E6 unknown /CN=US4752-TC2 +V 320926161515Z 12E4 unknown /CN=TCUS3612-3 +V 211014161456Z 12E2 unknown /CN=TC2174-4 +V 211014161456Z 12E0 unknown /CN=TC2174-4 +V 211014161455Z 12DE unknown /CN=TC2174-4 +V 320926161440Z 12DC unknown /CN=TC1883-7 +V 320926161440Z 12DA unknown /CN=TC1883-6 +V 320926161434Z 12D8 unknown /CN=rsa doe +V 320926161421Z 12D6 unknown /CN=TC1005-93 +V 320926161410Z 12D4 unknown /CN=TC1005-10 +V 320926161359Z 12D2 unknown /CN=TC1005-8 +V 320926161349Z 12D0 unknown /CN=TC1005-6 +V 320926161343Z 12CE unknown /CN=TC1005-3 +V 320926161343Z 12CC unknown /CN=TC1005-1 +V 320926161338Z 12CA unknown /CN=TestCase9 +V 320926161332Z 12C8 unknown /CN=US903-test7 CN +V 320926161321Z 12C6 unknown /CN=dsa doe +V 320926161321Z 12C4 unknown /CN=rsa doe +V 320926161304Z 12C2 unknown /CN=dsa doe +V 320926161304Z 12C0 unknown /CN=rsa doe +V 320926161208Z 12BE unknown /serialNumber=PID:Widget SN:2/CN=req by client in demo step 2 +V 320926161116Z 12BC unknown /serialNumber=PID:Widget SN:2/CN=req by client in demo step 2 diff --git a/tests/api.c b/tests/api.c index 513a1a1ad..0076322b2 100644 --- a/tests/api.c +++ b/tests/api.c @@ -307,6 +307,10 @@ #include #include #include +#ifdef OPENSSL_ALL + #include + #include +#endif #ifndef NO_AES #include #endif @@ -26280,6 +26284,7 @@ static void test_wolfSSL_PEM_PrivateKey(void) const char* fname = "./certs/server-key.pem"; size_t sz; byte* buf; + EVP_PKEY* pkey2; file = XFOPEN(fname, "rb"); AssertTrue((file != XBADFILE)); @@ -26299,6 +26304,11 @@ static void test_wolfSSL_PEM_PrivateKey(void) XFREE(buf, NULL, DYNAMIC_TYPE_FILE); BIO_free(bio); bio = NULL; + AssertNotNull(pkey2 = EVP_PKEY_new()); + pkey2->type = EVP_PKEY_RSA; + /* Test parameter copy */ + AssertIntEQ(EVP_PKEY_copy_parameters(pkey2, pkey), 0); + EVP_PKEY_free(pkey2); EVP_PKEY_free(pkey); pkey = NULL; } @@ -26311,6 +26321,8 @@ static void test_wolfSSL_PEM_PrivateKey(void) const char* fname = "./certs/ecc-key.pem"; size_t sz; byte* buf; + EVP_PKEY* pkey2; + int nid = 0; file = XFOPEN(fname, "rb"); AssertTrue((file != XBADFILE)); @@ -26328,6 +26340,14 @@ static void test_wolfSSL_PEM_PrivateKey(void) XFREE(buf, NULL, DYNAMIC_TYPE_FILE); BIO_free(bio); bio = NULL; + AssertNotNull(pkey2 = EVP_PKEY_new()); + pkey2->type = EVP_PKEY_EC; + /* Test parameter copy */ + AssertIntEQ(EVP_PKEY_copy_parameters(pkey2, pkey), 1); + /* Test default digest */ + AssertIntEQ(EVP_PKEY_get_default_digest_nid(pkey, &nid), 1); + AssertIntEQ(nid, NID_sha256); + EVP_PKEY_free(pkey2); EVP_PKEY_free(pkey); pkey = NULL; } @@ -26790,6 +26810,7 @@ static void test_wolfSSL_tmp_dh(void) int bytes; DSA* dsa; DH* dh; + DH* dh2; BIO* bio; SSL* ssl; SSL_CTX* ctx; @@ -26818,6 +26839,7 @@ static void test_wolfSSL_tmp_dh(void) dh = wolfSSL_DSA_dup_DH(dsa); AssertNotNull(dh); + AssertNotNull(dh2 = wolfSSL_DH_dup(dh)); AssertIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS); #ifndef NO_WOLFSSL_SERVER @@ -26829,6 +26851,7 @@ static void test_wolfSSL_tmp_dh(void) BIO_free(bio); DSA_free(dsa); DH_free(dh); + DH_free(dh2); SSL_free(ssl); SSL_CTX_free(ctx); @@ -27635,6 +27658,61 @@ static void test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void) #endif } +static void test_wolfSSL_PKCS7_certs(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + STACK_OF(X509)* sk = NULL; + STACK_OF(X509_INFO)* info_sk = NULL; + PKCS7 *p7 = NULL; + BIO* bio; + const byte* p = NULL; + int buflen = 0; + int i; + + printf(testingFmt, "wolfSSL_PKCS7_certs()"); + + /* Test twice. Once with d2i and once without to test + * that everything is free'd correctly. */ + for (i = 0; i < 2; i++) { + AssertNotNull(p7 = PKCS7_new()); + p7->version = 1; + p7->hashOID = SHAh; + AssertNotNull(bio = BIO_new(BIO_s_file())); + AssertIntGT(BIO_read_filename(bio, svrCertFile), 0); + AssertNotNull(info_sk = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL)); + AssertIntEQ(sk_X509_INFO_num(info_sk), 2); + AssertNotNull(sk = sk_X509_new_null()); + while (sk_X509_INFO_num(info_sk)) { + X509_INFO* info; + AssertNotNull(info = sk_X509_INFO_shift(info_sk)); + AssertIntEQ(sk_X509_push(sk, info->x509), 1); + info->x509 = NULL; + X509_INFO_free(info); + } + sk_X509_INFO_free(info_sk); + BIO_free(bio); + bio = BIO_new(BIO_s_mem()); + AssertIntEQ(wolfSSL_PKCS7_encode_certs(p7, sk, bio), 1); + AssertIntGT((buflen = BIO_get_mem_data(bio, &p)), 0); + + if (i == 0) { + PKCS7_free(p7); + /* Reset certs to force p7 to regenerate them */ + ((WOLFSSL_PKCS7*)p7)->certs = NULL; + AssertNotNull(d2i_PKCS7(&p7, &p, buflen)); + /* p7 free's the certs */ + AssertNotNull(wolfSSL_PKCS7_to_stack(p7)); + } + + BIO_free(bio); + PKCS7_free(p7); + } + + printf(resultFmt, passed); +#endif /* defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ +} static void test_wolfSSL_X509_STORE_CTX(void) { @@ -28033,6 +28111,7 @@ static void test_wolfSSL_CTX_set_srp_username(void) #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \ && !defined(NO_SHA256) && !defined(WC_NO_RNG) WOLFSSL_CTX* ctx; + WOLFSSL* ssl; const char *username = "TESTUSER"; const char *password = "TESTPASSWORD"; int r; @@ -28051,6 +28130,12 @@ static void test_wolfSSL_CTX_set_srp_username(void) AssertIntEQ(r,SSL_SUCCESS); r = wolfSSL_CTX_set_srp_username(ctx, (char *)username); AssertIntEQ(r,SSL_SUCCESS); + + AssertNotNull(ssl = SSL_new(ctx)); + AssertNotNull(SSL_get_srp_username(ssl)); + AssertStrEQ(SSL_get_srp_username(ssl), username); + + wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); printf(resultFmt, passed); @@ -29285,9 +29370,7 @@ static void test_wolfSSL_X509_cmp_time(void) XMEMSET(&asn_time, 0, sizeof(WOLFSSL_ASN1_TIME)); AssertIntEQ(0, wolfSSL_X509_cmp_time(&asn_time, &t)); - asn_time.type = ASN_UTC_TIME; - asn_time.length = ASN_UTC_TIME_SIZE; - XMEMCPY(&asn_time.data, "000222211515Z", 13); + AssertIntEQ(ASN1_TIME_set_string(&asn_time, "000222211515Z"), 1); AssertIntEQ(-1, wolfSSL_X509_cmp_time(&asn_time, NULL)); printf(resultFmt, passed); @@ -29443,6 +29526,7 @@ static void test_wolfSSL_X509_sign(void) DecodedCert dCert; EVP_PKEY *pub; EVP_PKEY *priv; + EVP_MD_CTX *mctx; #if defined(USE_CERT_BUFFERS_1024) const unsigned char* rsaPriv = client_key_der_1024; const unsigned char* rsaPub = client_keypub_der_1024; @@ -29510,6 +29594,11 @@ static void test_wolfSSL_X509_sign(void) /* test valid sign case */ ret = X509_sign(x509, priv, EVP_sha256()); + /* test valid X509_sign_ctx case */ + AssertNotNull(mctx = EVP_MD_CTX_new()); + AssertIntEQ(EVP_DigestSignInit(mctx, NULL, EVP_sha256(), NULL, priv), 1); + AssertIntGT(X509_sign_ctx(x509, mctx), 0); + #if defined(OPENSSL_ALL) && defined(WOLFSSL_ALT_NAMES) AssertIntEQ(X509_get_ext_count(x509), 1); #endif @@ -29577,6 +29666,12 @@ static void test_wolfSSL_X509_sign(void) AssertIntEQ(X509_sign(x509, NULL, EVP_sha256()), 0); AssertIntEQ(X509_sign(x509, priv, NULL), 0); + AssertIntEQ(X509_sign_ctx(NULL, mctx), 0); + EVP_MD_CTX_free(mctx); + AssertNotNull(mctx = EVP_MD_CTX_new()); + AssertIntEQ(X509_sign_ctx(x509, mctx), 0); + AssertIntEQ(X509_sign_ctx(x509, NULL), 0); + /* test invalid version number */ #if defined(OPENSSL_ALL) AssertIntNE(X509_set_version(x509, 6L), 0); @@ -29586,7 +29681,8 @@ static void test_wolfSSL_X509_sign(void) AssertIntEQ(X509_get_ext_count(x509), SSL_FAILURE); #endif - + EVP_MD_CTX_free(mctx); + X509_NAME_free(name); EVP_PKEY_free(priv); EVP_PKEY_free(pub); X509_free(x509); @@ -33207,6 +33303,36 @@ static void test_wolfSSL_ASN1_STRING_to_UTF8(void) wolfSSL_X509_free(x509); XFREE(actual_output, NULL, DYNAMIC_TYPE_TMP_BUFFER); } + +static void test_wolfSSL_ASN1_UNIVERSALSTRING_to_string(void) +{ + ASN1_STRING* asn1str_test; + ASN1_STRING* asn1str_answer; + /* Each character is encoded using 4 bytes */ + char input[] = { + 0, 0, 0, 'T', + 0, 0, 0, 'e', + 0, 0, 0, 's', + 0, 0, 0, 't', + }; + char output[] = "Test"; + + printf(testingFmt, "test_wolfSSL_ASN1_UNIVERSALSTRING_to_string()"); + + AssertNotNull(asn1str_test = ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)); + AssertIntEQ(ASN1_STRING_set(asn1str_test, input, sizeof(input)), 1); + AssertIntEQ(ASN1_UNIVERSALSTRING_to_string(asn1str_test), 1); + + AssertNotNull(asn1str_answer = ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)); + AssertIntEQ(ASN1_STRING_set(asn1str_answer, output, sizeof(output)-1), 1); + + AssertIntEQ(ASN1_STRING_cmp(asn1str_test, asn1str_answer), 0); + + ASN1_STRING_free(asn1str_test); + ASN1_STRING_free(asn1str_answer); + + printf(resultFmt, "passed"); +} #endif /* !defined(NO_ASN) */ static void test_wolfSSL_sk_CIPHER_description(void) @@ -34811,6 +34937,92 @@ static void test_wolfSSL_OBJ_sn(void) printf(resultFmt, passed); } + + +static unsigned long TXT_DB_hash(const WOLFSSL_STRING *s) +{ + return lh_strhash(s[3]); +} + +static int TXT_DB_cmp(const WOLFSSL_STRING *a, const WOLFSSL_STRING *b) +{ + return XSTRCMP(a[3], b[3]); +} + +static void test_wolfSSL_TXT_DB(void) +{ +#if !defined(NO_FILESYSTEM) + BIO *bio; + TXT_DB *db = NULL; + const int columns = 6; + const char *fields[6] = { + "V", + "320926161116Z", + "", + "12BD", + "unknown", + "/CN=rsa doe", + }; + + printf(testingFmt, "wolfSSL_TXT_DB"); + + /* Test read */ + AssertNotNull(bio = BIO_new(BIO_s_file())); + AssertIntGT(BIO_read_filename(bio, "./tests/TXT_DB.txt"), 0); + AssertNotNull(db = TXT_DB_read(bio, columns)); + AssertIntEQ(TXT_DB_insert(db, (WOLFSSL_STRING*)fields), 1); + BIO_free(bio); + + /* Test write */ + AssertNotNull(bio = BIO_new(BIO_s_mem())); + AssertIntEQ(TXT_DB_write(bio, db), 1484); + BIO_free(bio); + + /* Test index */ + AssertIntEQ(TXT_DB_create_index(db, 3, NULL, (wolf_sk_hash_cb)TXT_DB_hash, + (wolf_sk_compare_cb)TXT_DB_cmp), 1); + AssertNotNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields)); + fields[3] = "12DA"; + AssertNotNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields)); + fields[3] = "FFFF"; + AssertNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields)); + fields[3] = ""; + AssertNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields)); + + TXT_DB_free(db); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_NCONF(void) +{ +#if !defined(NO_FILESYSTEM) + const char* confFile = "./tests/NCONF_test.cnf"; + CONF* conf = NULL; + long eline = 0; + long num = 0; + + printf(testingFmt, "wolfSSL_NCONF"); + + AssertNotNull(conf = NCONF_new(NULL)); + + AssertIntEQ(NCONF_load(conf, confFile, &eline), 1); + AssertIntEQ(NCONF_get_number(conf, NULL, "port", &num), 1); + AssertIntEQ(num, 1234); + AssertIntEQ(NCONF_get_number(conf, "section2", "port", &num), 1); + AssertIntEQ(num, 4321); + AssertStrEQ(NCONF_get_string(conf, NULL, "dir"), "./test-dir"); + AssertStrEQ(NCONF_get_string(conf, "section1", "file1_copy"), + "./test-dir/file1"); + AssertStrEQ(NCONF_get_string(conf, "section2", "file_list"), + "./test-dir/file1:./test-dir/file2:./section1:file2"); + + NCONF_free(conf); + + printf(resultFmt, passed); +#endif +} #endif /* OPENSSL_ALL */ @@ -36535,6 +36747,11 @@ static void test_wolfssl_PKCS7(void) word32 len = sizeof(data); const byte* p = data; byte content[] = "Test data to encode."; +#if !defined(NO_RSA) & defined(USE_CERT_BUFFERS_2048) + BIO* bio; + byte key[sizeof_client_key_der_2048]; + word32 keySz = (word32)sizeof(key); +#endif AssertIntGT((len = CreatePKCS7SignedData(data, len, content, (word32)sizeof(content), @@ -36560,6 +36777,18 @@ static void test_wolfssl_PKCS7(void) AssertIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL, PKCS7_NOVERIFY), WOLFSSL_SUCCESS); +#if !defined(NO_RSA) & defined(USE_CERT_BUFFERS_2048) + /* test i2d */ + XMEMCPY(key, client_key_der_2048, keySz); + pkcs7->privateKey = key; + pkcs7->privateKeySz = (word32)sizeof(key); + pkcs7->encryptOID = RSAk; + pkcs7->hashOID = SHAh; + AssertNotNull(bio = BIO_new(BIO_s_mem())); + AssertIntEQ(i2d_PKCS7_bio(bio, pkcs7), 1); + BIO_free(bio); +#endif + PKCS7_free(NULL); PKCS7_free(pkcs7); @@ -38748,6 +38977,8 @@ static void test_wolfSSL_X509_print() !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(XSNPRINTF) X509 *x509; BIO *bio; + const X509_ALGOR *cert_sig_alg; + int stdout_fd = fileno(stdout); printf(testingFmt, "wolfSSL_X509_print"); x509 = X509_load_certificate_file(svrCertFile, WOLFSSL_FILETYPE_PEM); @@ -38764,13 +38995,19 @@ static void test_wolfSSL_X509_print() #endif BIO_free(bio); + AssertNotNull(bio = BIO_new_fd(stdout_fd, BIO_NOCLOSE)); + + /* Print signature */ + AssertNotNull(cert_sig_alg = X509_get0_tbs_sigalg(x509)); + AssertIntEQ(X509_signature_print(bio, cert_sig_alg, NULL), SSL_SUCCESS); + /* print to stdout */ - AssertNotNull(bio = BIO_new(BIO_s_file())); - wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); AssertIntEQ(X509_print(bio, x509), SSL_SUCCESS); - BIO_free(bio); + /* print again */ + AssertIntEQ(X509_print_fp(stdout, x509), SSL_SUCCESS); X509_free(x509); + BIO_free(bio); printf(resultFmt, passed); #endif } @@ -38782,11 +39019,11 @@ static void test_wolfSSL_RSA_print() !defined(HAVE_FAST_RSA) && !defined(NO_BIO) BIO *bio; WOLFSSL_RSA* rsa = NULL; + int stdout_fd = fileno(stdout); printf(testingFmt, "wolfSSL_RSA_print"); AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); - AssertNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())); - wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); + AssertNotNull(bio = wolfSSL_BIO_new_fd(stdout_fd, BIO_NOCLOSE)); AssertIntEQ(RSA_print(bio, rsa, 0), SSL_SUCCESS); BIO_free(bio); @@ -38877,6 +39114,7 @@ static void test_wolfSSL_ASN1_get_object(void) int len = sizeof_cliecc_cert_der_256; long asnLen = 0; int tag = 0, class = 0; + ASN1_OBJECT *a; printf(testingFmt, "wolfSSL_ASN1_get_object()"); @@ -38887,20 +39125,41 @@ static void test_wolfSSL_ASN1_get_object(void) AssertIntEQ(tag, 0x10); AssertIntEQ(class, 0); - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 772); AssertIntEQ(tag, 0x10); AssertIntEQ(class, 0); - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 3); AssertIntEQ(tag, 0); AssertIntEQ(class, 0x80); - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, asnLen) & 0x80, 0); + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 1); AssertIntEQ(tag, 0x2); AssertIntEQ(class, 0); + derBuf += asnLen; + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 20); + AssertIntEQ(tag, 0x2); + AssertIntEQ(class, 0); + derBuf += asnLen; + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 10); + AssertIntEQ(tag, 0x10); + AssertIntEQ(class, 0); + + /* Read an ASN OBJECT */ + AssertNotNull(d2i_ASN1_OBJECT(&a, &derBuf, len)); + ASN1_OBJECT_free(a); printf(resultFmt, passed); #endif /* OPENSSL_EXTRA */ @@ -39625,6 +39884,7 @@ void ApiTest(void) #endif test_wolfSSL_set_options(); test_wolfSSL_sk_SSL_CIPHER(); + test_wolfSSL_PKCS7_certs(); test_wolfSSL_X509_STORE_CTX(); test_wolfSSL_X509_STORE_CTX_get0_current_issuer(); test_wolfSSL_msgCb(); @@ -39748,6 +40008,7 @@ void ApiTest(void) test_wolfSSL_d2i_DHparams(); test_wolfSSL_i2d_DHparams(); test_wolfSSL_ASN1_STRING_to_UTF8(); + test_wolfSSL_ASN1_UNIVERSALSTRING_to_string(); test_wolfSSL_EC_KEY_dup(); test_wolfSSL_EVP_PKEY_set1_get1_DSA(); test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY(); @@ -39786,6 +40047,8 @@ void ApiTest(void) test_IncCtr(); test_wolfSSL_OBJ_ln(); test_wolfSSL_OBJ_sn(); + test_wolfSSL_TXT_DB(); + test_wolfSSL_NCONF(); #endif /* OPENSSL_ALL */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 1db84de6d..8f0c4e91c 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -652,8 +652,8 @@ decouple library dependencies with standard string, memory and so on. #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \ defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA) #define XTOUPPER(c) toupper((c)) - #define XISALPHA(c) isalpha((c)) #endif + #define XISALNUM(c) isalnum((c)) /* needed by wolfSSL_check_domain_name() */ #define XTOLOWER(c) tolower((c)) #endif diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index b00cb9ff0..52bdbb56c 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -615,6 +615,9 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #include #include #include + #define XWRITE write + #define XREAD read + #define XCLOSE close #endif #endif From b528a1a344d11492feb3b41b044a0ea3c5aabd83 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 23 Oct 2020 19:25:45 +0200 Subject: [PATCH 41/53] Plug memory leaks --- src/internal.c | 9 +- src/ssl.c | 229 ++++++++++++++++------------------------- tests/api.c | 24 +++-- wolfcrypt/src/evp.c | 1 + wolfcrypt/src/pkcs7.c | 14 ++- wolfcrypt/src/srp.c | 4 +- wolfssl/openssl/conf.h | 2 - wolfssl/ssl.h | 1 + 8 files changed, 127 insertions(+), 157 deletions(-) diff --git a/src/internal.c b/src/internal.c index b72b5ccba..c587ea27b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1854,10 +1854,6 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) wolfSSL_CertManagerFree(ctx->cm); ctx->cm = NULL; #ifdef OPENSSL_EXTRA - /* ctx->cm was free'd so cm of x509 store should now be NULL */ - if (ctx->x509_store_pt != NULL) { - ctx->x509_store_pt->cm = NULL; - } wolfSSL_X509_STORE_free(ctx->x509_store_pt); while (ctx->ca_names != NULL) { WOLFSSL_STACK *next = ctx->ca_names->next; @@ -3461,6 +3457,11 @@ void FreeX509(WOLFSSL_X509* x509) x509->key.pkey = NULL; } #endif /* OPENSSL_ALL */ + #ifdef WOLFSSL_CERT_REQ + if (x509->challengePwAttr) { + wolfSSL_X509_ATTRIBUTE_free(x509->challengePwAttr); + } + #endif /* WOLFSSL_CERT_REQ */ if (x509->altNames) { FreeAltNames(x509->altNames, x509->heap); x509->altNames = NULL; diff --git a/src/ssl.c b/src/ssl.c index 7728bb19b..77141f26e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15491,10 +15491,6 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ctx->x509_store.cm = str->cm; /* free existing store if it exists */ - if (ctx->x509_store_pt != NULL) { - /* cert manager was free'd a little earlier in this function */ - ctx->x509_store_pt->cm = NULL; - } wolfSSL_X509_STORE_free(ctx->x509_store_pt); ctx->x509_store.cache = str->cache; ctx->x509_store_pt = str; /* take ownership of store and free it @@ -19509,55 +19505,6 @@ WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void) return ret; } -WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, - char* name, char* value) -{ - WOLFSSL_CONF_VALUE* ret; - int len; - - WOLFSSL_ENTER("wolfSSL_CONF_VALUE_new_values"); - - if (!(ret = wolfSSL_CONF_VALUE_new())) { - WOLFSSL_MSG("wolfSSL_CONF_VALUE_new error"); - return NULL; - } - - if (section) { - len = XSTRLEN(section); - ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); - if (!ret->section) { - WOLFSSL_MSG("malloc error"); - wolfSSL_X509V3_conf_free(ret); - return NULL; - } - XMEMCPY(ret->section, section, len+1); - } - - if (name) { - len = XSTRLEN(name); - ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); - if (!ret->name) { - WOLFSSL_MSG("malloc error"); - wolfSSL_X509V3_conf_free(ret); - return NULL; - } - XMEMCPY(ret->name, name, len+1); - } - - if (value) { - len = XSTRLEN(value); - ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); - if (!ret->value) { - WOLFSSL_MSG("malloc error"); - wolfSSL_X509V3_conf_free(ret); - return NULL; - } - XMEMCPY(ret->value, value, len+1); - } - - return ret; -} - int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf, WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value) { @@ -19773,6 +19720,55 @@ WOLFSSL_STACK *wolfSSL_NCONF_get_section( return NULL; } +static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, + char* name, char* value) +{ + WOLFSSL_CONF_VALUE* ret; + int len; + + WOLFSSL_ENTER("wolfSSL_CONF_VALUE_new_values"); + + if (!(ret = wolfSSL_CONF_VALUE_new())) { + WOLFSSL_MSG("wolfSSL_CONF_VALUE_new error"); + return NULL; + } + + if (section) { + len = XSTRLEN(section); + ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret->section) { + WOLFSSL_MSG("malloc error"); + wolfSSL_X509V3_conf_free(ret); + return NULL; + } + XMEMCPY(ret->section, section, len+1); + } + + if (name) { + len = XSTRLEN(name); + ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret->name) { + WOLFSSL_MSG("malloc error"); + wolfSSL_X509V3_conf_free(ret); + return NULL; + } + XMEMCPY(ret->name, name, len+1); + } + + if (value) { + len = XSTRLEN(value); + ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret->value) { + WOLFSSL_MSG("malloc error"); + wolfSSL_X509V3_conf_free(ret); + return NULL; + } + XMEMCPY(ret->value, value, len+1); + } + + return ret; +} + static char* expandValue(WOLFSSL_CONF *conf, const char* section, char *str) { @@ -20001,7 +19997,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) goto cleanup; } - if (!(newVal = wolfSSL_CONF_VALUE_new_values(section->section, + if (!(newVal = wolfSSL_CONF_VALUE_new_values(NULL, name, exValue))) { WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error"); if (exValue != value) @@ -20089,7 +20085,6 @@ WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc) */ void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk) { - WOLFSSL_STACK* node; WOLFSSL_STACK* tmp; WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free"); @@ -20097,16 +20092,12 @@ void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk) return; /* parse through stack freeing each node */ - node = sk->next; - while (node) { - tmp = node; - node = node->next; - wolfSSL_X509V3_conf_free(tmp->data.conf); - XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + while (sk) { + tmp = sk->next; + wolfSSL_X509V3_conf_free(sk->data.conf); + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + sk = tmp; } - - /* free head of stack */ - XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); } int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk) @@ -24355,6 +24346,7 @@ static WOLFSSL_X509* wolfSSL_d2i_X509_X509_REQ_bio(WOLFSSL_BIO* bio, *x509 = localX509; } + XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); return localX509; } #endif /* !NO_BIO */ @@ -29354,6 +29346,9 @@ void wolfSSL_sk_free(WOLFSSL_STACK* sk) case STACK_TYPE_OBJ: wolfSSL_sk_ASN1_OBJECT_free(sk); break; + case STACK_TYPE_STRING: + wolfSSL_sk_WOLFSSL_STRING_free(sk); + break; #ifdef OPENSSL_ALL case STACK_TYPE_X509_INFO: wolfSSL_sk_X509_INFO_free(sk); @@ -40155,52 +40150,6 @@ cleanup: return wolfSSL_X509_sign(x509, ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(ctx)); } - - /* Converts the x509 name structure into DER format. - * - * out pointer to either a pre setup buffer or a pointer to null for - * creating a dynamic buffer. In the case that a pre-existing buffer is - * used out will be incremented the size of the DER buffer on success. - * - * returns the size of the buffer on success, or negative value with failure - */ - int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out) - { - CertName cName; - unsigned char buf[256]; /* ASN_MAX_NAME */ - int sz; - WOLFSSL_ENTER("wolfSSL_i2d_X509_NAME"); - - if (out == NULL || name == NULL) { - return BAD_FUNC_ARG; - } - XMEMSET(&cName, 0, sizeof(CertName)); - - if (CopyX509NameToCertName(name, &cName) != SSL_SUCCESS) { - WOLFSSL_MSG("Error converting x509 name to internal CertName"); - return SSL_FATAL_ERROR; - } - - sz = SetName(buf, sizeof(buf), &cName); - if (sz < 0) { - return sz; - } - - /* using buffer passed in */ - if (*out != NULL) { - XMEMCPY(*out, buf, sz); - *out += sz; - } - else { - *out = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL); - if (*out == NULL) { - return MEMORY_E; - } - XMEMCPY(*out, buf, sz); - } - - return sz; - } #endif /* WOLFSSL_CERT_GEN */ #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) @@ -41587,8 +41536,6 @@ err: name->entry[loc].set = 0; return ret; } - #endif /* !NO_CERTS */ - /* NID variables are dependent on compatibility header files currently * @@ -42863,7 +42810,6 @@ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x, #endif /* !NO_BIO */ #endif /* NO_DSA */ #endif /* OPENSSL_EXTRA */ -#endif /* WOLFCRYPT_ONLY */ #if defined(OPENSSL_EXTRA) @@ -47389,32 +47335,6 @@ int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject) return X509_V_OK; } -char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, - int idx) -{ - for (; idx > 0 && strings != NULL; idx--) - strings = strings->next; - if (strings == NULL) - return NULL; - return strings->data.string; -} - -#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ - -#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) - -WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x) -{ - WOLFSSL_ENTER("wolfSSL_X509_dup"); - - if (x == NULL) { - WOLFSSL_MSG("Error: NULL certificate passed in"); - return NULL; - } - - return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length); -} - WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) { WOLF_STACK_OF(WOLFSSL_STRING)* ret = wolfSSL_sk_new_node(NULL); @@ -47426,6 +47346,23 @@ WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) return ret; } +void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* sk) +{ + WOLFSSL_STACK* tmp; + WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free"); + + if (sk == NULL) + return; + + /* parse through stack freeing each node */ + while (sk) { + tmp = sk->next; + XFREE(sk->data.string, NULL, DYNAMIC_TYPE_OPENSSL); + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + sk = tmp; + } +} + WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) { @@ -47444,6 +47381,20 @@ int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) } #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x) +{ + WOLFSSL_ENTER("wolfSSL_X509_dup"); + + if (x == NULL) { + WOLFSSL_MSG("Error: NULL certificate passed in"); + return NULL; + } + + return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length); +} +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) #ifdef HAVE_ALPN diff --git a/tests/api.c b/tests/api.c index 0076322b2..5608029d8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25933,7 +25933,7 @@ static void test_wolfSSL_X509_check_private_key(void) #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) && \ defined(USE_CERT_BUFFERS_2048) X509* x509; - EVP_PKEY* pkey; + EVP_PKEY* pkey = NULL; const byte* key; printf(testingFmt, "wolfSSL_X509_check_private_key()"); @@ -25946,6 +25946,7 @@ static void test_wolfSSL_X509_check_private_key(void) &key, (long)sizeof_client_key_der_2048)); AssertIntEQ(X509_check_private_key(x509, pkey), 1); EVP_PKEY_free(pkey); + pkey = NULL; /* Check with wrong key */ key = server_key_der_2048; @@ -27698,10 +27699,10 @@ static void test_wolfSSL_PKCS7_certs(void) if (i == 0) { PKCS7_free(p7); - /* Reset certs to force p7 to regenerate them */ - ((WOLFSSL_PKCS7*)p7)->certs = NULL; AssertNotNull(d2i_PKCS7(&p7, &p, buflen)); - /* p7 free's the certs */ + /* Reset certs to force wolfSSL_PKCS7_to_stack to regenerate them */ + ((WOLFSSL_PKCS7*)p7)->certs = NULL; + /* PKCS7_free free's the certs */ AssertNotNull(wolfSSL_PKCS7_to_stack(p7)); } @@ -27746,6 +27747,7 @@ static void test_wolfSSL_X509_STORE_CTX(void) X509_STORE_CTX_set_error(NULL, -5); X509_STORE_CTX_free(ctx); + sk_X509_free(sk); X509_STORE_free(str); X509_free(x509); @@ -27774,7 +27776,8 @@ static void test_wolfSSL_X509_STORE_CTX(void) X509_STORE_free(str); /* CTX certs not freed yet */ X509_free(x5092); - /* sk2 freed as part of X509_STORE_CTX_free(), sk3 is dup so free here */ + sk_X509_free(sk); + /* sk3 is dup so free here */ sk_X509_free(sk3); #endif @@ -29682,7 +29685,6 @@ static void test_wolfSSL_X509_sign(void) #endif EVP_MD_CTX_free(mctx); - X509_NAME_free(name); EVP_PKEY_free(priv); EVP_PKEY_free(pub); X509_free(x509); @@ -29839,6 +29841,7 @@ static void test_wolfSSL_X509_PUBKEY(void) X509_PUBKEY_free(pubKey2); X509_free(x509); + EVP_PKEY_free(evpKey); printf(resultFmt, passed); #endif @@ -34963,6 +34966,7 @@ static void test_wolfSSL_TXT_DB(void) "unknown", "/CN=rsa doe", }; + char** fields_copy; printf(testingFmt, "wolfSSL_TXT_DB"); @@ -34970,7 +34974,10 @@ static void test_wolfSSL_TXT_DB(void) AssertNotNull(bio = BIO_new(BIO_s_file())); AssertIntGT(BIO_read_filename(bio, "./tests/TXT_DB.txt"), 0); AssertNotNull(db = TXT_DB_read(bio, columns)); - AssertIntEQ(TXT_DB_insert(db, (WOLFSSL_STRING*)fields), 1); + AssertNotNull(fields_copy = (char**)XMALLOC(sizeof(fields), NULL, + DYNAMIC_TYPE_OPENSSL)); + XMEMCPY(fields_copy, fields, sizeof(fields)); + AssertIntEQ(TXT_DB_insert(db, fields_copy), 1); BIO_free(bio); /* Test write */ @@ -38178,6 +38185,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) X509_free(req); BIO_free(bio); + EVP_PKEY_free(pub_key); } { AssertNotNull(bio = BIO_new_file(csrPopFile, "rb")); @@ -38200,6 +38208,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) X509_free(req); BIO_free(bio); + EVP_PKEY_free(pub_key); } { AssertNotNull(bio = BIO_new_file(csrDsaFile, "rb")); @@ -38217,6 +38226,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) X509_free(req); BIO_free(bio); + EVP_PKEY_free(pub_key); } } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 30cbf187d..473b692e6 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1904,6 +1904,7 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, WOLFSSL_MSG("wolfSSL_EC_KEY_new error"); return WOLFSSL_FAILURE; } + to->ownEcc = 1; to->ecc->group->curve_idx = from->ecc->group->curve_idx; to->ecc->group->curve_nid = from->ecc->group->curve_nid; to->ecc->group->curve_oid = from->ecc->group->curve_oid; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index b11660029..66d92001d 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2442,7 +2442,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs, flatSignedAttribsSz, esd); if (ret < 0) { - if (pkcs7->signedAttribsSz != 0) + if (flatSignedAttribs) XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -2507,7 +2507,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* if using header/footer, we are not returning the content */ if (output2 && output2Sz) { if (total2Sz > *output2Sz) { - if (pkcs7->signedAttribsSz != 0) + if (flatSignedAttribs) XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -2530,7 +2530,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } if (totalSz > *outputSz) { - if (pkcs7->signedAttribsSz != 0) + if (flatSignedAttribs) XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -2543,7 +2543,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } if (output == NULL) { - if (pkcs7->signedAttribsSz != 0) + if (flatSignedAttribs) XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -4915,9 +4915,15 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (ret == 0) { + byte isDynamic = pkcs7->isDynamic; #ifndef NO_PKCS7_STREAM PKCS7State* stream = pkcs7->stream; + pkcs7->stream = NULL; #endif + /* Free pkcs7 resources but not the structure itself */ + pkcs7->isDynamic = 0; + wc_PKCS7_Free(pkcs7); + pkcs7->isDynamic = isDynamic; /* This will reset PKCS7 structure and then set the * certificate */ ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz); diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index 24d7f6635..af047ac3c 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -325,12 +325,14 @@ int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size) if (!srp || !username) return BAD_FUNC_ARG; - srp->user = (byte*)XMALLOC(size, srp->heap, DYNAMIC_TYPE_SRP); + /* +1 for NULL char */ + srp->user = (byte*)XMALLOC(size + 1, srp->heap, DYNAMIC_TYPE_SRP); if (srp->user == NULL) return MEMORY_E; srp->userSz = size; XMEMCPY(srp->user, username, srp->userSz); + srp->user[size] = '\0'; return 0; } diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index 9dbe20ae0..f7369ec67 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -50,8 +50,6 @@ typedef WOLFSSL_CONF_VALUE CONF_VALUE; typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void); -WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, - char* name, char* value); WOLFSSL_API int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf, WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value); WOLFSSL_API void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 79e230a53..40e4dda5a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3939,6 +3939,7 @@ WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void); +WOLFSSL_API void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* sk); WOLFSSL_API WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value( WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); WOLFSSL_API int wolfSSL_sk_WOLFSSL_STRING_num( From 25f5427bddb73cbe2f9e281e0dcca2cde861e3bf Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 26 Oct 2020 15:05:59 +0100 Subject: [PATCH 42/53] Rebase and test fixes --- src/internal.c | 4 +- src/ssl.c | 281 +++++++++++++++++++++++----------------- tests/api.c | 28 +++- wolfcrypt/src/asn.c | 158 +++++++++++----------- wolfcrypt/src/dh.c | 2 - wolfssl/internal.h | 2 + wolfssl/openssl/bio.h | 7 + wolfssl/wolfcrypt/asn.h | 4 +- wolfssl/wolfcrypt/dh.h | 5 - 9 files changed, 287 insertions(+), 204 deletions(-) diff --git a/src/internal.c b/src/internal.c index c587ea27b..271352518 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3457,7 +3457,7 @@ void FreeX509(WOLFSSL_X509* x509) x509->key.pkey = NULL; } #endif /* OPENSSL_ALL */ - #ifdef WOLFSSL_CERT_REQ + #if defined(WOLFSSL_CERT_REQ) && defined(OPENSSL_ALL) if (x509->challengePwAttr) { wolfSSL_X509_ATTRIBUTE_free(x509->challengePwAttr); } @@ -9609,6 +9609,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) if (dCert->cPwdLen < CTC_NAME_SIZE) { XMEMCPY(x509->challengePw, dCert->cPwd, dCert->cPwdLen); x509->challengePw[dCert->cPwdLen] = '\0'; +#ifdef OPENSSL_ALL if (x509->challengePwAttr) { wolfSSL_X509_ATTRIBUTE_free(x509->challengePwAttr); } @@ -9626,6 +9627,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) else { ret = MEMORY_E; } +#endif } else { WOLFSSL_MSG("Challenge password too long"); diff --git a/src/ssl.c b/src/ssl.c index 77141f26e..ad7f8af0b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1686,7 +1686,7 @@ int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz) return WOLFSSL_SUCCESS; } -#endif /* !NO_RSA */ +#endif /* HAVE_ECC */ #ifndef NO_RSA int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz) @@ -8803,6 +8803,102 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) return ext; } +/** + * @param str String to copy + * @param buf Output buffer. If this contains a pointer then it is free'd + * with the DYNAMIC_TYPE_X509_EXT hint. + * @param len Output length + * @return WOLFSSL_SUCCESS on sucess and WOLFSSL_FAILURE on error + */ +static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf, + word32* len, void* heap) { + if (!str || !buf || !len) { + return WOLFSSL_FAILURE; + } + if (str->data && str->length > 0) { + if (*buf) + XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT); + *len = 0; + *buf = (byte*)XMALLOC(str->length, heap, + DYNAMIC_TYPE_X509_EXT); + if (!*buf) { + WOLFSSL_MSG("malloc error"); + return WOLFSSL_FAILURE; + } + *len = str->length; + XMEMCPY(*buf, str->data, str->length); + } + return WOLFSSL_SUCCESS; +} + +int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc) +{ + WOLFSSL_ENTER("wolfSSL_X509_add_ext"); + + if (!x509 || !ext || !ext->obj || loc >= 0) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + switch (ext->obj->type) { + case NID_authority_key_identifier: + if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId, + &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("asn1_string_copy_to_buffer error"); + return WOLFSSL_FAILURE; + } + x509->authKeyIdCrit = ext->crit; + break; + case NID_subject_key_identifier: + if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId, + &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("asn1_string_copy_to_buffer error"); + return WOLFSSL_FAILURE; + } + x509->subjKeyIdCrit = ext->crit; + break; + case NID_subject_alt_name: + { + WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk; + while (gns) { + WOLFSSL_GENERAL_NAME* gn = gns->data.gn; + if (!gn || !gn->d.ia5 || + wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data, + gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Subject alternative name missing extension"); + return WOLFSSL_FAILURE; + } + gns = gns->next; + } + x509->subjAltNameSet = 1; + x509->subjAltNameCrit = ext->crit; + break; + } + case NID_key_usage: + if (ext && ext->value.data && + ext->value.length == sizeof(word16)) { + x509->keyUsage = *(word16*)ext->value.data; + x509->keyUsageCrit = ext->crit; + x509->keyUsageSet = 1; + } + break; + case NID_basic_constraints: + if (ext->obj) { + x509->isCa = ext->obj->ca; + x509->basicConstCrit = ext->crit; + if (ext->obj->pathlen) + x509->pathLength = ext->obj->pathlen->length; + x509->basicConstSet = 1; + } + break; + default: + WOLFSSL_MSG("Unsupported extension to add"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + #ifndef NO_BIO /* Return 0 on success and 1 on failure. Copies ext data to bio, using indent * to pad the output. flag is ignored. */ @@ -9911,102 +10007,6 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type) return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type); } -/** - * @param str String to copy - * @param buf Output buffer. If this contains a pointer then it is free'd - * with the DYNAMIC_TYPE_X509_EXT hint. - * @param len Output length - * @return WOLFSSL_SUCCESS on sucess and WOLFSSL_FAILURE on error - */ -static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf, - word32* len, void* heap) { - if (!str || !buf || !len) { - return WOLFSSL_FAILURE; - } - if (str->data && str->length > 0) { - if (*buf) - XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT); - *len = 0; - *buf = (byte*)XMALLOC(str->length, heap, - DYNAMIC_TYPE_X509_EXT); - if (!*buf) { - WOLFSSL_MSG("malloc error"); - return WOLFSSL_FAILURE; - } - *len = str->length; - XMEMCPY(*buf, str->data, str->length); - } - return WOLFSSL_SUCCESS; -} - -int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc) -{ - WOLFSSL_ENTER("wolfSSL_X509_add_ext"); - - if (!x509 || !ext || !ext->obj || loc >= 0) { - WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; - } - - switch (ext->obj->type) { - case NID_authority_key_identifier: - if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId, - &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("asn1_string_copy_to_buffer error"); - return WOLFSSL_FAILURE; - } - x509->authKeyIdCrit = ext->crit; - break; - case NID_subject_key_identifier: - if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId, - &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("asn1_string_copy_to_buffer error"); - return WOLFSSL_FAILURE; - } - x509->subjKeyIdCrit = ext->crit; - break; - case NID_subject_alt_name: - { - WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk; - while (gns) { - WOLFSSL_GENERAL_NAME* gn = gns->data.gn; - if (!gn || !gn->d.ia5 || - wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data, - gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Subject alternative name missing extension"); - return WOLFSSL_FAILURE; - } - gns = gns->next; - } - x509->subjAltNameSet = 1; - x509->subjAltNameCrit = ext->crit; - break; - } - case NID_key_usage: - if (ext && ext->value.data && - ext->value.length == sizeof(word16)) { - x509->keyUsage = *(word16*)ext->value.data; - x509->keyUsageCrit = ext->crit; - x509->keyUsageSet = 1; - } - break; - case NID_basic_constraints: - if (ext->obj) { - x509->isCa = ext->obj->ca; - x509->basicConstCrit = ext->crit; - if (ext->obj->pathlen) - x509->pathLength = ext->obj->pathlen->length; - x509->basicConstSet = 1; - } - break; - default: - WOLFSSL_MSG("Unsupported extension to add"); - return WOLFSSL_FAILURE; - } - - return WOLFSSL_SUCCESS; -} - #ifndef NO_WOLFSSL_STUB WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc) { @@ -15772,6 +15772,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) bio->type = (byte)method->type; bio->method = method; bio->shutdown = BIO_CLOSE; /* default to close things */ + bio->num = -1; /* Default to invalid socket */ bio->init = 1; if (method->type != WOLFSSL_BIO_FILE && method->type != WOLFSSL_BIO_SOCKET && @@ -15880,7 +15881,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (bio->ptr) { XFCLOSE((XFILE)bio->ptr); } - else { + else if (bio->num != -1) { XCLOSE(bio->num); } } @@ -18958,7 +18959,9 @@ int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in) int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) { WOLFSSL_STACK* node; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) WOLFSSL_CIPHER ciph; +#endif WOLFSSL_ENTER("wolfSSL_sk_push"); if (!sk) { @@ -18967,7 +18970,7 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) /* Check if empty data */ switch (sk->type) { - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) case STACK_TYPE_CIPHER: /* check if entire struct is zero */ XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER)); @@ -18981,15 +18984,17 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) return WOLFSSL_SUCCESS; } break; - #endif +#endif default: /* All other types are pointers */ if (!sk->data.generic) { sk->data.generic = (void*)data; sk->num = 1; +#ifdef OPENSSL_ALL if (sk->hash_fn) { sk->hash = sk->hash_fn(sk->data.generic); } +#endif return WOLFSSL_SUCCESS; } break; @@ -19015,7 +19020,7 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) sk->hash = 0; #endif switch (sk->type) { - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) case STACK_TYPE_CIPHER: node->data.cipher = sk->data.cipher; sk->data.cipher = *(WOLFSSL_CIPHER*)data; @@ -19023,14 +19028,16 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) sk->hash = sk->hash_fn(&sk->data.cipher); } break; - #endif +#endif default: /* All other types are pointers */ node->data.generic = sk->data.generic; sk->data.generic = (void*)data; +#ifdef OPENSSL_ALL if (sk->hash_fn) { sk->hash = sk->hash_fn(sk->data.generic); } +#endif break; } @@ -20583,8 +20590,6 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) } #endif /* !NO_FILESYSTEM */ -#endif /* NO_FILESYSTEM */ - static WOLFSSL_X509* wolfSSL_X509_X509_REQ_load_certificate_buffer( const unsigned char* buf, int sz, int format, int type) { @@ -31195,7 +31200,6 @@ WOLFSSL_DH* wolfSSL_DH_new(void) return external; } - void wolfSSL_DH_free(WOLFSSL_DH* dh) { WOLFSSL_ENTER("wolfSSL_DH_free"); @@ -31359,6 +31363,43 @@ int SetDhInternal(WOLFSSL_DH* dh) } #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) +WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) +{ + WOLFSSL_DH* ret = NULL; + + WOLFSSL_ENTER("wolfSSL_DH_dup"); + + if (!dh) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS){ + WOLFSSL_MSG("Bad DH set internal"); + return NULL; + } + + if (!(ret = wolfSSL_DH_new())) { + WOLFSSL_MSG("wolfSSL_DH_new error"); + return NULL; + } + + if (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) != MP_OKAY) { + WOLFSSL_MSG("wc_DhKeyCopy error"); + wolfSSL_DH_free(ret); + return NULL; + } + ret->inSet = 1; + + if (SetDhExternal(ret) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetDhExternal error"); + wolfSSL_DH_free(ret); + return NULL; + } + + return ret; +} + /* Set the members of DhKey into WOLFSSL_DH * DhKey was populated from wc_DhKeyDecode */ @@ -39454,7 +39495,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ !defined(WOLFCRYPT_ONLY) - #ifndef NO_CERTS +#ifndef NO_CERTS void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name) { WOLFSSL_ENTER("wolfSSL_X509_NAME_free"); @@ -40137,7 +40178,6 @@ cleanup: return ret; } -#endif /* WOLFSSL_CERT_GEN */ int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx) { @@ -40987,7 +41027,7 @@ err: #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM) char* pem = NULL; - long i = 0, l; + long i = pem_struct_min_sz, l; const char* header = NULL; const char* headerEnd = NULL; const char* footer = NULL; @@ -41014,21 +41054,21 @@ err: if (pem == NULL) return WOLFSSL_FAILURE; - if (wolfSSL_BIO_read(bio, &pem[i], pem_struct_min_sz) != + if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) != pem_struct_min_sz) { goto err; } - i += pem_struct_min_sz; /* Read the header and footer */ while ((l = wolfSSL_BIO_read(bio, &pem[i], 1)) == 1) { i++; if (!header) - header = XSTRNSTR(pem, "-----", i); + header = XSTRNSTR(pem, "-----BEGIN ", i); else if (header) { if (!headerEnd) { - headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----"), - "-----", i - (header + XSTR_SIZEOF("-----") - pem)); + headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "), + "-----", + i - (header + XSTR_SIZEOF("-----BEGIN ") - pem)); if (headerEnd) { headerEnd += XSTR_SIZEOF("-----"); /* Read in the newline */ @@ -41293,6 +41333,11 @@ err: WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID()"); + if (!data) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + if (out == NULL || *out == NULL) { ne = wolfSSL_X509_NAME_ENTRY_new(); if (ne == NULL) { @@ -41537,6 +41582,8 @@ err: return ret; } +#endif /* !NO_CERTS */ + /* NID variables are dependent on compatibility header files currently * * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL @@ -41782,6 +41829,8 @@ err: } #endif +#endif /* !WOLFCRYPT_ONLY */ + #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \ defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \ defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \ @@ -51720,7 +51769,7 @@ int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v) #endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */ -#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ +#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer, @@ -52113,7 +52162,7 @@ int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey) { return wolfSSL_X509_set_pubkey(req, pkey); } -#endif /* OPENSSL_EXTRA && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */ +#endif /* OPENSSL_ALL && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */ #ifdef WOLFSSL_STATIC_EPHEMERAL static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo, @@ -52244,4 +52293,4 @@ int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo, #endif /* WOLFSSL_STATIC_EPHEMERAL */ -#endif /* WOLFCRYPT_ONLY */ +#endif /* !WOLFCRYPT_ONLY */ diff --git a/tests/api.c b/tests/api.c index 5608029d8..b679530e7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27747,7 +27747,9 @@ static void test_wolfSSL_X509_STORE_CTX(void) X509_STORE_CTX_set_error(NULL, -5); X509_STORE_CTX_free(ctx); +#ifdef OPENSSL_ALL sk_X509_free(sk); +#endif X509_STORE_free(str); X509_free(x509); @@ -38156,6 +38158,10 @@ static void test_wolfSSL_X509_CRL(void) static void test_wolfSSL_d2i_X509_REQ(void) { +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) + /* ./certs/csr.signed.der and ./certs/csr.attr.der were + * generated by libest + * ./certs/csr.attr.der contains sample attributes */ const char* csrFile = "./certs/csr.signed.der"; const char* csrPopFile = "./certs/csr.attr.der"; /* ./certs/csr.dsa.pem is generated using @@ -38164,7 +38170,9 @@ static void test_wolfSSL_d2i_X509_REQ(void) * -outform PEM * with the passphrase "wolfSSL" */ +#ifndef NO_DSA const char* csrDsaFile = "./certs/csr.dsa.pem"; +#endif BIO* bio = NULL; X509* req = NULL; EVP_PKEY *pub_key = NULL; @@ -38188,6 +38196,10 @@ static void test_wolfSSL_d2i_X509_REQ(void) EVP_PKEY_free(pub_key); } { +#ifdef OPENSSL_ALL + X509_ATTRIBUTE* attr; + ASN1_TYPE *at; +#endif AssertNotNull(bio = BIO_new_file(csrPopFile, "rb")); AssertNotNull(d2i_X509_REQ_bio(bio, &req)); @@ -38201,15 +38213,23 @@ static void test_wolfSSL_d2i_X509_REQ(void) */ AssertIntEQ(X509_REQ_verify(req, pub_key), 1); +#ifdef OPENSSL_ALL /* * Obtain the challenge password from the CSR */ - AssertIntGE(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1), 0); + AssertIntEQ(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1), + NID_pkcs9_challengePassword); + AssertNotNull(attr = X509_REQ_get_attr(req, NID_pkcs9_challengePassword)); + AssertNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0)); + AssertNotNull(at->value.asn1_string); + AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "2xIE+qqp/rhyTXP+"); +#endif X509_free(req); BIO_free(bio); EVP_PKEY_free(pub_key); } +#ifndef NO_DSA { AssertNotNull(bio = BIO_new_file(csrDsaFile, "rb")); AssertNotNull(PEM_read_bio_X509_REQ(bio, &req, NULL, NULL)); @@ -38228,6 +38248,8 @@ static void test_wolfSSL_d2i_X509_REQ(void) BIO_free(bio); EVP_PKEY_free(pub_key); } +#endif +#endif /* defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) */ } static void test_wolfSSL_PEM_read_X509(void) @@ -38987,7 +39009,9 @@ static void test_wolfSSL_X509_print() !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(XSNPRINTF) X509 *x509; BIO *bio; +#ifdef OPENSSL_ALL const X509_ALGOR *cert_sig_alg; +#endif int stdout_fd = fileno(stdout); printf(testingFmt, "wolfSSL_X509_print"); @@ -39007,9 +39031,11 @@ static void test_wolfSSL_X509_print() AssertNotNull(bio = BIO_new_fd(stdout_fd, BIO_NOCLOSE)); +#ifdef OPENSSL_ALL /* Print signature */ AssertNotNull(cert_sig_alg = X509_get0_tbs_sigalg(x509)); AssertIntEQ(X509_signature_print(bio, cert_sig_alg, NULL), SSL_SUCCESS); +#endif /* print to stdout */ AssertIntEQ(X509_print(bio, x509), SSL_SUCCESS); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 385b5d99d..05187a93e 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -121,6 +121,12 @@ extern int wc_InitRsaHw(RsaKey* key); #endif #endif +#ifndef NO_DSA + #include +#else + typedef void* DsaKey; +#endif + #ifdef WOLF_CRYPTO_CB #include #endif @@ -12365,83 +12371,6 @@ static int CopyValidity(byte* output, Cert* cert) #endif - -/* Set Date validity from now until now + daysValid - * return size in bytes written to output, 0 on error */ -static int SetValidity(byte* output, int daysValid) -{ - byte before[MAX_DATE_SIZE]; - byte after[MAX_DATE_SIZE]; - - int beforeSz; - int afterSz; - int seqSz; - - time_t now; - time_t then; - struct tm* tmpTime; - struct tm* expandedTime; - struct tm localTime; - -#if defined(NEED_TMP_TIME) - /* for use with gmtime_r */ - struct tm tmpTimeStorage; - tmpTime = &tmpTimeStorage; -#else - tmpTime = NULL; -#endif - (void)tmpTime; - - now = XTIME(0); - - /* before now */ - before[0] = ASN_GENERALIZED_TIME; - beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */ - - /* subtract 1 day of seconds for more compliance */ - then = now - 86400; - expandedTime = XGMTIME(&then, tmpTime); - if (expandedTime == NULL) { - WOLFSSL_MSG("XGMTIME failed"); - return 0; /* error */ - } - localTime = *expandedTime; - - /* adjust */ - localTime.tm_year += 1900; - localTime.tm_mon += 1; - - SetTime(&localTime, before + beforeSz); - beforeSz += ASN_GEN_TIME_SZ; - - after[0] = ASN_GENERALIZED_TIME; - afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */ - - /* add daysValid of seconds */ - then = now + (daysValid * (time_t)86400); - expandedTime = XGMTIME(&then, tmpTime); - if (expandedTime == NULL) { - WOLFSSL_MSG("XGMTIME failed"); - return 0; /* error */ - } - localTime = *expandedTime; - - /* adjust */ - localTime.tm_year += 1900; - localTime.tm_mon += 1; - - SetTime(&localTime, after + afterSz); - afterSz += ASN_GEN_TIME_SZ; - - /* headers and output */ - seqSz = SetSequence(beforeSz + afterSz, output); - XMEMCPY(output + seqSz, before, beforeSz); - XMEMCPY(output + seqSz + beforeSz, after, afterSz); - - return seqSz + beforeSz + afterSz; -} - - /* ASN Encoded Name field */ typedef struct EncodedName { int nameLen; /* actual string value length */ @@ -13433,6 +13362,81 @@ int SetName(byte* output, word32 outputSz, CertName* name) return totalBytes; } +/* Set Date validity from now until now + daysValid + * return size in bytes written to output, 0 on error */ +static int SetValidity(byte* output, int daysValid) +{ + byte before[MAX_DATE_SIZE]; + byte after[MAX_DATE_SIZE]; + + int beforeSz; + int afterSz; + int seqSz; + + time_t now; + time_t then; + struct tm* tmpTime; + struct tm* expandedTime; + struct tm localTime; + +#if defined(NEED_TMP_TIME) + /* for use with gmtime_r */ + struct tm tmpTimeStorage; + tmpTime = &tmpTimeStorage; +#else + tmpTime = NULL; +#endif + (void)tmpTime; + + now = XTIME(0); + + /* before now */ + before[0] = ASN_GENERALIZED_TIME; + beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */ + + /* subtract 1 day of seconds for more compliance */ + then = now - 86400; + expandedTime = XGMTIME(&then, tmpTime); + if (expandedTime == NULL) { + WOLFSSL_MSG("XGMTIME failed"); + return 0; /* error */ + } + localTime = *expandedTime; + + /* adjust */ + localTime.tm_year += 1900; + localTime.tm_mon += 1; + + SetTime(&localTime, before + beforeSz); + beforeSz += ASN_GEN_TIME_SZ; + + after[0] = ASN_GENERALIZED_TIME; + afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */ + + /* add daysValid of seconds */ + then = now + (daysValid * (time_t)86400); + expandedTime = XGMTIME(&then, tmpTime); + if (expandedTime == NULL) { + WOLFSSL_MSG("XGMTIME failed"); + return 0; /* error */ + } + localTime = *expandedTime; + + /* adjust */ + localTime.tm_year += 1900; + localTime.tm_mon += 1; + + SetTime(&localTime, after + afterSz); + afterSz += ASN_GEN_TIME_SZ; + + /* headers and output */ + seqSz = SetSequence(beforeSz + afterSz, output); + XMEMCPY(output + seqSz, before, beforeSz); + XMEMCPY(output + seqSz + beforeSz, after, afterSz); + + return seqSz + beforeSz + afterSz; +} + /* encode info from cert into DER encoded format */ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, const byte* ntruKey, word16 ntruSz, DsaKey* dsaKey, diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index f5e89aa25..0c9f18275 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -2103,7 +2103,6 @@ WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst) return ret; } -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) if ((ret = mp_copy(&src->pub, &dst->pub)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); return ret; @@ -2113,7 +2112,6 @@ WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst) WOLFSSL_MSG("mp_copy error"); return ret; } -#endif dst->heap = src->heap; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 086371fdb..4e0478f68 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3767,7 +3767,9 @@ struct WOLFSSL_X509 { byte serial[EXTERNAL_SERIAL_SIZE]; char subjectCN[ASN_NAME_MAX]; /* common name short cut */ #ifdef WOLFSSL_CERT_REQ +#ifdef OPENSSL_ALL WOLFSSL_X509_ATTRIBUTE* challengePwAttr; +#endif char challengePw[CTC_NAME_SIZE]; /* for REQ certs */ #endif WOLFSSL_X509_NAME issuer; diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index d112f038f..c5786b73a 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -40,7 +40,14 @@ #define BIO_FLAGS_SHOULD_RETRY WOLFSSL_BIO_FLAG_RETRY #define BIO_new_fp wolfSSL_BIO_new_fp +#if defined(OPENSSL_ALL) \ + || defined(HAVE_STUNNEL) \ + || defined(HAVE_LIGHTY) \ + || defined(WOLFSSL_MYSQL_COMPATIBLE) \ + || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) #define BIO_new_file wolfSSL_BIO_new_file +#endif #define BIO_new_fp wolfSSL_BIO_new_fp #define BIO_ctrl wolfSSL_BIO_ctrl #define BIO_ctrl_pending wolfSSL_BIO_ctrl_pending diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index af8faa95d..7f24efa4f 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -306,7 +306,7 @@ enum Misc_ASN { #endif RSA_INTS = 8, /* RSA ints in private key */ DSA_INTS = 5, /* DSA ints in private key */ - MIN_DATE_SIZE = 13, + MIN_DATE_SIZE = 12, MAX_DATE_SIZE = 32, ASN_GEN_TIME_SZ = 15, /* 7 numbers * 2 + Zulu tag */ #ifndef NO_RSA @@ -679,7 +679,7 @@ struct SignatureCtx { #ifndef NO_RSA byte* out; #endif -#if !defined(NO_RSA) && !defined(NO_DSA) +#if !(defined(NO_RSA) && defined(NO_DSA)) byte* sigCpy; #endif #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 00b1c6267..8bc1dd3d4 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -121,12 +121,7 @@ WOLFSSL_API int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz, const byte* pub, word32 pubSz); WOLFSSL_API int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz, byte* pub, word32* pPubSz); -#endif /* WOLFSSL_DH_EXTRA */ - -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst); -WOLFSSL_LOCAL int wc_DhSetFullKeys(DhKey* key,const byte* priv_key,word32 privSz, - const byte* pub_key, word32 pubSz); #endif WOLFSSL_API int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz, From 77c730361ed45c425da69f3bae0c05463a5b5910 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 28 Oct 2020 11:57:18 +0100 Subject: [PATCH 43/53] Jenkins fixes --- certs/include.am | 5 +- src/bio.c | 16 ++- src/ssl.c | 267 +++++++++++++++++++++++--------------- tests/api.c | 78 +++++++---- tests/include.am | 4 +- wolfcrypt/src/asn.c | 18 +-- wolfcrypt/src/evp.c | 14 +- wolfcrypt/src/pkcs7.c | 11 +- wolfcrypt/src/rsa.c | 5 - wolfssl/internal.h | 6 +- wolfssl/openssl/asn1.h | 2 +- wolfssl/openssl/conf.h | 21 ++- wolfssl/openssl/crypto.h | 5 + wolfssl/openssl/stack.h | 2 - wolfssl/ssl.h | 15 ++- wolfssl/wolfcrypt/types.h | 5 +- 16 files changed, 294 insertions(+), 180 deletions(-) diff --git a/certs/include.am b/certs/include.am index 28c5e8515..7d613b9ef 100644 --- a/certs/include.am +++ b/certs/include.am @@ -52,7 +52,10 @@ EXTRA_DIST += \ certs/ecc-privOnlyCert.pem \ certs/dh3072.pem \ certs/dh4096.pem \ - certs/client-cert-ext.pem + certs/client-cert-ext.pem \ + certs/csr.attr.der \ + certs/csr.dsa.pem \ + certs/csr.signed.der EXTRA_DIST += \ certs/ca-key.der \ diff --git a/src/bio.c b/src/bio.c index c5e335acb..d80b7c096 100644 --- a/src/bio.c +++ b/src/bio.c @@ -231,8 +231,11 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) if (bio && bio->type == WOLFSSL_BIO_FILE) { if (bio->ptr) ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr); + #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) else - ret = XREAD(bio->num, buf, len); + ret = (int)XREAD(bio->num, buf, len); + #endif } #endif @@ -586,8 +589,11 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) if (bio && bio->type == WOLFSSL_BIO_FILE) { if (bio->ptr) ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr); + #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) else - ret = XWRITE(bio->num, data, len); + ret = (int)XWRITE(bio->num, data, len); + #endif } #endif @@ -1328,6 +1334,12 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) } #ifndef NO_FILESYSTEM +/** + * Creates a new file BIO object + * @param fd file descriptor for to use for the new object + * @param close_flag BIO_NOCLOSE or BIO_CLOSE + * @return New BIO object or NULL on failure + */ WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag) { WOLFSSL_BIO* bio; diff --git a/src/ssl.c b/src/ssl.c index ad7f8af0b..ff6fa8d13 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8065,7 +8065,11 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert) } InitDecodedCert(&cert, rawCert, (word32)outSz, 0); - if (ParseCert(&cert, passedCert->isCSR ? CERTREQ_TYPE : CA_TYPE, + if (ParseCert(&cert, +#ifdef WOLFSSL_CERT_REQ + passedCert->isCSR ? CERTREQ_TYPE : +#endif + CA_TYPE, NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); return WOLFSSL_FAILURE; @@ -8080,7 +8084,10 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert) return WOLFSSL_FAILURE; } - if (!passedCert->isCSR) { +#ifdef WOLFSSL_CERT_REQ + if (!passedCert->isCSR) +#endif + { if (input[idx++] != ASN_EXTENSIONS) { WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); FreeDecodedCert(&cert); @@ -8403,7 +8410,11 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) InitDecodedCert( &cert, rawCert, (word32)outSz, 0); - if (ParseCert(&cert, x509->isCSR ? CERTREQ_TYPE : CA_TYPE, + if (ParseCert(&cert, +#ifdef WOLFSSL_CERT_REQ + x509->isCSR ? CERTREQ_TYPE : +#endif + CA_TYPE, NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); wolfSSL_X509_EXTENSION_free(ext); @@ -8420,7 +8431,10 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) return NULL; } - if (!x509->isCSR) { +#ifdef WOLFSSL_CERT_REQ + if (!x509->isCSR) +#endif + { if (input[idx++] != ASN_EXTENSIONS) { WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); wolfSSL_X509_EXTENSION_free(ext); @@ -9412,7 +9426,11 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) InitDecodedCert( &cert, rawCert, (word32)outSz, 0); - if (ParseCert(&cert, x509->isCSR ? CERTREQ_TYPE : CA_TYPE, + if (ParseCert(&cert, +#ifdef WOLFSSL_CERT_REQ + x509->isCSR ? CERTREQ_TYPE : +#endif + CA_TYPE, NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); return WOLFSSL_FATAL_ERROR; @@ -9427,7 +9445,10 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) return WOLFSSL_FATAL_ERROR; } - if (!x509->isCSR) { +#ifdef WOLFSSL_CERT_REQ + if (!x509->isCSR) +#endif + { if (input[idx++] != ASN_EXTENSIONS) { WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); FreeDecodedCert(&cert); @@ -13454,7 +13475,7 @@ int AddSession(WOLFSSL* ssl) session = &SessionCache[row].Sessions[idx]; } - session->side = ssl->options.side; + session->side = (byte)ssl->options.side; #ifdef WOLFSSL_TLS13 if (ssl->options.tls1_3) { @@ -15653,6 +15674,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return bio; } + /** + * Create new socket BIO object. This is a pure TCP connection with + * no SSL or TLS protection. + * @param str IP address to connect to + * @return New BIO object or NULL on failure + */ WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str) { WOLFSSL_BIO *bio; @@ -15665,6 +15692,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return bio; } + /** + * Set the port to connect to in the BIO object + * @param b BIO object + * @param port destination port + * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure + */ long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port) { int p; @@ -15685,6 +15718,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return WOLFSSL_SUCCESS; } +#ifdef HAVE_HTTP_CLIENT + /** + * Attempt to connect to the destination address and port + * @param b BIO object + * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure + */ long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b) { SOCKET_T sfd = SOCKET_INVALID; @@ -15704,7 +15743,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) b->shutdown = BIO_CLOSE; return WOLFSSL_SUCCESS; } - +#endif /* HAVE_HTTP_CLIENT */ int wolfSSL_BIO_eof(WOLFSSL_BIO* b) { @@ -15881,9 +15920,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (bio->ptr) { XFCLOSE((XFILE)bio->ptr); } + #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) else if (bio->num != -1) { XCLOSE(bio->num); } + #endif } #endif @@ -16229,8 +16271,8 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) } switch (version) { -#ifdef WOLFSSL_TLS13 case TLS1_3_VERSION: +#ifdef WOLFSSL_TLS13 wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2); FALL_THROUGH; #else @@ -19446,7 +19488,8 @@ static int wolfSSL_CONF_VALUE_cmp(const WOLFSSL_CONF_VALUE *a, } } -/* Use MD5 for hashing */ +/* Use MD5 for hashing as it is fast and should + * be good enough for database indexing */ unsigned long wolfSSL_LH_strhash(const char *str) { unsigned long ret = 0; @@ -19458,16 +19501,16 @@ unsigned long wolfSSL_LH_strhash(const char *str) return 0; #ifndef NO_MD5 - strLen = XSTRLEN(str); + strLen = (int)XSTRLEN(str); if (wc_Md5Hash((const byte*)str, strLen, digest) != 0) { WOLFSSL_MSG("wc_Md5Hash error"); return 0; } /* Take first 4 bytes in small endian as unsigned long */ - ret = digest[0]; - ret |= digest[1] << 8; - ret |= digest[2] << 16; - ret |= digest[3] << 24; + ret = (unsigned int)digest[0]; + ret |= ((unsigned int)digest[1] << 8 ); + ret |= ((unsigned int)digest[2] << 16); + ret |= ((unsigned int)digest[3] << 24); #else WOLFSSL_MSG("No md5 available for wolfSSL_LH_strhash"); #endif @@ -19551,7 +19594,7 @@ WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf, return NULL; } - slen = XSTRLEN(section); + slen = (int)XSTRLEN(section); if (!(ret = wolfSSL_CONF_VALUE_new())) { WOLFSSL_MSG("wolfSSL_CONF_new error"); @@ -19606,7 +19649,7 @@ WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, while (sk) { WOLFSSL_CONF_VALUE* val = sk->data.conf; if (val) { - if (XSTRCMP(section, val->section) == 0) { + if (!val->name && XSTRCMP(section, val->section) == 0) { return val; } } @@ -19741,7 +19784,7 @@ static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, } if (section) { - len = XSTRLEN(section); + len = (int)XSTRLEN(section); ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); if (!ret->section) { WOLFSSL_MSG("malloc error"); @@ -19752,7 +19795,7 @@ static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, } if (name) { - len = XSTRLEN(name); + len = (int)XSTRLEN(name); ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); if (!ret->name) { WOLFSSL_MSG("malloc error"); @@ -19763,7 +19806,7 @@ static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, } if (value) { - len = XSTRLEN(value); + len = (int)XSTRLEN(value); ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL); if (!ret->value) { WOLFSSL_MSG("malloc error"); @@ -19779,7 +19822,7 @@ static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section, static char* expandValue(WOLFSSL_CONF *conf, const char* section, char *str) { - int strLen = XSTRLEN(str); + int strLen = (int)XSTRLEN(str); char* ret = NULL; /* Check to see if there is anything to expand */ @@ -19806,7 +19849,7 @@ static char* expandValue(WOLFSSL_CONF *conf, const char* section, * format: ${section_name::var_name} */ s = ++startIdx; while (*strIdx && *strIdx != ':') strIdx++; - if (!strIdx || s == strIdx || strIdx[1] != ':') { + if (!*strIdx || s == strIdx || strIdx[1] != ':') { WOLFSSL_MSG("invalid section name in " "variable expansion"); goto expand_cleanup; @@ -19838,7 +19881,7 @@ static char* expandValue(WOLFSSL_CONF *conf, const char* section, *endIdx = prevValue; /* Skip copy if no value or zero-length value */ if (value && *value) { - int valueLen = XSTRLEN(value); + int valueLen = (int)XSTRLEN(value); char* newRet; /* This will allocate slightly more memory than necessary * but better be safe */ @@ -19900,7 +19943,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) WOLFSSL_MSG("wolfSSL_BIO_get_len error"); goto cleanup; } - if (!(buf = (char*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + if (!(buf = (char*)XMALLOC(bufLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { WOLFSSL_MSG("malloc error"); goto cleanup; } @@ -19918,11 +19961,11 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) idx = buf; bufEnd = buf + bufLen; while (idx < bufEnd) { - char* lineEnd = XSTRNSTR(idx, "\n", bufEnd - idx); + char* lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx)); char* maxIdx; if (!lineEnd) lineEnd = bufEnd; /* Last line in file */ - maxIdx = XSTRNSTR(idx, "#", lineEnd - idx); + maxIdx = XSTRNSTR(idx, "#", (unsigned int)(lineEnd - idx)); if (!maxIdx) maxIdx = lineEnd; line++; @@ -19950,7 +19993,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) /* Find end of section name */ while (idx < maxIdx && *idx != ' ' && *idx != ']') idx++; - sectionNameLen = idx - sectionName; + sectionNameLen = (int)(idx - sectionName); SKIP_WHITESPACE(idx, maxIdx); if (*idx != ']') { @@ -19976,7 +20019,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) /* Find end of name */ while (idx < maxIdx && *idx != ' ' && *idx != '=') idx++; - nameLen = idx - name; + nameLen = (int)(idx - name); SKIP_WHITESPACE(idx, maxIdx); if (*idx != '=') { WOLFSSL_MSG("Missing equals sign"); @@ -19989,7 +20032,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) idx = maxIdx-1; while (idx >= value && (*idx == ' ' || *idx == '\t')) idx--; - valueLen = idx - value + 1; + valueLen = (int)(idx - value + 1); /* Sanity checks */ if (nameLen <= 0 || valueLen <= 0) { @@ -21565,7 +21608,7 @@ WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) char** fieldPtr = NULL; int fieldPtrIdx = 0; char* fieldCheckIdx = NULL; - lineEnd = XSTRNSTR(idx, "\n", bufEnd - idx); + lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx)); if (!lineEnd) lineEnd = bufEnd; if (idx == lineEnd) /* empty line */ @@ -21675,7 +21718,7 @@ long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db) } } idx[-1] = '\n'; - sz = idx - buf; + sz = (int)(idx - buf); if (wolfSSL_BIO_write(out, buf, sz) != sz) { WOLFSSL_MSG("wolfSSL_BIO_write error"); @@ -23320,6 +23363,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return wolfSSL_X509_print_ex(bio, x509, 0, 0); } +#ifndef NO_FILESYSTEM int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509) { WOLFSSL_BIO* bio; @@ -23348,6 +23392,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return ret; } +#endif /* NO_FILESYSTEM */ #endif /* XSNPRINTF */ #endif /* !NO_BIO */ @@ -24179,8 +24224,13 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, return &store->lookup; } +#if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) +static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, + unsigned char* der, int* derSz, int includeSig); +#endif #ifndef NO_CERTS +#ifdef WOLFSSL_CERT_GEN #ifndef NO_BIO /* Converts the X509 to DER format and outputs it into bio. * @@ -24250,6 +24300,7 @@ int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 1); } #endif /* WOLFSSL_CERT_REQ */ +#endif /* WOLFSSL_CERT_GEN */ /* Converts an internal structure to a DER buffer * @@ -25299,6 +25350,8 @@ static int wolfSSL_X509_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pk int derSz = 0; int type; + (void)req; + if (x509 == NULL || pkey == NULL) { return WOLFSSL_FATAL_ERROR; } @@ -27668,7 +27721,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, { const unsigned char *d; long len; - int tag, class; + int tag, cls; WOLFSSL_ASN1_OBJECT* ret = NULL; WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT"); @@ -27680,7 +27733,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, d = *der; - if (wolfSSL_ASN1_get_object(&d, &len, &tag, &class, length) & 0x80) { + if (wolfSSL_ASN1_get_object(&d, &len, &tag, &cls, length) & 0x80) { WOLFSSL_MSG("wolfSSL_ASN1_get_object error"); return NULL; } @@ -27702,7 +27755,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, * @param in ASN1 encoded data. *in is moved to the value of the ASN1 object * @param len Length of parsed ASN1 object * @param tag Tag value of parsed ASN1 object - * @param class Class of parsed ASN1 object + * @param cls Class of parsed ASN1 object * @param inLen Length of *in buffer * @return int Depends on which bits are set in the returned int: * 0x80 an error occurred during parsing @@ -27710,7 +27763,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, * 0x01 the parsed object length is infinite */ int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, - int *class, long inLen) + int *cls, long inLen) { word32 inOutIdx = 0; int l; @@ -27719,27 +27772,27 @@ int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, WOLFSSL_ENTER("wolfSSL_ASN1_get_object"); - if (!in || !*in || !len || !tag || !class || inLen == 0) { + if (!in || !*in || !len || !tag || !cls || inLen == 0) { WOLFSSL_MSG("Bad parameter"); return ret; } - if (GetASNTag(*in, &inOutIdx, &t, inLen) != 0) { + if (GetASNTag(*in, &inOutIdx, &t, (word32)inLen) != 0) { WOLFSSL_MSG("GetASNTag error"); return ret; } - if (GetLength(*in, &inOutIdx, &l, inLen) < 0) { + if (GetLength(*in, &inOutIdx, &l, (word32)inLen) < 0) { WOLFSSL_MSG("GetLength error"); return ret; } *tag = t & 0x1F; /* Tag number is 5 lsb */ - *class = t & 0xC0; /* Class is 2 msb */ + *cls = t & 0xC0; /* Class is 2 msb */ *len = l; ret = t & ASN_CONSTRUCTED; - if (l > inLen - inOutIdx) { + if (l > (int)(inLen - inOutIdx)) { /* Still return other values but indicate error in msb */ ret |= 0x80; } @@ -27773,7 +27826,7 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, } XMEMCPY((byte*)ret->obj, *pp, len); - ret->objSz = len; + ret->objSz = (unsigned int)len; ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; *pp += len; @@ -29122,7 +29175,7 @@ int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str) WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; } - slen = XSTRLEN(str)+1; + slen = (int)XSTRLEN(str)+1; if (slen > CTC_DATE_SIZE) { WOLFSSL_MSG("Date string too long"); return WOLFSSL_FAILURE; @@ -39856,7 +39909,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) * updates derSz with certificate body size on success * return WOLFSSL_SUCCESS on success */ - int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, + static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, unsigned char* der, int* derSz, int includeSig) { int ret = WOLFSSL_FAILURE; @@ -40046,6 +40099,8 @@ cleanup: int sigType; WC_RNG rng; + (void)req; + sigType = wolfSSL_sigTypeFromPKEY(md, pkey); if (sigType == WOLFSSL_FAILURE) return WOLFSSL_FATAL_ERROR; @@ -40065,7 +40120,7 @@ cleanup: } #endif - /* Sign the certificate request body. */ + /* Sign the certificate (request) body. */ ret = wc_InitRng(&rng); if (ret != 0) return ret; @@ -40309,7 +40364,7 @@ cleanup: XFREE(pem, 0, DYNAMIC_TYPE_PEM); return NULL; } - footerSz = XSTRLEN(footer); + footerSz = (long)XSTRLEN(footer); /* TODO: Inefficient * reading in one byte at a time until see the footer @@ -40532,6 +40587,7 @@ err: } #endif +#ifdef WOLFSSL_CERT_GEN #ifndef NO_BIO int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x) { @@ -40558,6 +40614,7 @@ err: return ret; } #endif /* !NO_BIO */ +#endif /* WOLFSSL_CERT_GEN */ #endif /* !NO_FILESYSTEM */ #define PEM_BEGIN "-----BEGIN " @@ -41063,12 +41120,13 @@ err: while ((l = wolfSSL_BIO_read(bio, &pem[i], 1)) == 1) { i++; if (!header) - header = XSTRNSTR(pem, "-----BEGIN ", i); + header = XSTRNSTR(pem, "-----BEGIN ", (unsigned int)i); else if (header) { if (!headerEnd) { headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "), "-----", - i - (header + XSTR_SIZEOF("-----BEGIN ") - pem)); + (unsigned int) + (i - (header + XSTR_SIZEOF("-----BEGIN ") - pem))); if (headerEnd) { headerEnd += XSTR_SIZEOF("-----"); /* Read in the newline */ @@ -41082,12 +41140,12 @@ err: } else if (!footer) { footer = XSTRNSTR(headerEnd, "-----END ", - i - (headerEnd - pem)); + (unsigned int)(i - (headerEnd - pem))); } else if (!footerEnd) { footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"), - "-----", i - - (footer + XSTR_SIZEOF("-----") - pem)); + "-----", (unsigned int)(i - + (footer + XSTR_SIZEOF("-----") - pem))); if (footerEnd) { footerEnd += XSTR_SIZEOF("-----"); /* Now check that footer matches header */ @@ -41121,12 +41179,13 @@ err: WOLFSSL_MSG("Parsing x509 cert"); *x509 = wolfSSL_X509_load_certificate_buffer( (const unsigned char*) header, - footerEnd - header, WOLFSSL_FILETYPE_PEM); + (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM); if (!*x509) { WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error"); goto err; } } +#ifdef HAVE_CRL else if (headerEnd - header == XSTR_SIZEOF("-----BEGIN X509 CRL-----") && XMEMCMP(header, "-----BEGIN X509 CRL-----", @@ -41144,6 +41203,7 @@ err: goto err; } } +#endif else { /* TODO support WOLFSSL_X509_PKEY as well */ WOLFSSL_MSG("Unsupported PEM structure"); @@ -41216,7 +41276,9 @@ err: } if (ret != WOLFSSL_SUCCESS) { wolfSSL_X509_free(x509); +#ifdef HAVE_CRL wolfSSL_X509_CRL_free(crl); +#endif wolfSSL_X509_PKEY_free(x_pkey); } else { @@ -42194,7 +42256,7 @@ err: if (ret == ASN_OBJECT_ID_E) { /* Put ASN object tag in front and try again */ int len = SetObjectId(o->objSz, NULL) + o->objSz; - byte* buf = XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + byte* buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (!buf) { WOLFSSL_MSG("malloc error"); return -1; @@ -42269,35 +42331,34 @@ err: { WOLFSSL_ENTER("wolfSSL_OBJ_cmp"); - if (a != NULL && b != NULL && - a->obj != NULL && b->obj != NULL && - a->objSz == b->objSz) { - return XMEMCMP(a->obj, b->obj, a->objSz); - } - else if (a != NULL && b != NULL && a->objSz != b->objSz && - (a->type == EXT_KEY_USAGE_OID - || b->type == EXT_KEY_USAGE_OID)) { - /* Special case for EXT_KEY_USAGE_OID so that - * cmp will be treated as a substring search */ - /* Used in libest to check for id-kp-cmcRA in - * EXT_KEY_USAGE extension */ - unsigned int idx; - const byte* s; /* shorter */ - unsigned int sLen; - const byte* l; /* longer */ - unsigned int lLen; - if (a->objSz > b->objSz) { - s = b->obj; sLen = b->objSz; - l = a->obj; lLen = a->objSz; + if (a && b && a->obj && b->obj) { + if (a->objSz == b->objSz) { + return XMEMCMP(a->obj, b->obj, a->objSz); } - else { - s = a->obj; sLen = a->objSz; - l = b->obj; lLen = b->objSz; - } - for (idx = 0; idx <= lLen - sLen; idx++) { - if (XMEMCMP(l + idx, s, sLen) == 0) { - /* Found substring */ - return 0; + else if (a->type == EXT_KEY_USAGE_OID || + b->type == EXT_KEY_USAGE_OID) { + /* Special case for EXT_KEY_USAGE_OID so that + * cmp will be treated as a substring search */ + /* Used in libest to check for id-kp-cmcRA in + * EXT_KEY_USAGE extension */ + unsigned int idx; + const byte* s; /* shorter */ + unsigned int sLen; + const byte* l; /* longer */ + unsigned int lLen; + if (a->objSz > b->objSz) { + s = b->obj; sLen = b->objSz; + l = a->obj; lLen = a->objSz; + } + else { + s = a->obj; sLen = a->objSz; + l = b->obj; lLen = b->objSz; + } + for (idx = 0; idx <= lLen - sLen; idx++) { + if (XMEMCMP(l + idx, s, sLen) == 0) { + /* Found substring */ + return 0; + } } } } @@ -42554,18 +42615,6 @@ err: return ret == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } -#ifndef NO_WOLFSSL_STUB - WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( - WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk) - { - (void) sk; - WOLFSSL_ENTER("wolfSSL_dup_CA_list"); - WOLFSSL_STUB("SSL_dup_CA_list"); - - return NULL; - } -#endif - /* wolfSSL uses negative values for error states. This function returns an * unsigned type so the value returned is the absolute value of the error. */ @@ -42935,7 +42984,7 @@ size_t wolfSSL_strlcpy(char *dst, const char *src, size_t dstSize) { size_t i; - if (!dstSize) + if (!dstSize || !dst || !src) return 0; /* Always have to leave a space for NULL */ @@ -43615,7 +43664,6 @@ int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) if (ret <= 0) return WOLFSSL_FAILURE; return WOLFSSL_SUCCESS; } -#endif /* WOLFSSL_CERT_GEN */ int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert) { @@ -43679,10 +43727,10 @@ error: XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FAILURE; } +#endif /* WOLFSSL_CERT_GEN */ #endif /* !NO_BIO */ - #if defined(OPENSSL_EXTRA) && !defined(NO_DH) /* Initialize ctx->dh with dh's params. Return WOLFSSL_SUCCESS on ok */ long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh) @@ -46742,6 +46790,7 @@ int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s) return 0; } +#ifndef NO_BIO BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s) { WOLFSSL_ENTER("wolfSSL_SSL_get_rbio"); @@ -46898,7 +46947,7 @@ int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, if (len > (int)(sizeof(asn1->intData) - extraTagSz)) { /* Allocate mem for data */ if (asn1->isDynamic) { - byte* tmp = XREALLOC(asn1->data, len + extraTagSz, NULL, + byte* tmp = (byte*)XREALLOC(asn1->data, len + extraTagSz, NULL, DYNAMIC_TYPE_OPENSSL); if (!tmp) { WOLFSSL_MSG("realloc error"); @@ -46907,7 +46956,7 @@ int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, asn1->data = tmp; } else { - asn1->data = XMALLOC(len + extraTagSz, NULL, + asn1->data = (byte*)XMALLOC(len + extraTagSz, NULL, DYNAMIC_TYPE_OPENSSL); if (!asn1->data) { WOLFSSL_MSG("malloc error"); @@ -47425,7 +47474,7 @@ WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* st int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) { if (strings) - return strings->num; + return (int)strings->num; return 0; } #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ @@ -47712,7 +47761,7 @@ void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len) { if (ptr) - ForceZero(ptr, len); + ForceZero(ptr, (word32)len); } int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p, @@ -48130,6 +48179,7 @@ int oid2nid(word32 oid, int grp) } break; +#ifdef WOLFSSL_CERT_REQ case oidCsrAttrType: switch (oid) { case CHALLENGE_PASSWORD_OID: @@ -48138,6 +48188,7 @@ int oid2nid(word32 oid, int grp) return NID_serialNumber; } break; +#endif default: WOLFSSL_MSG("NID not in table"); @@ -51032,7 +51083,7 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, #endif /* !NO_BIO */ /** - * This API was added as a helper functio for libest. It + * This API was added as a helper function for libest. It * extracts a stack of certificates from the pkcs7 object. * @param pkcs7 PKCS7 parameter object * @return WOLFSSL_STACK_OF(WOLFSSL_X509)* @@ -51047,7 +51098,7 @@ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) if (!p7) { WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; + return NULL; } if (p7->certs) @@ -51714,7 +51765,6 @@ int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s) int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) { byte* p = NULL; - int pLen; WOLFSSL_ENTER("wolfSSL_X509_set_pubkey"); if (cert == NULL || pkey == NULL) @@ -51729,7 +51779,10 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) else return WOLFSSL_FAILURE; +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) if (pkey->type == EVP_PKEY_RSA) { + int pLen; /* Public and private key formats differ. Make sure to put in the * public key format in the cert. */ if ((pLen = wolfSSL_i2d_RSAPublicKey(pkey->rsa, (const byte**)&p)) <= 0) { @@ -51741,7 +51794,9 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey) cert->pubKey.buffer = p; cert->pubKey.length = pLen; } - else { + else +#endif + { p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); if (p == NULL) return WOLFSSL_FAILURE; @@ -51955,7 +52010,7 @@ int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, } if (len < 0) { - len = XSTRLEN((char*)bytes); + len = (int)XSTRLEN((char*)bytes); } /* For now just pretend that we support this for libest testing */ @@ -51998,7 +52053,7 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, switch (nid) { case NID_pkcs9_challengePassword: if (len < 0) - len = XSTRLEN((char*)bytes); + len = (int)XSTRLEN((char*)bytes); if (len < CTC_NAME_SIZE) { XMEMCPY(req->challengePw, bytes, len); req->challengePw[len] = '\0'; @@ -52029,7 +52084,7 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, break; case NID_serialNumber: if (len < 0) - len = XSTRLEN((char*)bytes); + len = (int)XSTRLEN((char*)bytes); if (len + 1 > EXTERNAL_SERIAL_SIZE) { WOLFSSL_MSG("SerialNumber too long"); return WOLFSSL_FAILURE; diff --git a/tests/api.c b/tests/api.c index b679530e7..630dce6e3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25290,7 +25290,17 @@ static int test_wc_HashGetFlags(void) static void test_wolfSSL_lhash(void) { +#ifdef OPENSSL_ALL + const char testStr[] = "Like a true nature's child\n" + "We were born\n" + "Born to be wild"; + printf(testingFmt, "wolfSSL_LH_strhash()"); + + AssertIntEQ(lh_strhash(testStr), 0xb1231320); + + printf(resultFmt, passed); +#endif } static void test_wolfSSL_X509_NAME(void) @@ -26811,7 +26821,9 @@ static void test_wolfSSL_tmp_dh(void) int bytes; DSA* dsa; DH* dh; +#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) DH* dh2; +#endif BIO* bio; SSL* ssl; SSL_CTX* ctx; @@ -26840,7 +26852,9 @@ static void test_wolfSSL_tmp_dh(void) dh = wolfSSL_DSA_dup_DH(dsa); AssertNotNull(dh); +#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) AssertNotNull(dh2 = wolfSSL_DH_dup(dh)); +#endif AssertIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS); #ifndef NO_WOLFSSL_SERVER @@ -26852,7 +26866,9 @@ static void test_wolfSSL_tmp_dh(void) BIO_free(bio); DSA_free(dsa); DH_free(dh); +#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) DH_free(dh2); +#endif SSL_free(ssl); SSL_CTX_free(ctx); @@ -27662,7 +27678,7 @@ static void test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void) static void test_wolfSSL_PKCS7_certs(void) { #if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ - !defined(NO_FILESYSTEM) && !defined(NO_RSA) + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(HAVE_PKCS7) STACK_OF(X509)* sk = NULL; STACK_OF(X509_INFO)* info_sk = NULL; PKCS7 *p7 = NULL; @@ -27712,7 +27728,7 @@ static void test_wolfSSL_PKCS7_certs(void) printf(resultFmt, passed); #endif /* defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ - !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(HAVE_PKCS7) */ } static void test_wolfSSL_X509_STORE_CTX(void) @@ -29434,7 +29450,9 @@ static void test_wolfSSL_X509(void) AssertNotNull(bio = BIO_new(BIO_s_mem())); +#ifdef WOLFSSL_CERT_GEN AssertIntEQ(i2d_X509_bio(bio, x509), SSL_SUCCESS); +#endif AssertNotNull(ctx = X509_STORE_CTX_new()); @@ -31228,6 +31246,7 @@ static void test_wolfSSL_BIO_write(void) char msg[] = "conversion test"; char out[40]; char expected[] = "Y29udmVyc2lvbiB0ZXN0AA==\n"; + void* bufPtr = NULL; BUF_MEM* buf = NULL; printf(testingFmt, "wolfSSL_BIO_write()"); @@ -31243,6 +31262,8 @@ static void test_wolfSSL_BIO_write(void) AssertIntEQ(SSL_SUCCESS, (int)BIO_get_mem_ptr(bio, &buf)); AssertNotNull(buf); AssertIntEQ(buf->length, 25); + AssertIntEQ(BIO_get_mem_data(bio, &bufPtr), 25); + AssertPtrEq(buf->data, bufPtr); AssertNotNull(ptr = BIO_find_type(bio, BIO_TYPE_MEM)); sz = sizeof(out); @@ -33444,12 +33465,15 @@ static void test_wolfSSL_get_ciphers_compat(void) static void test_wolfSSL_X509_PUBKEY_get(void) { - WOLFSSL_X509_PUBKEY pubkey = {0}; + WOLFSSL_X509_PUBKEY pubkey; WOLFSSL_X509_PUBKEY* key; - WOLFSSL_EVP_PKEY evpkey = {0}; + WOLFSSL_EVP_PKEY evpkey ; WOLFSSL_EVP_PKEY* evpPkey; WOLFSSL_EVP_PKEY* retEvpPkey; + XMEMSET(&pubkey, 0, sizeof(WOLFSSL_X509_PUBKEY)); + XMEMSET(&evpkey, 0, sizeof(WOLFSSL_EVP_PKEY)); + key = &pubkey; evpPkey = &evpkey; @@ -38158,7 +38182,7 @@ static void test_wolfSSL_X509_CRL(void) static void test_wolfSSL_d2i_X509_REQ(void) { -#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) +#if defined(WOLFSSL_CERT_REQ) && (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) /* ./certs/csr.signed.der and ./certs/csr.attr.der were * generated by libest * ./certs/csr.attr.der contains sample attributes */ @@ -38170,7 +38194,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) * -outform PEM * with the passphrase "wolfSSL" */ -#ifndef NO_DSA +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) const char* csrDsaFile = "./certs/csr.dsa.pem"; #endif BIO* bio = NULL; @@ -38229,7 +38253,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) BIO_free(bio); EVP_PKEY_free(pub_key); } -#ifndef NO_DSA +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) { AssertNotNull(bio = BIO_new_file(csrDsaFile, "rb")); AssertNotNull(PEM_read_bio_X509_REQ(bio, &req, NULL, NULL)); @@ -38248,8 +38272,8 @@ static void test_wolfSSL_d2i_X509_REQ(void) BIO_free(bio); EVP_PKEY_free(pub_key); } -#endif -#endif /* defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) */ +#endif /* !NO_DSA && !HAVE_SELFTEST */ +#endif /* WOLFSSL_CERT_REQ && (OPENSSL_ALL || OPENSSL_EXTRA) */ } static void test_wolfSSL_PEM_read_X509(void) @@ -39012,7 +39036,6 @@ static void test_wolfSSL_X509_print() #ifdef OPENSSL_ALL const X509_ALGOR *cert_sig_alg; #endif - int stdout_fd = fileno(stdout); printf(testingFmt, "wolfSSL_X509_print"); x509 = X509_load_certificate_file(svrCertFile, WOLFSSL_FILETYPE_PEM); @@ -39029,7 +39052,7 @@ static void test_wolfSSL_X509_print() #endif BIO_free(bio); - AssertNotNull(bio = BIO_new_fd(stdout_fd, BIO_NOCLOSE)); + AssertNotNull(bio = BIO_new_fd(STDOUT_FILENO, BIO_NOCLOSE)); #ifdef OPENSSL_ALL /* Print signature */ @@ -39055,11 +39078,10 @@ static void test_wolfSSL_RSA_print() !defined(HAVE_FAST_RSA) && !defined(NO_BIO) BIO *bio; WOLFSSL_RSA* rsa = NULL; - int stdout_fd = fileno(stdout); printf(testingFmt, "wolfSSL_RSA_print"); AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); - AssertNotNull(bio = wolfSSL_BIO_new_fd(stdout_fd, BIO_NOCLOSE)); + AssertNotNull(bio = BIO_new_fd(STDOUT_FILENO, BIO_NOCLOSE)); AssertIntEQ(RSA_print(bio, rsa, 0), SSL_SUCCESS); BIO_free(bio); @@ -39145,60 +39167,60 @@ static void test_wolfSSL_ASN1_STRING_print(void){ static void test_wolfSSL_ASN1_get_object(void) { -#ifdef OPENSSL_EXTRA +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) const unsigned char* derBuf = cliecc_cert_der_256; int len = sizeof_cliecc_cert_der_256; long asnLen = 0; - int tag = 0, class = 0; + int tag = 0, cls = 0; ASN1_OBJECT *a; printf(testingFmt, "wolfSSL_ASN1_get_object()"); /* Read a couple TLV triplets and make sure they match the expected values */ - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, len) & 0x80, 0); + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len) & 0x80, 0); AssertIntEQ(asnLen, 863); AssertIntEQ(tag, 0x10); - AssertIntEQ(class, 0); + AssertIntEQ(cls, 0); - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 772); AssertIntEQ(tag, 0x10); - AssertIntEQ(class, 0); + AssertIntEQ(cls, 0); - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 3); AssertIntEQ(tag, 0); - AssertIntEQ(class, 0x80); + AssertIntEQ(cls, 0x80); - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 1); AssertIntEQ(tag, 0x2); - AssertIntEQ(class, 0); + AssertIntEQ(cls, 0); derBuf += asnLen; - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 20); AssertIntEQ(tag, 0x2); - AssertIntEQ(class, 0); + AssertIntEQ(cls, 0); derBuf += asnLen; - AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &class, + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); AssertIntEQ(asnLen, 10); AssertIntEQ(tag, 0x10); - AssertIntEQ(class, 0); + AssertIntEQ(cls, 0); /* Read an ASN OBJECT */ AssertNotNull(d2i_ASN1_OBJECT(&a, &derBuf, len)); ASN1_OBJECT_free(a); printf(resultFmt, passed); -#endif /* OPENSSL_EXTRA */ +#endif /* OPENSSL_EXTRA && HAVE_ECC && USE_CERT_BUFFERS_256 */ } static void test_wolfSSL_RSA_verify() diff --git a/tests/include.am b/tests/include.am index 6e763c9ee..17443dcf1 100644 --- a/tests/include.am +++ b/tests/include.am @@ -50,5 +50,7 @@ EXTRA_DIST += tests/test.conf \ tests/test-trustpeer.conf \ tests/test-dhprime.conf \ tests/test-p521.conf \ - tests/test-ecc-cust-curves.conf + tests/test-ecc-cust-curves.conf \ + tests/NCONF_test.cnf \ + tests/TXT_DB.txt DISTCLEANFILES+= tests/.libs/unit.test diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 05187a93e..9213d6821 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7029,7 +7029,7 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST); sigCtx->digest = NULL; } -#if !defined(NO_RSA) && !defined(NO_DSA) +#if !(defined(NO_RSA) && defined(NO_DSA)) if (sigCtx->sigCpy) { XFREE(sigCtx->sigCpy, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE); sigCtx->sigCpy = NULL; @@ -7265,7 +7265,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* !NO_RSA */ - #ifndef NO_DSA + #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) case DSAk: { word32 idx = 0; @@ -7317,7 +7317,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, } break; } - #endif /* !NO_DSA */ + #endif /* !NO_DSA && !HAVE_SELFTEST */ #ifdef HAVE_ECC case ECDSAk: { @@ -7458,14 +7458,14 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* !NO_RSA */ - #ifndef NO_DSA + #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) case DSAk: { ret = wc_DsaVerify(sigCtx->digest, sigCtx->sigCpy, sigCtx->key.dsa, &sigCtx->verify); break; } - #endif /* !NO_DSA */ + #endif /* !NO_DSA && !HAVE_SELFTEST */ #if defined(HAVE_ECC) case ECDSAk: { @@ -7564,7 +7564,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* NO_RSA */ - #ifndef NO_DSA + #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) case DSAk: { if (sigCtx->verify == 1) { @@ -7576,7 +7576,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, } break; } - #endif /* !NO_DSA */ + #endif /* !NO_DSA && !HAVE_SELFTEST */ #ifdef HAVE_ECC case ECDSAk: { @@ -13497,7 +13497,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, } #endif -#ifndef NO_DSA +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) if (cert->keyType == DSA_KEY) { if (dsaKey == NULL) return PUBLIC_KEY_E; @@ -14246,7 +14246,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, } #endif -#ifndef NO_DSA +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) if (cert->keyType == DSA_KEY) { if (dsaKey == NULL) return PUBLIC_KEY_E; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 473b692e6..6ef7214ca 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1377,9 +1377,12 @@ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e) if (pkey) { pkey->type = id; ctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e); - if (ctx == NULL) { - wolfSSL_EVP_PKEY_free(pkey); - } + /* wolfSSL_EVP_PKEY_CTX_new calls wolfSSL_EVP_PKEY_up_ref so we need + * to always call wolfSSL_EVP_PKEY_free (either to free it if an + * error occured in the previous function or to decrease the reference + * count so that pkey is actually free'd when wolfSSL_EVP_PKEY_CTX_free + * is called) */ + wolfSSL_EVP_PKEY_free(pkey); } return ctx; } @@ -1955,8 +1958,9 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, WOLFSSL_MSG("Copy parameters not available for this key type"); return WOLFSSL_FAILURE; } - +#if defined(HAVE_ECC) || !defined(NO_DSA) return WOLFSSL_SUCCESS; +#endif } #ifndef NO_WOLFSSL_STUB @@ -3260,7 +3264,7 @@ const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) const struct s_ent *ent; for (i = 0; i < sizeof(nameUpper) && name[i] != '\0'; i++) { - nameUpper[i] = XTOUPPER(name[i]); + nameUpper[i] = (char)XTOUPPER(name[i]); } if (i < sizeof(nameUpper)) nameUpper[i] = '\0'; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 66d92001d..bb560b1b0 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1261,18 +1261,24 @@ void wc_PKCS7_Free(PKCS7* pkcs7) wc_PKCS7_SignerInfoFree(pkcs7); wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap); + pkcs7->decodedAttrib = NULL; wc_PKCS7_FreeCertSet(pkcs7); #ifdef ASN_BER_TO_DER - if (pkcs7->der != NULL) + if (pkcs7->der != NULL) { XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->der = NULL; + } #endif - if (pkcs7->contentDynamic != NULL) + if (pkcs7->contentDynamic != NULL) { XFREE(pkcs7->contentDynamic, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->contentDynamic = NULL; + } if (pkcs7->cek != NULL) { ForceZero(pkcs7->cek, pkcs7->cekSz); XFREE(pkcs7->cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->cek = NULL; } pkcs7->contentTypeSz = 0; @@ -4909,6 +4915,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, } #ifdef ASN_BER_TO_DER der = pkcs7->der; + pkcs7->der = NULL; #endif contentDynamic = pkcs7->contentDynamic; version = pkcs7->version; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 726c41f7b..58e24fb6c 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1252,11 +1252,6 @@ static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock, m += inputLen; o = 0; if (saltLen > 0) { - if (pkcsBlockLen < RSA_PSS_PAD_SZ + inputLen + saltLen) { - WOLFSSL_MSG("RSA-PSS Output buffer too short. " - "Recommend using WOLFSSL_PSS_SALT_LEN_DISCOVER"); - return PSS_SALTLEN_E; - } ret = wc_RNG_GenerateBlock(rng, salt, saltLen); if (ret == 0) { XMEMCPY(m, salt, saltLen); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4e0478f68..9657fbae9 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3637,7 +3637,9 @@ struct WOLFSSL_STACK { WOLFSSL_CIPHER cipher; WOLFSSL_ACCESS_DESCRIPTION* access; WOLFSSL_X509_EXTENSION* ext; +#ifdef OPENSSL_EXTRA WOLFSSL_CONF_VALUE* conf; +#endif void* generic; char* string; WOLFSSL_GENERAL_NAME* gn; @@ -3762,8 +3764,10 @@ struct WOLFSSL_X509 { byte authKeyIdSet:1; byte authKeyIdCrit:1; byte issuerSet:1; - byte isCSR:1; #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ +#ifdef WOLFSSL_CERT_REQ + byte isCSR:1; +#endif byte serial[EXTERNAL_SERIAL_SIZE]; char subjectCN[ASN_NAME_MAX]; /* common name short cut */ #ifdef WOLFSSL_CERT_REQ diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 9eea76d9b..8085f0c93 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -99,7 +99,7 @@ WOLFSSL_API WOLFSSL_ASN1_INTEGER *wolfSSL_BN_to_ASN1_INTEGER( WOLFSSL_API void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value); WOLFSSL_API int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, - int *class, long inLen); + int *cls, long inLen); WOLFSSL_API WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, const unsigned char **pp, long len); diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index f7369ec67..0efb2a34e 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -28,7 +28,8 @@ extern "C" { #endif -#include +#include +#include typedef struct WOLFSSL_CONF_VALUE { char *section; @@ -36,9 +37,8 @@ typedef struct WOLFSSL_CONF_VALUE { char *value; } WOLFSSL_CONF_VALUE; -typedef struct WOLFSSL_INIT_SETTINGS { - char* appname; -} WOLFSSL_INIT_SETTINGS; +/* ssl.h requires WOLFSSL_CONF_VALUE */ +#include typedef struct WOLFSSL_CONF { void *meth_data; @@ -47,21 +47,14 @@ typedef struct WOLFSSL_CONF { typedef WOLFSSL_CONF CONF; typedef WOLFSSL_CONF_VALUE CONF_VALUE; -typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; + +#ifdef OPENSSL_EXTRA WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void); WOLFSSL_API int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf, WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value); WOLFSSL_API void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val); -WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc); -WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(struct WOLFSSL_STACK *sk); -WOLFSSL_API int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk); -WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value( - const struct WOLFSSL_STACK *sk, int i); -WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk, - WOLFSSL_CONF_VALUE* val); - WOLFSSL_API WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth); WOLFSSL_API char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf, const char *group, const char *name); @@ -102,6 +95,8 @@ WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, #define X509V3_conf_free wolfSSL_X509V3_conf_free +#endif /* OPENSSL_EXTRA */ + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 4c1e9b024..640ee386f 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -33,6 +33,11 @@ #include "prefix_crypto.h" #endif +typedef struct WOLFSSL_INIT_SETTINGS { + char* appname; +} WOLFSSL_INIT_SETTINGS; + +typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; WOLFSSL_API const char* wolfSSLeay_version(int type); WOLFSSL_API unsigned long wolfSSLeay(void); diff --git a/wolfssl/openssl/stack.h b/wolfssl/openssl/stack.h index c13d715b9..559a79670 100644 --- a/wolfssl/openssl/stack.h +++ b/wolfssl/openssl/stack.h @@ -28,8 +28,6 @@ extern "C" { #endif -#include - typedef void (*wolfSSL_sk_freefunc)(void *); WOLFSSL_API void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, wolfSSL_sk_freefunc); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 40e4dda5a..b1d3b829e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -188,7 +188,6 @@ typedef struct WOLFSSL_X509_VERIFY_PARAM WOLFSSL_X509_VERIFY_PARAM; typedef struct WOLFSSL_BIO WOLFSSL_BIO; typedef struct WOLFSSL_BIO_METHOD WOLFSSL_BIO_METHOD; typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION; -typedef struct WOLFSSL_CONF_VALUE WOLFSSL_CONF_VALUE; typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; @@ -1361,7 +1360,9 @@ WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset #endif WOLFSSL_API int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, unsigned long nmflags, unsigned long cflag); +#ifndef NO_FILESYSTEM WOLFSSL_API int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509); +#endif WOLFSSL_API int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp, const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig); WOLFSSL_API void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig, @@ -3459,8 +3460,6 @@ WOLFSSL_API int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, unsigned char* out, int outSz); WOLFSSL_API int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses); -WOLFSSL_LOCAL int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, - unsigned char* der, int* derSz, int includeSig); WOLFSSL_API int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); #ifdef WOLFSSL_CERT_REQ WOLFSSL_API int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); @@ -3706,8 +3705,18 @@ WOLFSSL_API int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJE WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int, unsigned long); +#ifndef NO_FILESYSTEM WOLFSSL_API int wolfSSL_X509_NAME_print_ex_fp(XFILE,WOLFSSL_X509_NAME*,int, unsigned long); +#endif + +WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc); +WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(struct WOLFSSL_STACK *sk); +WOLFSSL_API int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk); +WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value( + const struct WOLFSSL_STACK *sk, int i); +WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk, + WOLFSSL_CONF_VALUE* val); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || HAVE_LIGHTY */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 8f0c4e91c..7148e1d24 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -650,10 +650,13 @@ decouple library dependencies with standard string, memory and so on. #include #endif #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \ - defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA) + defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA) || \ + defined(OPENSSL_EXTRA) #define XTOUPPER(c) toupper((c)) #endif + #ifdef OPENSSL_ALL #define XISALNUM(c) isalnum((c)) + #endif /* needed by wolfSSL_check_domain_name() */ #define XTOLOWER(c) tolower((c)) #endif From 2dd28ec5b3be1e81d4002c9cf450e13749e04f87 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 10 Dec 2020 15:41:12 +0100 Subject: [PATCH 44/53] Check if downgrading is allowed in SetSSL_CTX Pkcs7 cert limit based on build --- src/internal.c | 20 ++++++++++++++++++++ wolfssl/internal.h | 5 +++++ wolfssl/wolfcrypt/pkcs7.h | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/src/internal.c b/src/internal.c index 271352518..5b46a1661 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5273,22 +5273,42 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef OPENSSL_EXTRA if (ssl->version.minor == TLSv1_3_MINOR && (ssl->options.mask & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) { + if (!ctx->method->downgrade) { + WOLFSSL_MSG("\tInconsistent protocol options. TLS 1.3 set but not " + "allowed and downgrading disabled."); + return VERSION_ERROR; + } WOLFSSL_MSG("\tOption set to not allow TLSv1.3, Downgrading"); ssl->version.minor = TLSv1_2_MINOR; } if (ssl->version.minor == TLSv1_2_MINOR && (ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) { + if (!ctx->method->downgrade) { + WOLFSSL_MSG("\tInconsistent protocol options. TLS 1.2 set but not " + "allowed and downgrading disabled."); + return VERSION_ERROR; + } WOLFSSL_MSG("\tOption set to not allow TLSv1.2, Downgrading"); ssl->version.minor = TLSv1_1_MINOR; } if (ssl->version.minor == TLSv1_1_MINOR && (ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) { + if (!ctx->method->downgrade) { + WOLFSSL_MSG("\tInconsistent protocol options. TLS 1.1 set but not " + "allowed and downgrading disabled."); + return VERSION_ERROR; + } WOLFSSL_MSG("\tOption set to not allow TLSv1.1, Downgrading"); ssl->options.tls1_1 = 0; ssl->version.minor = TLSv1_MINOR; } if (ssl->version.minor == TLSv1_MINOR && (ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) { + if (!ctx->method->downgrade) { + WOLFSSL_MSG("\tInconsistent protocol options. TLS 1 set but not " + "allowed and downgrading disabled."); + return VERSION_ERROR; + } WOLFSSL_MSG("\tOption set to not allow TLSv1, Downgrading"); ssl->options.tls = 0; ssl->options.tls1_1 = 0; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 9657fbae9..0099f9b0b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4306,6 +4306,11 @@ struct WOLFSSL { StaticKeyExchangeInfo_t staticKE; #endif #ifdef OPENSSL_ALL + /* Added in libest port: allow applications to get the 'tls-unique' Channel + * Binding Type (https://tools.ietf.org/html/rfc5929#section-3). This is + * used in the EST protocol to bind an enrollment to a TLS session through + * 'proof-of-possession' (https://tools.ietf.org/html/rfc7030#section-3.4 + * and https://tools.ietf.org/html/rfc7030#section-3.5). */ byte clientFinished[TLS_FINISHED_SZ]; byte serverFinished[TLS_FINISHED_SZ]; #endif diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 31a4fc12d..537856114 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -48,7 +48,11 @@ /* Max number of certificates that PKCS7 structure can parse */ #ifndef MAX_PKCS7_CERTS +#ifdef OPENSSL_ALL #define MAX_PKCS7_CERTS 15 +#else + #define MAX_PKCS7_CERTS 4 +#endif #endif #ifndef MAX_ORI_TYPE_SZ From 22ae66dfe1adc5c1a128a856919f5f79d20dc0a3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 11 Dec 2020 13:28:23 +0100 Subject: [PATCH 45/53] wolfSSL_BIO_do_connect should look for a socket bio in the chain --- src/ssl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index ff6fa8d13..a9caa7bcc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15734,6 +15734,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return WOLFSSL_FAILURE; } + while (b && b->type != WOLFSSL_BIO_SOCKET) + b = b->next; + + if (!b) { + WOLFSSL_ENTER("No socket BIO in chain"); + return WOLFSSL_FAILURE; + } + if (wolfIO_TcpConnect(&sfd, b->ip, b->port, 0) < 0 ) { WOLFSSL_ENTER("wolfIO_TcpConnect error"); return WOLFSSL_FAILURE; From 8b9f8029a8c045aa119b855b4edd827934e6a3da Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 11 Dec 2020 14:34:54 +0100 Subject: [PATCH 46/53] Sanity check protocol version. --- src/ssl.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index a9caa7bcc..551b48506 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16228,12 +16228,25 @@ int wolfSSL_get_server_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey) #endif /* !NO_WOLFSSL_SERVER */ +static int sanityCheckProtoVersion(WOLFSSL_CTX* ctx) +{ + if ((ctx->mask & WOLFSSL_OP_NO_SSLv3) && + (ctx->mask & WOLFSSL_OP_NO_TLSv1) && + (ctx->mask & WOLFSSL_OP_NO_TLSv1_1) && + (ctx->mask & WOLFSSL_OP_NO_TLSv1_2) && + (ctx->mask & WOLFSSL_OP_NO_TLSv1_3)) { + WOLFSSL_MSG("All TLS versions disabled"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; +} + int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) { WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version"); if (ctx == NULL) { - return BAD_FUNC_ARG; + return WOLFSSL_FAILURE; } switch (version) { @@ -16275,7 +16288,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) break; #endif default: - return BAD_FUNC_ARG; + return WOLFSSL_FAILURE; } switch (version) { @@ -16313,7 +16326,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) return WOLFSSL_FAILURE; } - return WOLFSSL_SUCCESS; + return sanityCheckProtoVersion(ctx); } int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) @@ -16358,7 +16371,7 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) return WOLFSSL_FAILURE; } - return WOLFSSL_SUCCESS; + return sanityCheckProtoVersion(ctx); } #endif /* OPENSSL_EXTRA */ From 3231cfe9e0c721e67ec1055122d5bda880b70960 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 11 Dec 2020 19:30:55 +0100 Subject: [PATCH 47/53] Refactor extension stack generation --- configure.ac | 4 ++- src/ssl.c | 71 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 20704a3a2..5d1f382f3 100644 --- a/configure.ac +++ b/configure.ac @@ -857,7 +857,7 @@ fi if test "$ENABLED_OPENSSLALL" = "yes" then -AM_CFLAGS="-DOPENSSL_ALL -DWOLFSSL_EITHER_SIDE -DWC_RSA_NO_PADDING -DWC_RSA_PSS $AM_CFLAGS" +AM_CFLAGS="-DOPENSSL_ALL -DWOLFSSL_EITHER_SIDE -DWC_RSA_NO_PADDING -DWC_RSA_PSS -DWOLFSSL_PSS_LONG_SALT $AM_CFLAGS" fi # OPENSSL Extra Compatibility @@ -4259,6 +4259,8 @@ then ENABLED_OPENSSLALL="yes" ENABLED_OPENSSLEXTRA="yes" AM_CFLAGS="-DOPENSSL_EXTRA -DOPENSSL_ALL $AM_CFLAGS" + AM_CFLAGS="-DWOLFSSL_EITHER_SIDE -DWC_RSA_NO_PADDING $AM_CFLAGS" + AM_CFLAGS="-DWC_RSA_PSS -DWOLFSSL_PSS_LONG_SALT $AM_CFLAGS" fi # Requires OCSP diff --git a/src/ssl.c b/src/ssl.c index 551b48506..25fded2e2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8267,15 +8267,42 @@ int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos, return WOLFSSL_SUCCESS; } +static WOLFSSL_STACK* generateExtStack(const WOLFSSL_X509 *x) +{ + int numOfExt, i; + WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x; + WOLFSSL_STACK* ret; + WOLFSSL_STACK* tmp; + + if (!x509) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + /* Save x509->ext_sk */ + tmp = x509->ext_sk; + x509->ext_sk = NULL; + numOfExt = wolfSSL_X509_get_ext_count(x509); + + for (i = 0; i < numOfExt; i++) { + /* Build the extension stack */ + (void)wolfSSL_X509_set_ext(x509, i); + } + + /* Restore */ + ret = x509->ext_sk; + x509->ext_sk = tmp; + return ret; +} + /** * @param x Certificate to extract extensions from * @return STACK_OF(X509_EXTENSION)* */ const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x) { - int numOfExt, i; + int numOfExt; WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x; - WOLFSSL_STACK* tmp; WOLFSSL_ENTER("wolfSSL_X509_get0_extensions"); if (!x509) { @@ -8287,19 +8314,7 @@ const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x) if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) { wolfSSL_sk_free(x509->ext_sk_full); - x509->ext_sk_full = NULL; - /* Save x509->ext_sk */ - tmp = x509->ext_sk; - x509->ext_sk = NULL; - - for (i = 0; i < numOfExt; i++) { - /* Build the extension stack */ - (void)wolfSSL_X509_set_ext(x509, i); - } - - /* Restore */ - x509->ext_sk_full = x509->ext_sk; - x509->ext_sk = tmp; + x509->ext_sk_full = generateExtStack(x); } return x509->ext_sk_full; @@ -8310,10 +8325,7 @@ const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x) */ const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x) { - const WOLFSSL_STACK *ret = wolfSSL_X509_get0_extensions(x); - if (x) - ((WOLFSSL_X509*)x)->ext_sk_full = NULL; - return ret; + return generateExtStack(x); } /* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509. @@ -25364,7 +25376,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) /* Use the public key to verify the signature. Note: this only verifies * the certificate signature. * returns WOLFSSL_SUCCESS on successful signature verification */ -static int wolfSSL_X509_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req) +static int verify_X509_or_X509_REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req) { int ret; const byte* der; @@ -25417,13 +25429,13 @@ static int wolfSSL_X509_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pk int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) { - return wolfSSL_X509_X509_REQ_verify(x509, pkey, 0); + return verify_X509_or_X509_REQ(x509, pkey, 0); } #ifdef WOLFSSL_CERT_REQ int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) { - return wolfSSL_X509_X509_REQ_verify(x509, pkey, 1); + return verify_X509_or_X509_REQ(x509, pkey, 1); } #endif /* WOLFSSL_CERT_REQ */ #endif /* !NO_CERTS */ @@ -40351,7 +40363,7 @@ cleanup: } #ifndef NO_BIO - static WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_X509_REQ(WOLFSSL_BIO *bp, + static WOLFSSL_X509 *PEM_read_bio_X509_or_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u, int type) { WOLFSSL_X509* x509 = NULL; @@ -40361,7 +40373,7 @@ cleanup: long i = 0, l, footerSz; const char* footer = NULL; - WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509"); + WOLFSSL_ENTER("PEM_read_bio_X509_or_X509_REQ"); if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) { WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG); @@ -40439,14 +40451,14 @@ cleanup: WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { - return wolfSSL_PEM_read_bio_X509_X509_REQ(bp, x, cb, u, CERT_TYPE); + return PEM_read_bio_X509_or_X509_REQ(bp, x, cb, u, CERT_TYPE); } #ifdef WOLFSSL_CERT_REQ WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { - return wolfSSL_PEM_read_bio_X509_X509_REQ(bp, x, cb, u, CERTREQ_TYPE); + return PEM_read_bio_X509_or_X509_REQ(bp, x, cb, u, CERTREQ_TYPE); } #endif @@ -52025,6 +52037,7 @@ int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, { WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt"); +#ifdef HAVE_LIBEST if (!req || !attrname || !bytes || type != MBSTRING_ASC) { WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; @@ -52052,9 +52065,13 @@ int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, } /* return error if not built for libest */ -#ifdef HAVE_LIBEST return WOLFSSL_SUCCESS; #else + (void)req; + (void)attrname; + (void)type; + (void)bytes; + (void)len; return WOLFSSL_FAILURE; #endif } From 24b89928dc956fb4bc2cecdec6c02058b5cc81c3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 14 Dec 2020 13:35:34 +0100 Subject: [PATCH 48/53] Code review names changes and refactoring --- src/ssl.c | 108 ++++++++++++++++++++++------------------- wolfssl/openssl/conf.h | 2 + wolfssl/ssl.h | 1 + 3 files changed, 62 insertions(+), 49 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 25fded2e2..c14dac55f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18300,7 +18300,7 @@ WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in, return newX509; } -static WOLFSSL_X509* wolfSSL_X509_X509_REQ_d2i(WOLFSSL_X509** x509, +static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509, const byte* in, int len, int req) { WOLFSSL_X509 *newX509 = NULL; @@ -18369,14 +18369,14 @@ int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509) WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) { - return wolfSSL_X509_X509_REQ_d2i(x509, in, len, 0); + return d2i_X509orX509REQ(x509, in, len, 0); } #ifdef WOLFSSL_CERT_REQ WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len) { - return wolfSSL_X509_X509_REQ_d2i(x509, in, len, 1); + return d2i_X509orX509REQ(x509, in, len, 1); } #endif #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA || @@ -19495,13 +19495,13 @@ static unsigned long wolfSSL_CONF_VALUE_hash(const WOLFSSL_CONF_VALUE *val) return 0; } -static int wolfSSL_CONF_VALUE_cmp(const WOLFSSL_CONF_VALUE *a, +static int wolfssl_conf_value_cmp(const WOLFSSL_CONF_VALUE *a, const WOLFSSL_CONF_VALUE *b) { int cmp_val; if (!a || !b) { - return -1; + return WOLFSSL_FATAL_ERROR; } if (a->section != b->section) { @@ -20156,7 +20156,7 @@ WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc) ret = wolfSSL_sk_new_node(NULL); if (!ret) return NULL; - ret->comp = compFunc ? compFunc : (wolf_sk_compare_cb)wolfSSL_CONF_VALUE_cmp; + ret->comp = compFunc ? compFunc : (wolf_sk_compare_cb)wolfssl_conf_value_cmp; ret->hash_fn = (wolf_sk_hash_cb)wolfSSL_CONF_VALUE_hash; ret->type = STACK_TYPE_CONF_VALUE; return ret; @@ -20666,7 +20666,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) } #endif /* !NO_FILESYSTEM */ -static WOLFSSL_X509* wolfSSL_X509_X509_REQ_load_certificate_buffer( +static WOLFSSL_X509* loadX509orX509REQFromBuffer( const unsigned char* buf, int sz, int format, int type) { @@ -20735,7 +20735,7 @@ static WOLFSSL_X509* wolfSSL_X509_X509_REQ_load_certificate_buffer( WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( const unsigned char* buf, int sz, int format) { - return wolfSSL_X509_X509_REQ_load_certificate_buffer(buf, sz, + return loadX509orX509REQFromBuffer(buf, sz, format, CERT_TYPE); } @@ -20743,7 +20743,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer( const unsigned char* buf, int sz, int format) { - return wolfSSL_X509_X509_REQ_load_certificate_buffer(buf, sz, + return loadX509orX509REQFromBuffer(buf, sz, format, CERTREQ_TYPE); } #endif @@ -24258,7 +24258,7 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, } #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) -static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, +static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req, unsigned char* der, int* derSz, int includeSig); #endif @@ -24273,15 +24273,15 @@ static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, * * returns WOLFSSL_SUCCESS on success */ -static int wolfSSL_i2d_X509_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req) +static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req) { int ret = WOLFSSL_FAILURE; /* Get large buffer to hold cert der */ - int derSz = 8192; + int derSz = X509_BUFFER_SZ; #ifdef WOLFSSL_SMALL_STACK byte* der; #else - byte der[8192]; + byte der[X509_BUFFER_SZ]; #endif WOLFSSL_ENTER("wolfSSL_i2d_X509_bio"); @@ -24297,7 +24297,7 @@ static int wolfSSL_i2d_X509_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, i } #endif - if (wolfSSL_X509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) { + if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) { goto cleanup; } @@ -24324,13 +24324,13 @@ cleanup: */ int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) { - return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 0); + return loadX509orX509REQFromBio(bio, x509, 0); } #ifdef WOLFSSL_CERT_REQ int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) { - return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 1); + return loadX509orX509REQFromBio(bio, x509, 1); } #endif /* WOLFSSL_CERT_REQ */ #endif /* WOLFSSL_CERT_GEN */ @@ -24384,7 +24384,7 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out) * @param req 1 for a CSR and 0 for a x509 cert * @return pointer to WOLFSSL_X509 structure on success and NULL on fail */ -static WOLFSSL_X509* wolfSSL_d2i_X509_X509_REQ_bio(WOLFSSL_BIO* bio, +static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509, int req) { WOLFSSL_X509* localX509 = NULL; @@ -24442,13 +24442,13 @@ static WOLFSSL_X509* wolfSSL_d2i_X509_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) { - return wolfSSL_d2i_X509_X509_REQ_bio(bio, x509, 0); + return d2i_X509orX509REQ_bio(bio, x509, 0); } #ifdef WOLFSSL_CERT_REQ WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) { - return wolfSSL_d2i_X509_X509_REQ_bio(bio, x509, 1); + return d2i_X509orX509REQ_bio(bio, x509, 1); } #endif @@ -25376,7 +25376,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) /* Use the public key to verify the signature. Note: this only verifies * the certificate signature. * returns WOLFSSL_SUCCESS on successful signature verification */ -static int verify_X509_or_X509_REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req) +static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req) { int ret; const byte* der; @@ -25429,13 +25429,13 @@ static int verify_X509_or_X509_REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, i int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) { - return verify_X509_or_X509_REQ(x509, pkey, 0); + return verifyX509orX509REQ(x509, pkey, 0); } #ifdef WOLFSSL_CERT_REQ int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) { - return verify_X509_or_X509_REQ(x509, pkey, 1); + return verifyX509orX509REQ(x509, pkey, 1); } #endif /* WOLFSSL_CERT_REQ */ #endif /* !NO_CERTS */ @@ -39942,7 +39942,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) * updates derSz with certificate body size on success * return WOLFSSL_SUCCESS on success */ - static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req, + static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req, unsigned char* der, int* derSz, int includeSig) { int ret = WOLFSSL_FAILURE; @@ -40243,7 +40243,7 @@ cleanup: } x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey); - if ((ret = wolfSSL_X509_make_der(x509, 0, der, &derSz, 0)) != + if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Unable to make DER for X509"); WOLFSSL_LEAVE("wolfSSL_X509_sign", ret); @@ -40363,7 +40363,8 @@ cleanup: } #ifndef NO_BIO - static WOLFSSL_X509 *PEM_read_bio_X509_or_X509_REQ(WOLFSSL_BIO *bp, + + static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u, int type) { WOLFSSL_X509* x509 = NULL; @@ -40373,7 +40374,7 @@ cleanup: long i = 0, l, footerSz; const char* footer = NULL; - WOLFSSL_ENTER("PEM_read_bio_X509_or_X509_REQ"); + WOLFSSL_ENTER("loadX509orX509REQFromPemBio"); if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) { WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG); @@ -40451,14 +40452,14 @@ cleanup: WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { - return PEM_read_bio_X509_or_X509_REQ(bp, x, cb, u, CERT_TYPE); + return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE); } #ifdef WOLFSSL_CERT_REQ WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { - return PEM_read_bio_X509_or_X509_REQ(bp, x, cb, u, CERTREQ_TYPE); + return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE); } #endif @@ -43703,11 +43704,11 @@ int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert) byte* pem = NULL; int pemSz = 0; /* Get large buffer to hold cert der */ - int derSz = 8192; + int derSz = X509_BUFFER_SZ; #ifdef WOLFSSL_SMALL_STACK byte* der; #else - byte der[8192]; + byte der[X509_BUFFER_SZ]; #endif int ret; @@ -43726,7 +43727,7 @@ int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert) } #endif - if (wolfSSL_X509_make_der(cert, 0, der, &derSz, 1) != WOLFSSL_SUCCESS) { + if (wolfssl_x509_make_der(cert, 0, der, &derSz, 1) != WOLFSSL_SUCCESS) { goto error; } @@ -51963,7 +51964,7 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, /* Create a Cert that has the certificate request fields. */ req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey); - if (wolfSSL_X509_make_der(req, 1, der, &derSz, 0) != WOLFSSL_SUCCESS) { + if (wolfssl_x509_make_der(req, 1, der, &derSz, 0) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -51984,29 +51985,38 @@ int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, return WOLFSSL_FAILURE; } -static int wolfSSL_regen_X509_REQ_der_buffer(WOLFSSL_X509* x509) +static int regenX509REQDerBuffer(WOLFSSL_X509* x509) { - byte der[4096]; - int derSz = sizeof(der); - - if (wolfSSL_X509_make_der(x509, 1, der, &derSz, 0) != - WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Unable to make DER for X509 REQ"); + int derSz = X509_BUFFER_SZ; + int ret = WOLFSSL_FAILURE; +#ifdef WOLFSSL_SMALL_STACK + byte* der; + der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!der) { + WOLFSSL_MSG("malloc failed"); return WOLFSSL_FAILURE; } +#else + byte der[X509_BUFFER_SZ]; +#endif - FreeDer(&x509->derCert); - - /* store cert for potential retrieval */ - if (AllocDer(&x509->derCert, derSz, CERT_TYPE, x509->heap) == 0) { - XMEMCPY(x509->derCert->buffer, der, derSz); + if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) { + FreeDer(&x509->derCert); + if (AllocDer(&x509->derCert, derSz, CERT_TYPE, x509->heap) == 0) { + XMEMCPY(x509->derCert->buffer, der, derSz); + ret = WOLFSSL_SUCCESS; + } + else { + WOLFSSL_MSG("Failed to allocate DER buffer for X509"); + } } else { - WOLFSSL_MSG("Failed to allocate DER buffer for X509"); - return WOLFSSL_FAILURE; + WOLFSSL_MSG("Unable to make DER for X509 REQ"); } - - return WOLFSSL_SUCCESS; +#ifdef WOLFSSL_SMALL_STACK + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; } int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, @@ -52028,7 +52038,7 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, ext_sk = ext_sk->next; } - return wolfSSL_regen_X509_REQ_der_buffer(req); + return regenX509REQDerBuffer(req); } int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index 0efb2a34e..a56983ef1 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -92,6 +92,8 @@ WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, #define NCONF_load wolfSSL_NCONF_load #define CONF_modules_load wolfSSL_CONF_modules_load +#define _CONF_new_section wolfSSL_CONF_new_section +#define _CONF_get_section wolfSSL_CONF_get_section #define X509V3_conf_free wolfSSL_X509V3_conf_free diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b1d3b829e..de194f612 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3580,6 +3580,7 @@ WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int c); || defined(WOLFSSL_MYSQL_COMPATIBLE) \ || defined(WOLFSSL_HAPROXY) \ || defined(OPENSSL_EXTRA) +#define X509_BUFFER_SZ 8192 WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_file(const char *filename, const char *mode); WOLFSSL_API long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX*, WOLFSSL_DH*); From 383df620bf63ab567a79d8ed2742d1a439ca07a1 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 15 Dec 2020 15:10:44 +0100 Subject: [PATCH 49/53] Add CSR test with Extension Request attribute --- certs/csr.ext.der | Bin 0 -> 566 bytes certs/include.am | 3 ++- tests/api.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 certs/csr.ext.der diff --git a/certs/csr.ext.der b/certs/csr.ext.der new file mode 100644 index 0000000000000000000000000000000000000000..fd39dea6cdd75a5a6c6adb827222a03a72b243d3 GIT binary patch literal 566 zcmXqLVlpylVw}yy$ZQ~DC}beO#vIDR%)^c4d^5jJ z3}{t)x6PDoYfx+V;kw_G=kYI}s}Q3>#M)G_EjcoXW-=Dl5p+*lW<( z)y}d;$b_k#rJjL-u}L5)KPfq}L@znBI5}T0IX|~aAS*LBDL)BGL>L}K2tleCV!#J- z7C$57e-;*ICe{bY!Osl}{zeAQgky`WuW&WLb$={n^l4Am>(#BzZBes>?wks8sCBtG zsUt3#rRsD2yPU0)7MMgIOrIehzLRB^L7CUVsTJwm^Q}0i?O~H(+;`z-^UcR%^LNEG zWQx?ydR??N&PDI$QX7}F!+Vr_Q;dI!Ua|j{cPZ=Yhx3VS`bjm%v%+Vk3G$xwJpus! CGS;U6 literal 0 HcmV?d00001 diff --git a/certs/include.am b/certs/include.am index 7d613b9ef..c7e70ad1a 100644 --- a/certs/include.am +++ b/certs/include.am @@ -55,7 +55,8 @@ EXTRA_DIST += \ certs/client-cert-ext.pem \ certs/csr.attr.der \ certs/csr.dsa.pem \ - certs/csr.signed.der + certs/csr.signed.der \ + certs/csr.ext.der EXTRA_DIST += \ certs/ca-key.der \ diff --git a/tests/api.c b/tests/api.c index 630dce6e3..5e55bdc1d 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38183,11 +38183,13 @@ static void test_wolfSSL_X509_CRL(void) static void test_wolfSSL_d2i_X509_REQ(void) { #if defined(WOLFSSL_CERT_REQ) && (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) - /* ./certs/csr.signed.der and ./certs/csr.attr.der were + /* ./certs/csr.signed.der, ./certs/csr.ext.der, and ./certs/csr.attr.der were * generated by libest - * ./certs/csr.attr.der contains sample attributes */ + * ./certs/csr.attr.der contains sample attributes + * ./certs/csr.ext.der contains sample extensions */ const char* csrFile = "./certs/csr.signed.der"; const char* csrPopFile = "./certs/csr.attr.der"; + const char* csrExtFile = "./certs/csr.ext.der"; /* ./certs/csr.dsa.pem is generated using * openssl req -newkey dsa:certs/dsaparams.pem \ * -keyout certs/csr.dsa.key.pem -keyform PEM -out certs/csr.dsa.pem \ @@ -38249,6 +38251,42 @@ static void test_wolfSSL_d2i_X509_REQ(void) AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "2xIE+qqp/rhyTXP+"); #endif + X509_free(req); + BIO_free(bio); + EVP_PKEY_free(pub_key); + } + { +#ifdef OPENSSL_ALL + X509_ATTRIBUTE* attr; + ASN1_TYPE *at; +#endif + AssertNotNull(bio = BIO_new_file(csrExtFile, "rb")); + /* This CSR contains an Extension Request attribute so + * we test extension parsing in a CSR attribute here. */ + AssertNotNull(d2i_X509_REQ_bio(bio, &req)); + + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + +#ifdef OPENSSL_ALL + /* + * Obtain the challenge password from the CSR + */ + AssertIntEQ(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1), + NID_pkcs9_challengePassword); + AssertNotNull(attr = X509_REQ_get_attr(req, NID_pkcs9_challengePassword)); + AssertNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0)); + AssertNotNull(at->value.asn1_string); + AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo"); +#endif + X509_free(req); BIO_free(bio); EVP_PKEY_free(pub_key); From dc266bc524b723bba38e3714a5e1d94277e886ef Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 15 Dec 2020 16:18:44 +0100 Subject: [PATCH 50/53] Call X509_REQ_get_extensions and X509_get_ext_by_NID on a CSR object --- tests/api.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/api.c b/tests/api.c index 5e55bdc1d..5d1f8f93c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38250,6 +38250,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) AssertNotNull(at->value.asn1_string); AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "2xIE+qqp/rhyTXP+"); #endif + AssertIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1); X509_free(req); BIO_free(bio); @@ -38260,6 +38261,7 @@ static void test_wolfSSL_d2i_X509_REQ(void) X509_ATTRIBUTE* attr; ASN1_TYPE *at; #endif + STACK_OF(X509_EXTENSION) *exts = NULL; AssertNotNull(bio = BIO_new_file(csrExtFile, "rb")); /* This CSR contains an Extension Request attribute so * we test extension parsing in a CSR attribute here. */ @@ -38275,6 +38277,9 @@ static void test_wolfSSL_d2i_X509_REQ(void) */ AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + AssertNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(req)); + AssertIntEQ(sk_X509_EXTENSION_num(exts), 2); + #ifdef OPENSSL_ALL /* * Obtain the challenge password from the CSR @@ -38286,10 +38291,13 @@ static void test_wolfSSL_d2i_X509_REQ(void) AssertNotNull(at->value.asn1_string); AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo"); #endif + AssertIntGE(X509_get_ext_by_NID(req, NID_key_usage, -1), 0); + AssertIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0); X509_free(req); BIO_free(bio); EVP_PKEY_free(pub_key); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) { From c03744db61e6e68a559002ccf47881907cb118fa Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 16 Dec 2020 15:36:01 +0100 Subject: [PATCH 51/53] Refactor wc_CheckPrivateKey - Change wc_CheckPrivateKey to wc_CheckPrivateKeyCert and wc_CheckPrivateKey - wolfSSL_X509_check_private_key no longer needs to decode cert to check key - Fix scope in api.c --- src/ssl.c | 37 ++++++-------------- tests/api.c | 11 +++--- wolfcrypt/src/asn.c | 77 +++++++++++++++++++++++++---------------- wolfcrypt/src/pkcs12.c | 2 +- wolfssl/wolfcrypt/asn.h | 4 ++- 5 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index c14dac55f..84a191d81 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7430,7 +7430,7 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) else #endif { - ret = wc_CheckPrivateKey(buff, size, der); + ret = wc_CheckPrivateKeyCert(buff, size, der); if (ret == 1) { ret = WOLFSSL_SUCCESS; } @@ -8034,7 +8034,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) } else #endif - ret = wc_CheckPrivateKey(buff, size, &der); + ret = wc_CheckPrivateKeyCert(buff, size, &der); FreeDecodedCert(&der); return ret; } @@ -19521,8 +19521,11 @@ static int wolfssl_conf_value_cmp(const WOLFSSL_CONF_VALUE *a, } } -/* Use MD5 for hashing as it is fast and should - * be good enough for database indexing */ +/* Use MD5 for hashing as OpenSSL uses a hash algorithm that is + * "not as good as MD5, but still good" so using MD5 should + * be good enough for this application. The produced hashes don't + * need to line up between OpenSSL and wolfSSL. The hashes are for + * internal indexing only */ unsigned long wolfSSL_LH_strhash(const char *str) { unsigned long ret = 0; @@ -42617,11 +42620,6 @@ err: int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key) { - DecodedCert dc; - byte* der; - int derSz; - int ret; - WOLFSSL_ENTER("wolfSSL_X509_check_private_key"); if (!x509 || !key) { @@ -42629,24 +42627,9 @@ err: return WOLFSSL_FAILURE; } - der = (byte*)wolfSSL_X509_get_der(x509, &derSz); - if (der == NULL) { - WOLFSSL_MSG("wolfSSL_X509_get_der error"); - return WOLFSSL_FAILURE; - } - - InitDecodedCert(&dc, der, derSz, x509->heap); - - if (ParseCertRelative(&dc, CERT_TYPE, NO_VERIFY, NULL) != 0) { - FreeDecodedCert(&dc); - return WOLFSSL_FAILURE; - } - - der = (byte*)key->pkey.ptr; - derSz = key->pkey_sz; - ret = wc_CheckPrivateKey(der, derSz, &dc); - FreeDecodedCert(&dc); - return ret == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz, + x509->pubKey.buffer, x509->pubKey.length, + x509->pubKeyOID) == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } /* wolfSSL uses negative values for error states. This function returns an diff --git a/tests/api.c b/tests/api.c index 5d1f8f93c..5af0d206d 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38249,8 +38249,8 @@ static void test_wolfSSL_d2i_X509_REQ(void) AssertNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0)); AssertNotNull(at->value.asn1_string); AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "2xIE+qqp/rhyTXP+"); -#endif AssertIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1); +#endif X509_free(req); BIO_free(bio); @@ -38260,8 +38260,8 @@ static void test_wolfSSL_d2i_X509_REQ(void) #ifdef OPENSSL_ALL X509_ATTRIBUTE* attr; ASN1_TYPE *at; -#endif STACK_OF(X509_EXTENSION) *exts = NULL; +#endif AssertNotNull(bio = BIO_new_file(csrExtFile, "rb")); /* This CSR contains an Extension Request attribute so * we test extension parsing in a CSR attribute here. */ @@ -38277,10 +38277,10 @@ static void test_wolfSSL_d2i_X509_REQ(void) */ AssertIntEQ(X509_REQ_verify(req, pub_key), 1); +#ifdef OPENSSL_ALL AssertNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(req)); AssertIntEQ(sk_X509_EXTENSION_num(exts), 2); - -#ifdef OPENSSL_ALL + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); /* * Obtain the challenge password from the CSR */ @@ -38290,14 +38290,13 @@ static void test_wolfSSL_d2i_X509_REQ(void) AssertNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0)); AssertNotNull(at->value.asn1_string); AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo"); -#endif AssertIntGE(X509_get_ext_by_NID(req, NID_key_usage, -1), 0); AssertIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0); +#endif X509_free(req); BIO_free(bio); EVP_PKEY_free(pub_key); - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9213d6821..f8cdfcd6a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2904,25 +2904,29 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz, #endif /* HAVE_PKCS8 */ #if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY) -/* check that the private key is a pair for the public key in certificate +/* check that the private key is a pair for the public key * return 1 (true) on match * return 0 or negative value on failure/error * - * key : buffer holding DER format key - * keySz : size of key buffer - * der : a initialized and parsed DecodedCert holding a certificate */ -int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) + * privKey : buffer holding DER format private key + * privKeySz : size of private key buffer + * pubKey : buffer holding DER format public key + * pubKeySz : size of public key buffer + * ks : type of key */ +int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, + const byte* pubKey, word32 pubKeySz, enum Key_Sum ks) { int ret; - (void)keySz; + (void)privKeySz; + (void)pubKeySz; - if (key == NULL || der == NULL) { + if (privKey == NULL || pubKey == NULL) { return BAD_FUNC_ARG; } #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT) /* test if RSA key */ - if (der->keyOID == RSAk) { + if (ks == RSAk) { #ifdef WOLFSSL_SMALL_STACK RsaKey* a; RsaKey* b = NULL; @@ -2957,12 +2961,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #endif return ret; } - if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) { + if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) { WOLFSSL_MSG("Checking RSA key pair"); keyIdx = 0; /* reset to 0 for parsing public key */ - if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b, - der->pubKeySize)) == 0) { + if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b, + pubKeySz)) == 0) { /* limit for user RSA crypto because of RsaKey * dereference. */ #if defined(HAVE_USER_RSA) @@ -2991,7 +2995,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #endif /* !NO_RSA && !NO_ASN_CRYPT */ #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT) - if (der->keyOID == ECDSAk) { + if (ks == ECDSAk) { #ifdef WOLFSSL_SMALL_STACK ecc_key* key_pair; byte* privDer; @@ -3021,8 +3025,8 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) return ret; } - if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair, - keySz)) == 0) { + if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair, + privKeySz)) == 0) { WOLFSSL_MSG("Checking ECC key pair"); if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz)) @@ -3030,9 +3034,9 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) wc_ecc_free(key_pair); ret = wc_ecc_init(key_pair); if (ret == 0) { - ret = wc_ecc_import_private_key((const byte*)privDer, - privSz, (const byte*)der->publicKey, - der->pubKeySize, key_pair); + ret = wc_ecc_import_private_key(privDer, + privSz, pubKey, + pubKeySz, key_pair); } /* public and private extracted successfully now check if is @@ -3056,7 +3060,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */ #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT) - if (der->keyOID == ED25519k) { + if (ks == ED25519k) { #ifdef WOLFSSL_SMALL_STACK ed25519_key* key_pair; #else @@ -3077,12 +3081,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #endif return ret; } - if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair, - keySz)) == 0) { + if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair, + privKeySz)) == 0) { WOLFSSL_MSG("Checking ED25519 key pair"); keyIdx = 0; - if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize, - key_pair)) == 0) { + if ((ret = wc_ed25519_import_public(pubKey, pubKeySz, + key_pair)) == 0) { /* public and private extracted successfully no check if is * a pair and also do sanity checks on key. wc_ecc_check_key * checks that private * base generator equals pubkey */ @@ -3099,7 +3103,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT) - if (der->keyOID == ED448k) { + if (ks == ED448k) { #ifdef WOLFSSL_SMALL_STACK ed448_key* key_pair = NULL; #else @@ -3120,12 +3124,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #endif return ret; } - if ((ret = wc_Ed448PrivateKeyDecode(key, &keyIdx, key_pair, - keySz)) == 0) { + if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair, + privKeySz)) == 0) { WOLFSSL_MSG("Checking ED448 key pair"); keyIdx = 0; - if ((ret = wc_ed448_import_public(der->publicKey, der->pubKeySize, - key_pair)) == 0) { + if ((ret = wc_ed448_import_public(pubKey, pubKeySz, + key_pair)) == 0) { /* public and private extracted successfully no check if is * a pair and also do sanity checks on key. wc_ecc_check_key * checks that private * base generator equals pubkey */ @@ -3144,11 +3148,26 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) ret = 0; } - (void)keySz; - return ret; } +/* check that the private key is a pair for the public key in certificate + * return 1 (true) on match + * return 0 or negative value on failure/error + * + * key : buffer holding DER format key + * keySz : size of key buffer + * der : a initialized and parsed DecodedCert holding a certificate */ +int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der) +{ + if (key == NULL || der == NULL) { + return BAD_FUNC_ARG; + } + + return wc_CheckPrivateKey(key, keySz, der->publicKey, + der->pubKeySize, (enum Key_Sum) der->keyOID); +} + #endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */ #ifndef NO_PWDBASED diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index ca9a4e53e..10bb8b3cc 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -948,7 +948,7 @@ static void freeDecCertList(WC_DerCertList** list, byte** pkey, word32* pkeySz, InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap); if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) { - if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) { + if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, &DeCert) == 1) { WOLFSSL_MSG("Key Pair found"); *cert = current->buffer; *certSz = current->bufferSz; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 7f24efa4f..1537ccc7e 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1197,7 +1197,9 @@ WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx, byte* serial, int* serialSz, word32 maxIdx); WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx); -WOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der); +WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der); +WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, + const byte* pubKey, word32 pubKeySz, enum Key_Sum ks); WOLFSSL_LOCAL int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g); WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*); From f2694134b0cf9d29c68939228f64860e754ce055 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 17 Dec 2020 14:46:07 +0100 Subject: [PATCH 52/53] Fix after rebase --- src/ssl.c | 43 +++++-------------------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 84a191d81..b457913b3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -31310,43 +31310,6 @@ void wolfSSL_DH_free(WOLFSSL_DH* dh) } } -WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) -{ - WOLFSSL_DH* ret = NULL; - - WOLFSSL_ENTER("wolfSSL_DH_dup"); - - if (!dh) { - WOLFSSL_MSG("Bad parameter"); - return NULL; - } - - if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS){ - WOLFSSL_MSG("Bad DH set internal"); - return NULL; - } - - if (!(ret = wolfSSL_DH_new())) { - WOLFSSL_MSG("wolfSSL_DH_new error"); - return NULL; - } - - if (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) != MP_OKAY) { - WOLFSSL_MSG("wc_DhKeyCopy error"); - wolfSSL_DH_free(ret); - return NULL; - } - ret->inSet = 1; - - if (SetDhExternal(ret) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetDhExternal error"); - wolfSSL_DH_free(ret); - return NULL; - } - - return ret; -} - int SetDhInternal(WOLFSSL_DH* dh) { int ret = WOLFSSL_FATAL_ERROR; @@ -31452,6 +31415,8 @@ int SetDhInternal(WOLFSSL_DH* dh) } #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) + +#ifdef WOLFSSL_DH_EXTRA WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) { WOLFSSL_DH* ret = NULL; @@ -31488,6 +31453,7 @@ WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) return ret; } +#endif /* WOLFSSL_DH_EXTRA */ /* Set the members of DhKey into WOLFSSL_DH * DhKey was populated from wc_DhKeyDecode @@ -42629,7 +42595,8 @@ err: return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz, x509->pubKey.buffer, x509->pubKey.length, - x509->pubKeyOID) == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + (enum Key_Sum)x509->pubKeyOID) == 1 ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } /* wolfSSL uses negative values for error states. This function returns an From 6226edb394da0f85c916830fb3b46ecfd8857fd7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 18 Dec 2020 12:48:25 +0100 Subject: [PATCH 53/53] Use CSR with smaller key size 4096 -> 2048 --- certs/csr.attr.der | Bin 1171 -> 761 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/certs/csr.attr.der b/certs/csr.attr.der index bceadd777f6f0b9a776e210024ef1a7d63d45bb3..e8c5baee6187be05aad491024480b879844c1a3c 100644 GIT binary patch delta 704 zcmbQt`IEKYpo!_LK@;O$CPoH>Dno7qPB!LH7B*p~&|pIW13nOki-)~DKPN3X*vC-B zKnNtl&BN_nR9R4xuMm=&m}{tHpa2qO=8^O&EiO?=R0v8<%*m-#aL&)o&CgTtOUz9* zlsAxNsARwkSHsB2%D~*j$j@NV z#K^_e#K_3-X=!!Rrz7XT=ZJo)_T)QWfAhot+XtFbY(LHAS*zd9=JtTKt!dS!o~RS- zdFvMX-BaXrNvu**^jf&G++X<%7lZTlh6@R$_mrwt zKi&HrYBRogoS2pOzsDq~`?lb;9!ZgttGgHzB+u>WjJ+Y^x^${!_^a!dn+h^6)~&bJ zJ{;q?G%G_+P9^m=XDi1_Tft)STxXFFe!Jgmvq|utvV3PdY1+4^p8HbT_ViUQQ+uQ{ zclF{4`F~kE&VOL}yDeY!K-Axsi-z%9+6nL8WEGsgf3e%{e*HW1PZ&3CSfcFI z6!|7QN$uFxl}DC6`l6&`>!@MXv+>-M)>lVz%KfJ~X>E>DTReZoa~@kB=Eb`%mhNNv zZfeh2EBkNJV_)GeDYmN%E;@hyF>^ zoaqOuX5ZUczgT6?)om7=ZroZedRy@DoYVH7{=_mLTW9m&Ymogx@!qKg&z~eM*j-(_ zr&=$%MJ|_rdT&1Wqn?89Tf6!fKUGcZkgY3mvbj6|n~1IAYVoXvuY_f#)#YEf34Ahp x7_PFZyY+;t5tGaI#-)J;KPKxpdj#09FJ0kr`t=#^^*ja0% delta 1117 zcmey#I+?THpoyj5poyuRiIKrT#8AjUfQ>nng;|)>(8yfRK+izW(4dJ)$$*!QQ>)FR z?K>|cBO@yVa}yIkgFzD$7gG}xBf~jcCx4xa71uun_y{|j7%5dhHWeWV8?-bOl`=;pk#iZyz*({RH_)z5c z7k8!Hv1?I`wYfHa_2P8=LG@+*f~J{K;JA{w*(K-GAChY*6`c*?MMv$86@f zqlXx?qZkE$bbW5!FzN38#%Yc+9XAE)>vnE>5fm?bq59r2z7NMWCB>|aFL&(8eQJN9 zZ{|_{q~&XFtbY*ta9+3AgB;KB!dd6vd6n){I{7NtSAx6aMX0A_(%XW&^=v&4Zj_v} zdo5hIfn$Cm)6&@A>o6!> z`eQiZhl`S1ua4WVM=$?Q*?jf?(wF?N=g;X{{yM1TK-cl~Sl{&q?lYo~wtZsx>>`tQ zTP;?1!;zPv^Zc(G=I1B~J-gp}=~~%hxBit~e=n$(w(d6851gV~#Vh|zKfjRIhtIG< za7x3Mzb3{;_ODrvP3_TWZ(yls1-juH644>9s)V8~({F7_}LN zCtqPys%K(kI3|4ID}Usc{kQY)79VWwf8ZHZyTB@P&9_7|`Hiu8l72_+%Fj&Ouk+0D z#|o{S{S1oBT>}ioH@u!MCRi{>n>RGg?z;ZVz|)hT_$(7ud$VAVoSN4AHSzY}-QIgy zHJzMXKKpjQr})SF*Z8J-l}fgG%h7Eu z@KLFG(ng+w4XZsD&W)?@-Y~0d^C^AY2$3yUv^6uVuo zDZWdx^!8`xV~#Xw5tru)4m?IuB@0(9 zO?)pD^*?5cXt;O9bW4dwVVy&5&o@_W_%uWH``<+h#St2vDcveB