From dc7ae37f7a39cde7b38467148ce5a3788adc2e11 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Mon, 26 Jul 2021 10:05:13 -0700 Subject: [PATCH] Make changes to support port of NTP from OpenSSL to wolfSSL. --- certs/dsaparams.der | Bin 0 -> 291 bytes certs/include.am | 1 + configure.ac | 21 +- src/ssl.c | 1011 ++++++++++++++++++++++++++++---- tests/api.c | 350 +++++++++-- wolfcrypt/src/asn.c | 25 +- wolfcrypt/src/evp.c | 49 +- wolfssl/openssl/bn.h | 29 +- wolfssl/openssl/cmac.h | 58 ++ wolfssl/openssl/dsa.h | 11 +- wolfssl/openssl/evp.h | 9 +- wolfssl/openssl/include.am | 1 + wolfssl/openssl/pem.h | 1 + wolfssl/openssl/rsa.h | 2 + wolfssl/openssl/ssl.h | 10 +- wolfssl/ssl.h | 19 +- wolfssl/wolfcrypt/asn.h | 4 + wolfssl/wolfcrypt/asn_public.h | 5 +- 18 files changed, 1395 insertions(+), 211 deletions(-) create mode 100644 certs/dsaparams.der create mode 100644 wolfssl/openssl/cmac.h diff --git a/certs/dsaparams.der b/certs/dsaparams.der new file mode 100644 index 0000000000000000000000000000000000000000..166068ab225463c597249170f1a20c54bf8af945 GIT binary patch literal 291 zcmV+;0o?vDf&m`_fq?+c-X&;&Qw`;J*3ytUKaiq7Gn8)VPb*`qFsl{15$cLvjm)^z zq1C}homz8hVoA{k2WR##qdC1!4YboDBZTaeCR$1Ee2GYAP3Y*@Q2V8EpCTCL<_kuL zX6{mtMo+Z^&h6vA<+Xv*S?R#7P0&py_qtH%$&dad89gqiQao(}6#)B3`|N=r$Q_CR<9IUW-j1rj p(Ey*b0umXb73>rkTn;AA`L4`+wb3U0h5i(iww--;<29Ea-o$XUj{g7v literal 0 HcmV?d00001 diff --git a/certs/include.am b/certs/include.am index 11fcf3401..0df422e37 100644 --- a/certs/include.am +++ b/certs/include.am @@ -47,6 +47,7 @@ EXTRA_DIST += \ certs/test-servercert.p12 \ certs/test-servercert-rc2.p12 \ certs/ecc-rsa-server.p12 \ + certs/dsaparams.der \ certs/dsaparams.pem \ certs/ecc-privOnlyKey.pem \ certs/ecc-privOnlyCert.pem \ diff --git a/configure.ac b/configure.ac index 710998c5e..c6eadf954 100644 --- a/configure.ac +++ b/configure.ac @@ -777,6 +777,7 @@ AC_ARG_ENABLE([mcast], # openssh (--enable-openssh) WOLFSSL_OPENSSH # openvpn (--enable-openvpn) WOLFSSL_OPENVPN # nginix (--enable-nginx) WOLFSSL_NGINX +# ntp (--enable-ntp) # haproxy (--enable-haproxy) WOLFSSL_HAPROXY # wpa_supplicant (--enable-wpas) WOLFSSL_WPAS # ssl fortress (--enable-fortress) FORTRESS @@ -852,6 +853,13 @@ AC_ARG_ENABLE([wpas-dpp], [ ENABLED_WPAS_DPP=no ] ) +# ntp support +AC_ARG_ENABLE([ntp], + [AS_HELP_STRING([--enable-ntp],[Enable ntp support (default: disabled)])], + [ ENABLED_NTP=$enableval ], + [ ENABLED_NTP=no ] + ) + if test "$ENABLED_WPAS_DPP" = "yes" then ENABLED_WPAS="yes" @@ -949,7 +957,7 @@ AC_ARG_ENABLE([opensslall], [ ENABLED_OPENSSLALL=$enableval ], [ ENABLED_OPENSSLALL=no ] ) -if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" +if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" || test "$ENABLED_NTP" == "yes" then ENABLED_OPENSSLALL="yes" fi @@ -965,7 +973,7 @@ AC_ARG_ENABLE([opensslextra], [ ENABLED_OPENSSLEXTRA=$enableval ], [ ENABLED_OPENSSLEXTRA=no ] ) -if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_SIGNAL" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_FORTRESS" = "yes" || test "$ENABLED_BUMP" = "yes" || test "$ENABLED_SNIFFER" = "yes" || test "$ENABLED_OPENSSLALL" = "yes" || test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "x$ENABLED_LIGHTY" = "xyes" || test "$ENABLED_LIBSSH2" = "yes" +if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_SIGNAL" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_FORTRESS" = "yes" || test "$ENABLED_BUMP" = "yes" || test "$ENABLED_SNIFFER" = "yes" || test "$ENABLED_OPENSSLALL" = "yes" || test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "x$ENABLED_LIGHTY" = "xyes" || test "$ENABLED_LIBSSH2" = "yes" || test "x$ENABLED_NTP" = "xyes" then ENABLED_OPENSSLEXTRA="yes" fi @@ -1894,7 +1902,7 @@ AC_ARG_ENABLE([keygen], [ ENABLED_KEYGEN=no ] ) -if test "$ENABLED_BIND" = "yes" || test "$ENABLED_LIBSSH2" = "yes" +if test "$ENABLED_BIND" = "yes" || test "$ENABLED_NTP" = "yes" || test "$ENABLED_LIBSSH2" = "yes" then ENABLED_KEYGEN=yes fi @@ -1911,7 +1919,7 @@ AC_ARG_ENABLE([certgen], [ ENABLED_CERTGEN=$enableval ], [ ENABLED_CERTGEN=no ] ) -if test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_BIND" = "yes" +if test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_BIND" = "yes" || test "$ENABLED_NTP" = "yes" then ENABLED_CERTGEN=yes fi @@ -2014,7 +2022,7 @@ AC_ARG_ENABLE([dsa], [ ENABLED_DSA=no ] ) -if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_BIND" = "yes" || test "$ENABLED_LIBSSH2" = "yes" +if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_BIND" = "yes" || test "$ENABLED_LIBSSH2" = "yes" || test "$ENABLED_NTP" = "yes" then ENABLED_DSA="yes" fi @@ -3095,7 +3103,7 @@ AC_ARG_ENABLE([cmac], [ ENABLED_CMAC=no ] ) -if test "$ENABLED_WPAS" != "no" +if test "$ENABLED_WPAS" != "no" || test "$ENABLED_NTP" = "yes" then ENABLED_CMAC=yes fi @@ -6936,6 +6944,7 @@ echo " * HAPROXY: $ENABLED_HAPROXY" echo " * STUNNEL: $ENABLED_STUNNEL" echo " * tcpdump: $ENABLED_TCPDUMP" echo " * libssh2: $ENABLED_LIBSSH2" +echo " * ntp: $ENABLED_NTP" echo " * Apache httpd: $ENABLED_APACHE_HTTPD" echo " * NGINX: $ENABLED_NGINX" echo " * ASIO: $ENABLED_ASIO" diff --git a/src/ssl.c b/src/ssl.c index e0875ef87..5cb2ff162 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -77,6 +77,7 @@ /* openssl headers begin */ #include #include + #include #include #include #include @@ -8140,53 +8141,44 @@ int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der) return wolfSSL_EVP_PKEY_get_der(key, der); } - -/* Reads in a DER format key. If PKCS8 headers are found they are stripped off. - * - * type type of key - * out newly created WOLFSSL_EVP_PKEY structure - * in pointer to input key DER - * inSz size of in buffer - * - * On success a non null pointer is returned and the pointer in is advanced the - * same number of bytes read. - */ -WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, - const unsigned char **in, long inSz) +static WOLFSSL_EVP_PKEY* _d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out, + const unsigned char **in, long inSz, int priv) { - int ret; + int ret = 0; word32 idx = 0, algId; word16 pkcs8HeaderSz = 0; WOLFSSL_EVP_PKEY* local; - - WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey"); + int opt; if (in == NULL || inSz < 0) { WOLFSSL_MSG("Bad argument"); return NULL; } - /* Check if input buffer has PKCS8 header. In the case that it does not - * have a PKCS8 header then do not error out. */ - if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx, (word32)inSz, - &algId)) > 0) { - WOLFSSL_MSG("Found PKCS8 header"); - pkcs8HeaderSz = (word16)idx; + if (priv == 1) { + /* Check if input buffer has PKCS8 header. In the case that it does not + * have a PKCS8 header then do not error out. */ + if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx, + (word32)inSz, &algId)) > 0) { + WOLFSSL_MSG("Found PKCS8 header"); + pkcs8HeaderSz = (word16)idx; - if ((type == EVP_PKEY_RSA && algId != RSAk) || - (type == EVP_PKEY_EC && algId != ECDSAk) || - (type == EVP_PKEY_DSA && algId != DSAk) || - (type == EVP_PKEY_DH && algId != DHk)) { - WOLFSSL_MSG("PKCS8 does not match EVP key type"); - return NULL; + if ((type == EVP_PKEY_RSA && algId != RSAk) || + (type == EVP_PKEY_EC && algId != ECDSAk) || + (type == EVP_PKEY_DSA && algId != DSAk) || + (type == EVP_PKEY_DH && algId != DHk)) { + WOLFSSL_MSG("PKCS8 does not match EVP key type"); + return NULL; + } + + (void)idx; /* not used */ } - - (void)idx; /* not used */ - } - else { - if (ret != ASN_PARSE_E) { - WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header"); - return NULL; + else { + if (ret != ASN_PARSE_E) { + WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 " + "header"); + return NULL; + } } } @@ -8221,9 +8213,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, wolfSSL_EVP_PKEY_free(local); return NULL; } + opt = priv ? WOLFSSL_RSA_LOAD_PRIVATE : WOLFSSL_RSA_LOAD_PUBLIC; if (wolfSSL_RSA_LoadDer_ex(local->rsa, (const unsigned char*)local->pkey.ptr, local->pkey_sz, - WOLFSSL_RSA_LOAD_PRIVATE) != WOLFSSL_SUCCESS) { + opt) != WOLFSSL_SUCCESS) { wolfSSL_EVP_PKEY_free(local); return NULL; } @@ -8237,8 +8230,11 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, wolfSSL_EVP_PKEY_free(local); return NULL; } - if (wolfSSL_EC_KEY_LoadDer(local->ecc, - (const unsigned char*)local->pkey.ptr, local->pkey_sz) + opt = priv ? WOLFSSL_EC_KEY_LOAD_PRIVATE : + WOLFSSL_EC_KEY_LOAD_PUBLIC; + if (wolfSSL_EC_KEY_LoadDer_ex(local->ecc, + (const unsigned char*)local->pkey.ptr, local->pkey_sz, + opt) != WOLFSSL_SUCCESS) { wolfSSL_EVP_PKEY_free(local); return NULL; @@ -8254,8 +8250,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, wolfSSL_EVP_PKEY_free(local); return NULL; } - if (wolfSSL_DSA_LoadDer(local->dsa, - (const unsigned char*)local->pkey.ptr, local->pkey_sz) + opt = priv ? WOLFSSL_DSA_LOAD_PRIVATE : WOLFSSL_DSA_LOAD_PUBLIC; + if (wolfSSL_DSA_LoadDer_ex(local->dsa, + (const unsigned char*)local->pkey.ptr, local->pkey_sz, + opt) != WOLFSSL_SUCCESS) { wolfSSL_EVP_PKEY_free(local); return NULL; @@ -8301,6 +8299,31 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, return local; } +WOLFSSL_EVP_PKEY* wolfSSL_d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out, + const unsigned char **in, long inSz) +{ + WOLFSSL_ENTER("wolfSSL_d2i_PublicKey"); + + return _d2i_PublicKey(type, out, in, inSz, 0); +} +/* Reads in a DER format key. If PKCS8 headers are found they are stripped off. + * + * type type of key + * out newly created WOLFSSL_EVP_PKEY structure + * in pointer to input key DER + * inSz size of in buffer + * + * On success a non null pointer is returned and the pointer in is advanced the + * same number of bytes read. + */ +WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, + const unsigned char **in, long inSz) +{ + WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey"); + + return _d2i_PublicKey(type, out, in, inSz, 1); +} + #ifndef NO_CERTS int wolfSSL_check_private_key(const WOLFSSL* ssl) @@ -19399,17 +19422,6 @@ const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509) return x509->notAfterData; } - -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_STUB) -WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj) -{ - (void) s; - (void) adj; - WOLFSSL_STUB("wolfSSL_X509_gmtime_adj"); - return NULL; -} -#endif - /* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate * * outSz : gets set to the size of the buffer @@ -24448,6 +24460,10 @@ int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der) return wolfSSL_EVP_PKEY_get_der(key, der); } +int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY *key, unsigned char **der) +{ + return wolfSSL_EVP_PKEY_get_der(key, der); +} #endif /* !NO_ASN && !NO_PWDBASED */ @@ -25572,14 +25588,46 @@ int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a, } #endif -#ifndef NO_WOLFSSL_STUB -long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i) +long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* a) { - (void)i; - WOLFSSL_STUB("ASN1_INTEGER_get"); - return 0; + long ret = 1; + WOLFSSL_BIGNUM* bn = NULL; + + WOLFSSL_ENTER("ASN1_INTEGER_get"); + + if (a == NULL) { + /* OpenSSL returns 0 when a is NULL and -1 if there is an error. Quoting + * the documentation: + * + * "ASN1_INTEGER_get() also returns the value of a but it returns 0 if a + * is NULL and -1 on error (which is ambiguous because -1 is a + * legitimate value for an ASN1_INTEGER). New applications should use + * ASN1_INTEGER_get_int64() instead." + * */ + ret = 0; + } + + if (ret > 0) { + bn = wolfSSL_ASN1_INTEGER_to_BN(a, NULL); + if (bn == NULL) { + ret = -1; + } + } + if (ret > 0) { + ret = wolfSSL_BN_get_word(bn); + if (a->negative == 1) { + ret = -ret; + } + } + + if (bn != NULL) { + wolfSSL_BN_free(bn); + } + + WOLFSSL_LEAVE("ASN1_INTEGER_get", (int)ret); + + return ret; } -#endif #endif /* OPENSSL_EXTRA */ @@ -26654,6 +26702,11 @@ WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg) WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts"); return WOLFSSL_FAILURE; } + +WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj) +{ + return wolfSSL_X509_time_adj(s, adj, NULL); +} #endif /*** TBD ***/ @@ -27326,21 +27379,6 @@ int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p) return (int)p->num; } -#if !defined(NO_FILESYSTEM) -#ifndef NO_WOLFSSL_STUB -/*** TBD ***/ -WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **x, pem_password_cb *cb, void *u) -{ - (void)fp; - (void)x; - (void)cb; - (void)u; - WOLFSSL_STUB("PEM_read_PrivateKey"); - return NULL; -} -#endif -#endif - WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i) { WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value"); @@ -30980,8 +31018,109 @@ int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, #endif /* NO_DH */ #endif /* OPENSSL_EXTRA */ -#if !defined(NO_DSA) && \ - (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) +#if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA)) +/* Print the number bn in hex with name field and indentation indent to file fp. + * Used by wolfSSL_DSA_print_fp and wolfSSL_RSA_print_fp to print DSA and RSA + * keys and parameters. + */ +static int PrintBNFieldFp(XFILE fp, int indent, const char* field, + const WOLFSSL_BIGNUM* bn) { + static const int HEX_INDENT = 4; + static const int MAX_DIGITS_PER_LINE = 30; + + int ret = WOLFSSL_SUCCESS; + int i = 0; + char* buf = NULL; + + if (fp == XBADFILE || indent < 0 || field == NULL || bn == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == WOLFSSL_SUCCESS) { + buf = wolfSSL_BN_bn2hex(bn); + if (buf == NULL) { + ret = WOLFSSL_FAILURE; + } + } + if (ret == WOLFSSL_SUCCESS) { + XFPRINTF(fp, "%*s", indent, ""); + XFPRINTF(fp, "%s:\n", field); + XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); + while (buf[i]) { + if (i != 0) { + if (i % 2 == 0) { + XFPRINTF(fp, ":"); + } + if (i % MAX_DIGITS_PER_LINE == 0) { + XFPRINTF(fp, "\n"); + XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); + } + } + XFPRINTF(fp, "%c", buf[i++]); + } + XFPRINTF(fp, "\n"); + } + + if (buf != NULL) { + XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL); + } + + return ret; +} +#endif /* OPENSSL_EXTRA && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM + * && (!NO_DSA || !NO_RSA)*/ + +#ifndef NO_DSA +#if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + !defined(NO_STDIO_FILESYSTEM) +/* return code compliant with OpenSSL : + * 1 if success, 0 if error + */ +int wolfSSL_DSA_print_fp(XFILE fp, WOLFSSL_DSA* dsa, int indent) +{ + int ret = WOLFSSL_SUCCESS; + int pBits; + + WOLFSSL_ENTER("wolfSSL_DSA_print_fp"); + + if (fp == XBADFILE || dsa == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS && dsa->p != NULL) { + pBits = wolfSSL_BN_num_bits(dsa->p); + if (pBits == WOLFSSL_FAILURE) { + ret = WOLFSSL_FAILURE; + } + else { + XFPRINTF(fp, "%*s", indent, ""); + XFPRINTF(fp, "Private-Key: (%d bit)\n", pBits); + } + } + if (ret == WOLFSSL_SUCCESS && dsa->priv_key != NULL) { + ret = PrintBNFieldFp(fp, indent, "priv", dsa->priv_key); + } + if (ret == WOLFSSL_SUCCESS && dsa->pub_key != NULL) { + ret = PrintBNFieldFp(fp, indent, "pub", dsa->pub_key); + } + if (ret == WOLFSSL_SUCCESS && dsa->p != NULL) { + ret = PrintBNFieldFp(fp, indent, "P", dsa->p); + } + if (ret == WOLFSSL_SUCCESS && dsa->q != NULL) { + ret = PrintBNFieldFp(fp, indent, "Q", dsa->q); + } + if (ret == WOLFSSL_SUCCESS && dsa->g != NULL) { + ret = PrintBNFieldFp(fp, indent, "G", dsa->g); + } + + WOLFSSL_LEAVE("wolfSSL_DSA_print_fp", ret); + + return ret; +} +#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_FILESYSTEM && NO_STDIO_FILESYSTEM */ + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa) { if (dsa) { @@ -31096,8 +31235,8 @@ int SetDsaExternal(WOLFSSL_DSA* dsa) return WOLFSSL_SUCCESS; } -#endif /* !NO_DSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ - +#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ +#endif /* !NO_DSA */ #if !defined(NO_DSA) && defined(OPENSSL_EXTRA) /* Openssl -> WolfSSL */ @@ -31957,8 +32096,109 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, return WOLFSSL_SUCCESS; } #endif /* !HAVE_SELFTEST && !HAVE_FIPS */ -#endif /* NO_DSA */ +WOLFSSL_API int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa, + unsigned char** out) +{ + int ret = 0; + word32 derLen = 0; + int preAllocated = 1; + DsaKey* key = NULL; + + WOLFSSL_ENTER("wolfSSL_i2d_DSAparams"); + + if (dsa == NULL || dsa->internal == NULL || out == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + key = (DsaKey*)dsa->internal; + ret = wc_DsaKeyToParamsDer_ex(key, NULL, &derLen); + if (ret == LENGTH_ONLY_E) { + ret = 0; + } + } + if (ret == 0 && *out == NULL) { + /* If we're allocating out for the caller, we don't increment out just + past the end of the DER buffer. If out is already allocated, we do. + (OpenSSL convention) */ + preAllocated = 0; + *out = (unsigned char*)XMALLOC(derLen, key->heap, DYNAMIC_TYPE_OPENSSL); + if (*out == NULL) { + ret = MEMORY_E; + } + } + if (ret == 0) { + ret = wc_DsaKeyToParamsDer_ex(key, *out, &derLen); + } + if (ret >= 0 && preAllocated == 1) { + *out += derLen; + } + + if (ret < 0 && preAllocated == 0) { + XFREE(*out, key->heap, DYNAMIC_TYPE_OPENSSL) + } + + WOLFSSL_LEAVE("wolfSSL_i2d_DSAparams", ret); + + return ret; +} + +WOLFSSL_API WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa, + const unsigned char** der, long derLen) +{ + WOLFSSL_DSA* ret = NULL; + int err = 0; + word32 idx = 0; + int asnLen; + DsaKey* internalKey = NULL; + + WOLFSSL_ENTER("wolfSSL_d2i_DSAparams"); + + if (der == NULL || *der == NULL || derLen <= 0) { + err = 1; + } + if (err == 0) { + ret = wolfSSL_DSA_new(); + err = ret == NULL; + } + if (err == 0) { + err = GetSequence(*der, &idx, &asnLen, (word32)derLen) <= 0; + } + if (err == 0) { + internalKey = (DsaKey*)ret->internal; + err = GetInt(&internalKey->p, *der, &idx, (word32)derLen) != 0; + } + if (err == 0) { + err = GetInt(&internalKey->q, *der, &idx, (word32)derLen) != 0; + } + if (err == 0) { + err = GetInt(&internalKey->g, *der, &idx, (word32)derLen) != 0; + } + if (err == 0) { + err = SetIndividualExternal(&ret->p, &internalKey->p) + != WOLFSSL_SUCCESS; + } + if (err == 0) { + err = SetIndividualExternal(&ret->q, &internalKey->q) + != WOLFSSL_SUCCESS; + } + if (err == 0) { + err = SetIndividualExternal(&ret->g, &internalKey->g) + != WOLFSSL_SUCCESS; + } + if (err == 0 && dsa != NULL) { + *dsa = ret; + } + + if (err != 0 && ret != NULL) { + wolfSSL_DSA_free(ret); + ret = NULL; + } + + return ret; +} +#endif /* NO_DSA */ #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) @@ -33029,6 +33269,154 @@ const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx) return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type); } +#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) +WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void) +{ + WOLFSSL_CMAC_CTX* ctx = NULL; + + ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL, + DYNAMIC_TYPE_OPENSSL); + if (ctx != NULL) { + ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC); + if (ctx->internal == NULL) { + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + ctx = NULL; + } + } + if (ctx != NULL) { + ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new(); + if (ctx->cctx == NULL) { + XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + ctx = NULL; + } + } + + return ctx; +} + +void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx) +{ + if (ctx != NULL) { + if (ctx->internal != NULL) { + XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); + } + if (ctx->cctx != NULL) { + wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx); + } + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx) +{ + WOLFSSL_EVP_CIPHER_CTX* cctx = NULL; + + if (ctx != NULL) { + cctx = ctx->cctx; + } + + return cctx; +} + +int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keyLen, + const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine) +{ + int ret = WOLFSSL_SUCCESS; + + (void)engine; + + WOLFSSL_ENTER("wolfSSL_CMAC_Init"); + + if (ctx == NULL || cipher == NULL || (cipher != EVP_AES_128_CBC && + cipher != EVP_AES_192_CBC && cipher != EVP_AES_256_CBC)) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key, (word32)keyLen, + WC_CMAC_AES, NULL); + if (ret != 0) { + ret = WOLFSSL_FAILURE; + } + else { + ret = WOLFSSL_SUCCESS; + } + } + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL, + 1); + } + + WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret); + + return ret; +} + +int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CMAC_Update"); + + if (ctx == NULL || ctx->internal == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + if (data) { + ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data, (word32)len); + if (ret != 0){ + ret = WOLFSSL_FAILURE; + } + else { + ret = WOLFSSL_SUCCESS; + } + } + } + + WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret); + + return ret; +} + +int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, + size_t* len) +{ + int ret = WOLFSSL_SUCCESS; + int blockSize; + + WOLFSSL_ENTER("wolfSSL_CMAC_Final"); + + if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL || len == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + blockSize = EVP_CIPHER_CTX_block_size(ctx->cctx); + if (blockSize <= 0) { + ret = WOLFSSL_FAILURE; + } + else { + *len = blockSize; + } + } + if (ret == WOLFSSL_SUCCESS) { + ret = wc_CmacFinal((Cmac*)ctx->internal, out, (word32*)len); + if (ret != 0) { + ret = WOLFSSL_FAILURE; + } + else { + ret = WOLFSSL_SUCCESS; + } + } + + WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret); + + return ret; +} +#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA */ + /* Free the dynamically allocated data. * * p Pointer to dynamically allocated memory. @@ -34409,7 +34797,6 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) } } - /* set the group in WOLFSSL_EC_KEY and return WOLFSSL_SUCCESS on success */ int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group) { @@ -34774,13 +35161,13 @@ void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p) printf("%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet); num = wolfSSL_BN_bn2hex(p->X); printf("\tX = %s\n", num); - XFREE(num, NULL, DYNAMIC_TYPE_ECC); + XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); num = wolfSSL_BN_bn2hex(p->Y); printf("\tY = %s\n", num); - XFREE(num, NULL, DYNAMIC_TYPE_ECC); + XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); num = wolfSSL_BN_bn2hex(p->Z); printf("\tZ = %s\n", num); - XFREE(num, NULL, DYNAMIC_TYPE_ECC); + XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL); #else (void)msg; (void)p; @@ -37468,8 +37855,57 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x, #ifndef NO_RSA -#ifndef NO_BIO -#if defined(XSNPRINTF) && !defined(HAVE_FAST_RSA) +#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + !defined(NO_STDIO_FILESYSTEM) +int wolfSSL_RSA_print_fp(XFILE fp, WOLFSSL_RSA* rsa, int indent) +{ + int ret = WOLFSSL_SUCCESS; + int keySize; + + WOLFSSL_ENTER("wolfSSL_RSA_print_fp"); + + if (fp == XBADFILE || rsa == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS && rsa->n != NULL) { + keySize = wolfSSL_BN_num_bits(rsa->n); + if (keySize == WOLFSSL_FAILURE) { + ret = WOLFSSL_FAILURE; + } + else { + XFPRINTF(fp, "%*s", indent, ""); + XFPRINTF(fp, "RSA Private-Key: (%d bit, 2 primes)\n", keySize); + } + } + if (ret == WOLFSSL_SUCCESS && rsa->n != NULL) { + ret = PrintBNFieldFp(fp, indent, "modulus", rsa->n); + } + if (ret == WOLFSSL_SUCCESS && rsa->d != NULL) { + ret = PrintBNFieldFp(fp, indent, "privateExponent", rsa->d); + } + if (ret == WOLFSSL_SUCCESS && rsa->p != NULL) { + ret = PrintBNFieldFp(fp, indent, "prime1", rsa->p); + } + if (ret == WOLFSSL_SUCCESS && rsa->q != NULL) { + ret = PrintBNFieldFp(fp, indent, "prime2", rsa->q); + } + if (ret == WOLFSSL_SUCCESS && rsa->dmp1 != NULL) { + ret = PrintBNFieldFp(fp, indent, "exponent1", rsa->dmp1); + } + if (ret == WOLFSSL_SUCCESS && rsa->dmq1 != NULL) { + ret = PrintBNFieldFp(fp, indent, "exponent2", rsa->dmq1); + } + if (ret == WOLFSSL_SUCCESS && rsa->iqmp != NULL) { + ret = PrintBNFieldFp(fp, indent, "coefficient", rsa->iqmp); + } + + WOLFSSL_LEAVE("wolfSSL_RSA_print_fp", ret); + + return ret; +} +#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */ +#if defined(XSNPRINTF) && !defined(NO_BIO) && !defined(HAVE_FAST_RSA) /* snprintf() must be available */ /****************************************************************************** @@ -37645,9 +38081,7 @@ int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset) return WOLFSSL_SUCCESS; } - -#endif /* XSNPRINTF */ -#endif /* !NO_BIO */ +#endif /* XSNPRINTF && !NO_BIO && !HAVE_FAST_RSA */ #if !defined(NO_FILESYSTEM) #ifndef NO_WOLFSSL_STUB @@ -37756,7 +38190,7 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, } #if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ - !defined(NO_RSA) && !defined(HAVE_USER_RSA) + !defined(HAVE_USER_RSA) /* Converts an internal RSA structure to DER format. * If "pp" is null then buffer size only is returned. * If "*pp" is null then a created buffer is set in *pp and the caller is @@ -37801,8 +38235,8 @@ int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp) return ret; } -#endif /* !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ - * !defined(NO_RSA) && !defined(HAVE_USER_RSA) */ +#endif /* !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && + * !defined(HAVE_USER_RSA) */ #endif /* !NO_RSA */ #endif /* OPENSSL_EXTRA */ @@ -40569,6 +41003,38 @@ err: return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u, CERT_TYPE); } +#ifndef NO_BIO + WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, + WOLFSSL_EVP_PKEY **x, pem_password_cb *cb, void *u) + { + int err = 0; + WOLFSSL_EVP_PKEY* ret = NULL; + WOLFSSL_BIO* bio = NULL; + + WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey"); + + if (fp == XBADFILE) { + err = 1; + } + if (err == 0) { + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + err = bio == NULL; + } + if (err == 0) { + err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS; + } + if (err == 0) { + ret = wolfSSL_PEM_read_bio_PrivateKey(bio, x, cb, u); + } + + if (bio != NULL) { + wolfSSL_BIO_free(bio); + } + + return ret; + } +#endif + #if defined(HAVE_CRL) WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **crl, pem_password_cb *cb, void *u) @@ -41994,6 +42460,15 @@ err: const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info; size_t i; WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn"); + + if (n == NID_md5) { + /* NID_surname == NID_md5 and NID_surname comes before NID_md5 in + * wolfssl_object_info. As a result, the loop below will incorrectly + * return "SN" instead of "MD5." NID_surname isn't the true OpenSSL + * NID, but other functions rely on this table and modifying it to + * conform with OpenSSL's NIDs isn't trivial. */ + return "MD5"; + } for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) { if (obj_info->nid == n) { return obj_info->sName; @@ -48518,6 +48993,33 @@ int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn) } #endif +/* If not using old FIPS or CAVP selftest or not using fast or user RSA, able + * to check RSA key. */ +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \ + !defined(HAVE_USER_RSA) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) && \ + defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) +int wolfSSL_RSA_check_key(const WOLFSSL_RSA* rsa) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_RSA_check_key"); + + if (rsa == NULL || rsa->internal == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS && wc_CheckRsaKey((RsaKey*)rsa->internal) != 0) { + ret = WOLFSSL_FAILURE; + } + + WOLFSSL_LEAVE("wolfSSL_RSA_check_key", ret); + + return ret; +} +#endif + /* return compliant with OpenSSL * size of encrypted data if success , -1 if error */ @@ -48914,6 +49416,100 @@ int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a, return 0; } +WOLFSSL_API int wolfSSL_BN_mul(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b, + WOLFSSL_BN_CTX *ctx) +{ + int ret = WOLFSSL_SUCCESS; + + (void)ctx; + + WOLFSSL_ENTER("wolfSSL_BN_mul"); + + if (r == NULL || a == NULL || b == NULL || r->internal == NULL || + a->internal == NULL || b->internal == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ret = mp_mul((mp_int*)a->internal, (mp_int*)b->internal, + (mp_int*)r->internal); + if (ret == MP_OKAY) { + ret = WOLFSSL_SUCCESS; + } + else { + ret = WOLFSSL_FAILURE; + } + } + + WOLFSSL_LEAVE("wolfSSL_BN_mul", ret); + + return ret; +} + +int wolfSSL_BN_div(WOLFSSL_BIGNUM* dv, WOLFSSL_BIGNUM* rem, + const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* d, + WOLFSSL_BN_CTX* ctx) +{ + int ret = WOLFSSL_SUCCESS; + + (void)ctx; + + WOLFSSL_ENTER("wolfSSL_BN_div"); + + if (dv == NULL || rem == NULL || a == NULL || d == NULL || + dv->internal == NULL || rem->internal == NULL || a->internal == NULL || + d->internal == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ret = mp_div((mp_int*)a->internal, (mp_int*)d->internal, + (mp_int*)dv->internal, (mp_int*)rem->internal); + if (ret == MP_OKAY) { + ret = WOLFSSL_SUCCESS; + } + else { + ret = WOLFSSL_FAILURE; + } + } + + WOLFSSL_LEAVE("wolfSSL_BN_div", ret); + + return ret; +} + +#ifdef WOLFSSL_KEY_GEN /* Needed to get mp_gcd. */ +int wolfSSL_BN_gcd(WOLFSSL_BIGNUM* r, WOLFSSL_BIGNUM* a, WOLFSSL_BIGNUM* b, + WOLFSSL_BN_CTX* ctx) +{ + int ret = WOLFSSL_SUCCESS; + + (void)ctx; + + WOLFSSL_ENTER("wolfSSL_BN_gcd"); + + if (r == NULL || a == NULL || b == NULL || r->internal == NULL || + a->internal == NULL || b->internal == NULL) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ret = mp_gcd((mp_int*)a->internal, (mp_int*)b->internal, + (mp_int*)r->internal); + if (ret == MP_OKAY) { + ret = WOLFSSL_SUCCESS; + } + else { + ret = WOLFSSL_FAILURE; + } + } + + WOLFSSL_LEAVE("wolfSSL_BN_gcd", ret); + + return ret; +} +#endif /* WOLFSSL_KEY_GEN */ + /* WOLFSSL_SUCCESS on ok */ int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c) @@ -49033,6 +49629,30 @@ int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM* bn) return mp_isneg((mp_int*)bn->internal); } +WOLFSSL_API void wolfSSL_BN_zero(WOLFSSL_BIGNUM* bn) +{ + if (bn == NULL || bn->internal == NULL) { + return; + } + + mp_zero((mp_int*)bn->internal); +} + +WOLFSSL_API int wolfSSL_BN_one(WOLFSSL_BIGNUM* bn) +{ + int ret = WOLFSSL_SUCCESS; + + if (bn == NULL || bn->internal == NULL) { + return WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_BN_set_word(bn, 1); + } + + return ret; +} + /* return compliant with OpenSSL * 1 if BIGNUM is zero, 0 else */ int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn) @@ -49679,6 +50299,102 @@ char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn) } #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ +/* Internal function for adding/subtracting an unsigned long from a + * WOLFSSL_BIGNUM. To add, pass "sub" as 0. To subtract, pass it as 1. + * Returns 1 (WOLFSSL_SUCCESS) on success and 0 (WOLFSSL_FAILURE) on failure. + */ +static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w, + int sub) +{ + int ret = WOLFSSL_SUCCESS; + int rc = 0; + mp_int w_mp; + + XMEMSET(&w_mp, 0, sizeof(mp_int)); + + if (bn == NULL || bn->internal == NULL) { + WOLFSSL_MSG("bn NULL error"); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + if (w <= MP_MASK) { + if (sub == 1) { + rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w, + (mp_int*)bn->internal); + } + else { + rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w, + (mp_int*)bn->internal); + } + if (rc != MP_OKAY) { + WOLFSSL_MSG("mp_add/sub_d error"); + ret = WOLFSSL_FAILURE; + } + } + else { + if (mp_init(&w_mp) != MP_OKAY) { + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS) { + if (mp_set_int(&w_mp, w) != MP_OKAY) { + ret = WOLFSSL_FAILURE; + } + } + if (ret == WOLFSSL_SUCCESS) { + if (sub == 1) { + rc = mp_sub((mp_int *)bn->internal, &w_mp, + (mp_int *)bn->internal); + } + else { + rc = mp_add((mp_int *)bn->internal, &w_mp, + (mp_int *)bn->internal); + } + if (rc != MP_OKAY) { + WOLFSSL_MSG("mp_add/sub error"); + ret = WOLFSSL_FAILURE; + } + } + } + } + + mp_free(&w_mp); + + return ret; +} + +/* return code compliant with OpenSSL : + * 1 if success, 0 else + */ +int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_BN_add_word"); + + ret = wolfSSL_BN_add_word_int(bn, w, 0); + + WOLFSSL_LEAVE("wolfSSL_BN_add_word", ret); + + return ret; +} + +/* return code compliant with OpenSSL : + * 1 if success, 0 else + */ +WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_BN_sub_word"); + + ret = wolfSSL_BN_add_word_int(bn, w, 1); + + WOLFSSL_LEAVE("wolfSSL_BN_sub_word", ret); + + return ret; +} + /* return code compliant with OpenSSL : * 1 if success, 0 else */ @@ -49720,41 +50436,6 @@ int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n) return WOLFSSL_SUCCESS; } -/* return code compliant with OpenSSL : - * 1 if success, 0 else - */ -int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) -{ - WOLFSSL_MSG("wolfSSL_BN_add_word"); - - if (bn == NULL || bn->internal == NULL) { - WOLFSSL_MSG("bn NULL error"); - return WOLFSSL_FAILURE; - } - - if (w <= MP_MASK) { - if (mp_add_d((mp_int*)bn->internal, (mp_digit)w, (mp_int*)bn->internal) != MP_OKAY) { - WOLFSSL_MSG("mp_add_d error"); - return WOLFSSL_FAILURE; - } - } else { - int ret; - mp_int w_mp; - if (mp_init(&w_mp) != MP_OKAY) - return WOLFSSL_FAILURE; - if (mp_set_int(&w_mp, w) != MP_OKAY) - return WOLFSSL_FAILURE; - ret = mp_add((mp_int *)bn->internal, &w_mp, (mp_int *)bn->internal); - mp_free(&w_mp); - if (ret != MP_OKAY) { - WOLFSSL_MSG("mp_add error"); - return WOLFSSL_FAILURE; - } - } - - return WOLFSSL_SUCCESS; -} - /* return code compliant with OpenSSL : * 1 if success, 0 else */ @@ -49804,6 +50485,63 @@ int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, #ifdef WOLFSSL_KEY_GEN +int wolfSSL_BN_generate_prime_ex(WOLFSSL_BIGNUM* prime, int bits, + int safe, const WOLFSSL_BIGNUM* add, const WOLFSSL_BIGNUM* rem, + WOLFSSL_BN_GENCB* cb) +{ + int ret = WOLFSSL_SUCCESS; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG* rng = NULL; +#else + WC_RNG rng[1]; +#endif + + (void)cb; + + WOLFSSL_ENTER("wolfSSL_BN_generate_prime_ex"); + + if (safe == 1 || add != NULL || rem != NULL) { + /* These parameters aren't supported, yet. */ + ret = WOLFSSL_FAILURE; + } + + if (prime == NULL || prime->internal == NULL) { + ret = WOLFSSL_FAILURE; + } + +#ifdef WOLFSSL_SMALL_STACK + if (ret == WOLFSSL_SUCCESS) { + rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (rng == NULL) { + ret = WOLFSSL_FAILURE; + } + } +#endif + if (ret == WOLFSSL_SUCCESS) { + XMEMSET(rng, 0, sizeof(WC_RNG)); + if (wc_InitRng(rng) != 0) { + ret = WOLFSSL_FAILURE; + } + } + + if (ret == WOLFSSL_SUCCESS) { + if (mp_rand_prime((mp_int*)prime->internal, (bits + 7) / 8, rng, NULL) + != MP_OKAY) { + ret = WOLFSSL_FAILURE; + } + } + + wc_FreeRng(rng); +#ifdef WOLFSSL_SMALL_STACK + if (rng != NULL) + XFREE(rng, NULL, DYNAMIC_TYPE_RNG); +#endif + + WOLFSSL_LEAVE("wolfSSL_BN_generate_prime_ex", ret); + + return ret; +} + /* return code compliant with OpenSSL : * 1 if prime, 0 if not, -1 if error */ @@ -51091,6 +51829,31 @@ int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio, } +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey, + const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, + pem_password_cb* cb, void* ctx) +{ + int ret = WOLFSSL_SUCCESS; + BIO *b; + + WOLFSSL_ENTER("wolfSSL_PEM_write_PKCS8PrivateKey"); + + b = wolfSSL_BIO_new_fp(f, BIO_NOCLOSE); + if (b == NULL) { + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_PEM_write_bio_PKCS8PrivateKey(b, pkey, enc, passwd, + passwdSz, cb, ctx); + } + + wolfSSL_BIO_free(b); + + return ret; +} +#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */ + static int bio_get_data(WOLFSSL_BIO* bio, byte** data) { int ret = 0; diff --git a/tests/api.c b/tests/api.c index 556777871..2c25ecd6c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -298,6 +298,7 @@ #endif #endif #ifdef OPENSSL_EXTRA + #include #include #include #include @@ -28259,6 +28260,47 @@ static void test_wolfSSL_private_keys(void) #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ } +static void test_wolfSSL_PEM_read_PrivateKey(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) + XFILE file; + const char* fname = "./certs/server-key.pem"; + EVP_PKEY* pkey; + RSA* rsa; + WOLFSSL_EVP_PKEY_CTX* ctx; + unsigned char* sig; + size_t sigLen; + const unsigned char tbs[] = {0, 1, 2, 3, 4, 5, 6, 7}; + size_t tbsLen = sizeof(tbs); + + printf(testingFmt, "test_wolfSSL_PEM_read_PrivateKey()"); + + /* Check error case. */ + AssertNull(pkey = PEM_read_PrivateKey(NULL, NULL, NULL, NULL)); + + /* Read in an RSA key. */ + file = XFOPEN(fname, "rb"); + AssertTrue(file != XBADFILE); + AssertNotNull(pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL)); + XFCLOSE(file); + + /* Make sure the key is usable by signing some data with it. */ + AssertNotNull(rsa = EVP_PKEY_get0_RSA(pkey)); + AssertIntGT((sigLen = RSA_size(rsa)), 0); + AssertNotNull(sig = (unsigned char*)XMALLOC(sigLen, HEAP_HINT, + DYNAMIC_TYPE_TMP_BUFFER)); + AssertNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_sign(ctx, sig, &sigLen, tbs, tbsLen), + WOLFSSL_SUCCESS); + + XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + + printf(resultFmt, passed); +#endif +} static void test_wolfSSL_PEM_PrivateKey(void) { @@ -29237,6 +29279,40 @@ static void test_wolfSSL_EVP_MD_size(void) #endif /* OPENSSL_EXTRA */ } +static void test_wolfSSL_EVP_MD_pkey_type(void) +{ +#ifdef OPENSSL_EXTRA + const WOLFSSL_EVP_MD* md; + + printf(testingFmt, "test_wolfSSL_EVP_MD_pkey_type()"); + +#ifndef NO_MD5 + AssertNotNull(md = EVP_md5()); + AssertIntEQ(EVP_MD_pkey_type(md), NID_md5WithRSAEncryption); +#endif +#ifndef NO_SHA + AssertNotNull(md = EVP_sha1()); + AssertIntEQ(EVP_MD_pkey_type(md), NID_sha1WithRSAEncryption); +#endif +#ifdef WOLFSSL_SHA224 + AssertNotNull(md = EVP_sha224()); + AssertIntEQ(EVP_MD_pkey_type(md), NID_sha224WithRSAEncryption); +#endif + AssertNotNull(md = EVP_sha256()); + AssertIntEQ(EVP_MD_pkey_type(md), NID_sha256WithRSAEncryption); +#ifdef WOLFSSL_SHA384 + AssertNotNull(md = EVP_sha384()); + AssertIntEQ(EVP_MD_pkey_type(md), NID_sha384WithRSAEncryption); +#endif +#ifdef WOLFSSL_SHA512 + AssertNotNull(md = EVP_sha512()); + AssertIntEQ(EVP_MD_pkey_type(md), NID_sha512WithRSAEncryption); +#endif + + printf(resultFmt, passed); +#endif +} + #ifdef OPENSSL_EXTRA static void test_hmac_signing(const WOLFSSL_EVP_MD *type, const byte* testKey, size_t testKeySz, const char* testData, size_t testDataSz, @@ -31318,13 +31394,12 @@ static void test_X509_STORE_get0_objects(void) static void test_wolfSSL_BN(void) { - #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) BIGNUM* a; BIGNUM* b; BIGNUM* c; BIGNUM* d; ASN1_INTEGER* ai; - unsigned char value[1]; printf(testingFmt, "wolfSSL_BN()"); @@ -31332,47 +31407,87 @@ static void test_wolfSSL_BN(void) AssertNotNull(c = BN_new()); AssertNotNull(d = BN_new()); - value[0] = 0x03; ai = ASN1_INTEGER_new(); AssertNotNull(ai); /* at the moment hard setting since no set function */ ai->data[0] = 0x02; /* tag for ASN_INTEGER */ ai->data[1] = 0x01; /* length of integer */ - ai->data[2] = value[0]; + ai->data[2] = 0x03; AssertNotNull(a = ASN1_INTEGER_to_BN(ai, NULL)); ASN1_INTEGER_free(ai); - value[0] = 0x02; - AssertNotNull(BN_bin2bn(value, sizeof(value), b)); + AssertIntEQ(BN_set_word(b, 2), SSL_SUCCESS); + AssertIntEQ(BN_set_word(c, 5), SSL_SUCCESS); - value[0] = 0x05; - AssertNotNull(BN_bin2bn(value, sizeof(value), c)); + /* a + 3 = */ + AssertIntEQ(BN_add_word(NULL, 3), WOLFSSL_FAILURE); + AssertIntEQ(BN_add_word(a, 3), WOLFSSL_SUCCESS); + + /* check result 3 + 3*/ + AssertIntEQ(BN_get_word(a), 6); + /* set a back to 3 */ + AssertIntEQ(BN_set_word(a, 3), SSL_SUCCESS); + + /* a - 3 = */ + AssertIntEQ(BN_sub_word(NULL, 3), WOLFSSL_FAILURE); + AssertIntEQ(BN_sub_word(a, 3), WOLFSSL_SUCCESS); + + /* check result 3 - 3*/ + AssertIntEQ(BN_get_word(a), 0); + /* set a back to 3 */ + AssertIntEQ(BN_set_word(a, 3), SSL_SUCCESS); /* a^b mod c = */ AssertIntEQ(BN_mod_exp(d, NULL, b, c, NULL), WOLFSSL_FAILURE); AssertIntEQ(BN_mod_exp(d, a, b, c, NULL), WOLFSSL_SUCCESS); - /* check result 3^2 mod 5 */ - value[0] = 0; - AssertIntEQ(BN_bn2bin(d, value), sizeof(value)); - AssertIntEQ((int)(value[0]), 4); + /* check result 3^2 mod 5 */ + AssertIntEQ(BN_get_word(d), 4); + + /* a*b = */ + AssertIntEQ(BN_mul(d, NULL, b, NULL), WOLFSSL_FAILURE); + AssertIntEQ(BN_mul(d, a, b, NULL), WOLFSSL_SUCCESS); + + /* check result 3*2 */ + AssertIntEQ(BN_get_word(d), 6); + + /* c/b = */ + AssertIntEQ(BN_div(d, NULL, c, b, NULL), WOLFSSL_FAILURE); + AssertIntEQ(BN_div(d, a, c, b, NULL), WOLFSSL_SUCCESS); + + /* check result 5/2 */ + AssertIntEQ(BN_get_word(d), 2); /* check quotient */ + AssertIntEQ(BN_get_word(a), 1); /* check remainder */ + /* set a back to 3 */ + AssertIntEQ(BN_set_word(a, 3), SSL_SUCCESS); /* a*b mod c = */ AssertIntEQ(BN_mod_mul(d, NULL, b, c, NULL), SSL_FAILURE); AssertIntEQ(BN_mod_mul(d, a, b, c, NULL), SSL_SUCCESS); - /* check result 3*2 mod 5 */ - value[0] = 0; - AssertIntEQ(BN_bn2bin(d, value), sizeof(value)); - AssertIntEQ((int)(value[0]), 1); + /* check result 3*2 mod 5 */ + AssertIntEQ(BN_get_word(d), 1); + + AssertIntEQ(BN_set_word(a, 16), SSL_SUCCESS); + AssertIntEQ(BN_set_word(b, 24), SSL_SUCCESS); + +#ifdef WOLFSSL_KEY_GEN + /* gcd of a and b */ + AssertIntEQ(BN_gcd(d, NULL, b, NULL), SSL_FAILURE); + AssertIntEQ(BN_gcd(d, a, b, NULL), SSL_SUCCESS); + + /* check result gcd(16, 24) */ + AssertIntEQ(BN_get_word(d), 8); +#endif /* WOLFSSL_KEY_GEN */ + + /* set b back to 2 */ + AssertIntEQ(BN_set_word(b, 2), SSL_SUCCESS); /* BN_mod_inverse test */ - value[0] = 0; BIGNUM *r = BN_new(); BIGNUM *val = BN_mod_inverse(r,b,c,NULL); - AssertIntEQ(BN_bn2bin(r, value), 1); - AssertIntEQ((int)(value[0] & 0x03), 3); + AssertIntEQ((int)(BN_get_word(r) & 0x03), 3); BN_free(val); #if !defined(WOLFSSL_SP_MATH) && (!defined(WOLFSSL_SP_MATH_ALL) || \ @@ -31407,12 +31522,10 @@ static void test_wolfSSL_BN(void) /* check that getting a string and a bin of the same number are equal, * and that the comparison works EQ, LT and GT */ AssertIntGT(BN_hex2bn(&a, "03"), 0); - value[0] = 0x03; AssertNotNull(b = BN_new()); - AssertNotNull(BN_bin2bn(value, sizeof(value), b)); - value[0] = 0x04; + AssertIntEQ(BN_set_word(b, 3), SSL_SUCCESS); AssertNotNull(c = BN_new()); - AssertNotNull(BN_bin2bn(value, sizeof(value), c)); + AssertIntEQ(BN_set_word(c, 4), SSL_SUCCESS); AssertIntEQ(BN_cmp(a, b), 0); AssertIntLT(BN_cmp(a, c), 0); AssertIntGT(BN_cmp(c, b), 0); @@ -31442,37 +31555,36 @@ static void test_wolfSSL_BN(void) BN_init(&cv); BN_init(&dv); - value[0] = 0x3; - AssertNotNull(BN_bin2bn(value, sizeof(value), ap)); - - value[0] = 0x02; - AssertNotNull(BN_bin2bn(value, sizeof(value), &bv)); - - value[0] = 0x05; - AssertNotNull(BN_bin2bn(value, sizeof(value), &cv)); + AssertIntEQ(BN_set_word(ap, 3), SSL_SUCCESS); + AssertIntEQ(BN_set_word(&bv, 2), SSL_SUCCESS); + AssertIntEQ(BN_set_word(&cv, 5), SSL_SUCCESS); /* a^b mod c = */ AssertIntEQ(BN_mod_exp(&dv, NULL, &bv, &cv, NULL), WOLFSSL_FAILURE); AssertIntEQ(BN_mod_exp(&dv, ap, &bv, &cv, NULL), WOLFSSL_SUCCESS); /* check result 3^2 mod 5 */ - value[0] = 0; - AssertIntEQ(BN_bn2bin(&dv, value), sizeof(value)); - AssertIntEQ((int)(value[0]), 4); + AssertIntEQ(BN_get_word(&dv), 4); /* a*b mod c = */ AssertIntEQ(BN_mod_mul(&dv, NULL, &bv, &cv, NULL), SSL_FAILURE); AssertIntEQ(BN_mod_mul(&dv, ap, &bv, &cv, NULL), SSL_SUCCESS); /* check result 3*2 mod 5 */ - value[0] = 0; - AssertIntEQ(BN_bn2bin(&dv, value), sizeof(value)); - AssertIntEQ((int)(value[0]), 1); + AssertIntEQ(BN_get_word(&dv), 1); BN_free(ap); } #endif +#ifdef WOLFSSL_KEY_GEN + AssertNotNull(a = BN_new()); + AssertIntEQ(BN_generate_prime_ex(a, 512, 0, NULL, NULL, NULL), + SSL_SUCCESS); + AssertIntEQ(BN_is_prime_ex(a, 8, NULL, NULL), SSL_SUCCESS); + BN_free(a); +#endif + printf(resultFmt, passed); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */ } @@ -32589,6 +32701,8 @@ static void test_wolfSSL_X509_time_adj(void) not_after = XTIME(0) + (60 * 24 * 30); /* 30 days after */ AssertNotNull(X509_time_adj(X509_get_notBefore(x509), not_before, &t)); AssertNotNull(X509_time_adj(X509_get_notAfter(x509), not_after, &t)); + /* Check X509_gmtime_adj, too. */ + AssertNotNull(X509_gmtime_adj(X509_get_notAfter(x509), not_after)); X509_free(x509); @@ -34208,6 +34322,37 @@ static void test_wolfSSL_HMAC(void) #endif } +static void test_wolfSSL_CMAC() +{ +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CMAC) + + int i = 0; + byte key[AES_128_KEY_SIZE]; + CMAC_CTX* cmacCtx = NULL; + byte out[AES_BLOCK_SIZE]; + size_t outLen = AES_BLOCK_SIZE; + + printf(testingFmt, "test_wolfSSL_CMAC()"); + + for (; i < AES_128_KEY_SIZE; ++i) { + key[i] = i; + } + AssertNotNull(cmacCtx = CMAC_CTX_new()); + /* Check CMAC_CTX_get0_cipher_ctx; return value not used. */ + AssertNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx)); + AssertIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(), + NULL), SSL_SUCCESS); + /* re-using test key as data to hash */ + AssertIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), SSL_SUCCESS); + AssertIntEQ(CMAC_Update(cmacCtx, NULL, 0), SSL_SUCCESS); + AssertIntEQ(CMAC_Final(cmacCtx, out, &outLen), SSL_SUCCESS); + AssertIntEQ(outLen, AES_BLOCK_SIZE); + CMAC_CTX_free(cmacCtx); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA && WOLFSSL_CMAC */ +} + static void test_wolfSSL_OBJ(void) { @@ -35767,6 +35912,13 @@ static void test_wolfSSL_RSA(void) AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); AssertIntEQ(RSA_size(rsa), 256); + +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \ + (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION >= 2))) && !defined(HAVE_SELFTEST) && \ + !defined(HAVE_INTEL_QA) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) + AssertIntEQ(RSA_check_key(rsa), WOLFSSL_SUCCESS); +#endif /* sanity check */ AssertIntEQ(RSA_bits(NULL), 0); @@ -40504,6 +40656,72 @@ static void test_wolfSSL_PKEY_up_ref(void) #endif } +static void test_wolfSSL_d2i_and_i2d_PublicKey(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) + EVP_PKEY* pkey; + const unsigned char* p; + unsigned char* der = NULL; + int derLen; + + printf(testingFmt, "test_wolfSSL_d2i_and_i2d_PublicKey()"); + + p = client_keypub_der_2048; + /* Check that key can be successfully decoded. */ + AssertNotNull(pkey = wolfSSL_d2i_PublicKey(EVP_PKEY_RSA, NULL, &p, + sizeof_client_keypub_der_2048)); + /* Check that key can be successfully encoded. */ + AssertIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &der)), 0); + /* Ensure that the encoded version matches the original. */ + AssertIntEQ(derLen, sizeof_client_keypub_der_2048); + AssertIntEQ(XMEMCMP(der, client_keypub_der_2048, derLen), 0); + + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); + EVP_PKEY_free(pkey); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_d2i_and_i2d_DSAparams(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_DSA) + DSA* dsa; + char file[] = "./certs/dsaparams.der"; + XFILE f; + int derInLen; + byte* derIn; + int derOutLen; + byte* derOut = NULL; + + printf(testingFmt, "test_wolfSSL_d2i_and_i2d_DSAparams()"); + + f = XFOPEN(file, "rb"); + AssertTrue(f != XBADFILE); + AssertTrue(XFSEEK(f, 0, XSEEK_END) == 0); + derInLen = (int)XFTELL(f); + XREWIND(f); + AssertNotNull(derIn = (byte*)XMALLOC(derInLen, HEAP_HINT, + DYNAMIC_TYPE_TMP_BUFFER)); + AssertIntEQ(XFREAD(derIn, 1, derInLen, f), derInLen); + XFCLOSE(f); + + /* Check that params can be successfully decoded. */ + AssertNotNull(dsa = d2i_DSAparams(NULL, (const byte**)&derIn, derInLen)); + /* Check that params can be successfully encoded. */ + AssertIntGE((derOutLen = i2d_DSAparams(dsa, &derOut)), 0); + /* Ensure that the encoded version matches the original. */ + AssertIntEQ(derInLen, derOutLen); + AssertIntEQ(XMEMCMP(derIn, derOut, derInLen), 0); + + XFREE(derIn, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derOut, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); + DSA_free(dsa); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_i2d_PrivateKey(void) { #if (!defined(NO_RSA) || defined(HAVE_ECC)) && defined(OPENSSL_EXTRA) && !defined(NO_ASN) && !defined(NO_PWDBASED) @@ -44121,80 +44339,85 @@ static void test_wolfSSL_X509_NAME_ENTRY_get_object(void) #endif } -static void test_wolfSSL_ASN1_INTEGER_set(void) +static void test_wolfSSL_ASN1_INTEGER_get_set(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) ASN1_INTEGER *a; long val; int ret; - printf(testingFmt, "wolfSSL_ASN1_INTEGER_set"); + printf(testingFmt, "test_wolfSSL_ASN1_INTEGER_get_set"); - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = 0; ret = ASN1_INTEGER_set(NULL, val); AssertIntEQ(ret, 0); - wolfSSL_ASN1_INTEGER_free(a); + ASN1_INTEGER_free(a); /* 0 */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = 0; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); /* 40 */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = 40; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); /* -40 */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = -40; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - AssertIntEQ(a->negative, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); /* 128 */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = 128; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); /* -128 */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = -128; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - AssertIntEQ(a->negative, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); /* 200 */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = 200; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); #ifndef TIME_T_NOT_64BIT /* int max (2147483647) */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = 2147483647; ret = ASN1_INTEGER_set(a, val); AssertIntEQ(ret, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); /* int min (-2147483648) */ - a = wolfSSL_ASN1_INTEGER_new(); + a = ASN1_INTEGER_new(); val = -2147483647 - 1; ret = ASN1_INTEGER_set(a, val); - AssertIntEQ(a->negative, 1); AssertIntEQ(ret, 1); - wolfSSL_ASN1_INTEGER_free(a); + AssertIntEQ(ASN1_INTEGER_get(a), val); + ASN1_INTEGER_free(a); #endif printf(resultFmt, passed); @@ -46490,6 +46713,7 @@ void ApiTest(void) test_wolfSSL_ASN1_UTCTIME_print(); test_wolfSSL_ASN1_GENERALIZEDTIME_free(); test_wolfSSL_private_keys(); + test_wolfSSL_PEM_read_PrivateKey(); test_wolfSSL_PEM_PrivateKey(); #ifndef NO_BIO test_wolfSSL_PEM_bio_RSAKey(); @@ -46502,6 +46726,7 @@ void ApiTest(void) test_wolfSSL_tmp_dh(); test_wolfSSL_ctrl(); test_wolfSSL_EVP_MD_size(); + test_wolfSSL_EVP_MD_pkey_type(); test_wolfSSL_EVP_Digest(); test_wolfSSL_EVP_Digest_all(); test_wolfSSL_EVP_PKEY_new_mac_key(); @@ -46598,6 +46823,7 @@ void ApiTest(void) test_wolfSSL_ERR_print_errors(); #endif test_wolfSSL_HMAC(); + test_wolfSSL_CMAC(); test_wolfSSL_OBJ(); test_wolfSSL_i2a_ASN1_OBJECT(); test_wolfSSL_OBJ_cmp(); @@ -46657,7 +46883,7 @@ void ApiTest(void) test_wolfSSL_OPENSSL_hexstr2buf(); test_wolfSSL_ASN1_STRING_print_ex(); test_wolfSSL_ASN1_TIME_to_generalizedtime(); - test_wolfSSL_ASN1_INTEGER_set(); + test_wolfSSL_ASN1_INTEGER_get_set(); test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(); test_wolfSSL_i2c_ASN1_INTEGER(); test_wolfSSL_X509_check_ca(); @@ -46669,6 +46895,8 @@ void ApiTest(void) test_wolfssl_EVP_aes_gcm(); test_wolfSSL_PKEY_up_ref(); test_wolfSSL_EVP_Cipher_extra(); + test_wolfSSL_d2i_and_i2d_PublicKey(); + test_wolfSSL_d2i_and_i2d_DSAparams(); test_wolfSSL_i2d_PrivateKey(); test_wolfSSL_OCSP_id_get0_info(); test_wolfSSL_i2d_OCSP_CERTID(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 4ab62a189..d8153d330 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5332,7 +5332,7 @@ int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen) } #endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */ -static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32 inLen, +static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32* inLen, int ints, int includeVersion) { word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0; @@ -5343,7 +5343,7 @@ static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32 inLen, byte ver[MAX_VERSION_SZ]; byte* tmps[DSA_INTS]; - if (ints > DSA_INTS) + if (ints > DSA_INTS || inLen == NULL) return BAD_FUNC_ARG; XMEMSET(sizes, 0, sizeof(sizes)); @@ -5381,7 +5381,12 @@ static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32 inLen, seqSz = SetSequence(verSz + intTotalLen, seq); outLen = seqSz + verSz + intTotalLen; - if (outLen > (int)inLen) { + *inLen = outLen; + if (output == NULL) { + FreeTmpDsas(tmps, key->heap, ints); + return LENGTH_ONLY_E; + } + if (outLen > (int)*inLen) { FreeTmpDsas(tmps, key->heap, ints); return BAD_FUNC_ARG; } @@ -5413,7 +5418,7 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen) if (key->type != DSA_PRIVATE) return BAD_FUNC_ARG; - return DsaKeyIntsToDer(key, output, inLen, DSA_INTS, 1); + return DsaKeyIntsToDer(key, output, &inLen, DSA_INTS, 1); } /* Convert DsaKey parameters to DER format, write to output (inLen), @@ -5424,6 +5429,17 @@ int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen) if (!key || !output) return BAD_FUNC_ARG; + return DsaKeyIntsToDer(key, output, &inLen, DSA_PARAM_INTS, 0); +} + +/* This version of the function allows output to be NULL. In that case, the + DsaKeyIntsToDer will return LENGTH_ONLY_E and the required output buffer + size will be pointed to by inLen. */ +int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, word32* inLen) +{ + if (!key || !inLen) + return BAD_FUNC_ARG; + return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0); } @@ -5954,6 +5970,7 @@ int wc_OBJ_sn2nid(const char *sn) {WOLFSSL_ORG_NAME, NID_organizationName}, {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName}, {WOLFSSL_EMAIL_ADDR, NID_emailAddress}, + {"SHA1", NID_sha1}, {NULL, -1}}; int i; #ifdef HAVE_ECC diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 08d498344..2e4600aea 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3587,12 +3587,12 @@ const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) return NULL; } -int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) +int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) { const struct s_ent *ent ; WOLFSSL_ENTER("EVP_MD_type"); for( ent = md_tbl; ent->name != NULL; ent++){ - if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) { + if(XSTRNCMP((const char *)type, ent->name, XSTRLEN(ent->name)+1) == 0) { return ent->nid; } } @@ -6143,9 +6143,21 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) case NID_sha1: return wolfSSL_EVP_sha1(); #endif +#ifdef WOLFSSL_SHA224 + case NID_sha224: + return wolfSSL_EVP_sha224(); +#endif #ifndef NO_SHA256 case NID_sha256: return wolfSSL_EVP_sha256(); +#endif +#ifdef WOLFSSL_SHA384 + case NID_sha384: + return wolfSSL_EVP_sha384(); +#endif +#ifdef WOLFSSL_SHA512 + case NID_sha512: + return wolfSSL_EVP_sha512(); #endif default: WOLFSSL_MSG("Bad digest id value"); @@ -6941,6 +6953,39 @@ int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type) return BAD_FUNC_ARG; } +int wolfSSL_EVP_MD_pkey_type(const WOLFSSL_EVP_MD* type) +{ + int ret = BAD_FUNC_ARG; + + WOLFSSL_ENTER("wolfSSL_EVP_MD_pkey_type"); + + if (type != NULL) { + if (XSTRNCMP(type, "MD5", 3) == 0) { + ret = NID_md5WithRSAEncryption; + } + else if (XSTRNCMP(type, "SHA1", 4) == 0) { + ret = NID_sha1WithRSAEncryption; + } + else if (XSTRNCMP(type, "SHA224", 6) == 0) { + ret = NID_sha224WithRSAEncryption; + } + else if (XSTRNCMP(type, "SHA256", 6) == 0) { + ret = NID_sha256WithRSAEncryption; + } + else if (XSTRNCMP(type, "SHA384", 6) == 0) { + ret = NID_sha384WithRSAEncryption; + } + else if (XSTRNCMP(type, "SHA512", 6) == 0) { + ret = NID_sha512WithRSAEncryption; + } + } + + WOLFSSL_LEAVE("wolfSSL_EVP_MD_pkey_type", ret); + + return ret; +} + + int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) { diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 0bc288005..ac8fd6634 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -47,7 +47,6 @@ typedef struct WOLFSSL_BIGNUM { #endif } WOLFSSL_BIGNUM; - #define BN_ULONG WOLFSSL_BN_ULONG #define WOLFSSL_BN_ULONG unsigned long @@ -69,6 +68,12 @@ WOLFSSL_API void wolfSSL_BN_clear(WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_sub(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_mul(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*, + WOLFSSL_BIGNUM*, WOLFSSL_BN_CTX*); +WOLFSSL_API int wolfSSL_BN_div(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*, + const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, WOLFSSL_BN_CTX*); +WOLFSSL_API int wolfSSL_BN_gcd(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*, + WOLFSSL_BIGNUM*, WOLFSSL_BN_CTX*); WOLFSSL_API int wolfSSL_BN_mod(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, const WOLFSSL_BN_CTX*); WOLFSSL_API int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, @@ -81,6 +86,8 @@ WOLFSSL_API const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void); WOLFSSL_API int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM*); +WOLFSSL_API void wolfSSL_BN_zero(WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_one(WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM*); @@ -110,6 +117,7 @@ WOLFSSL_API char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); +WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); @@ -121,6 +129,8 @@ WOLFSSL_API int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx); WOLFSSL_API char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM*); +WOLFSSL_API int wolfSSL_BN_generate_prime_ex(WOLFSSL_BIGNUM*, int, int, + const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, WOLFSSL_BN_GENCB*); WOLFSSL_API int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM*, int, WOLFSSL_BN_CTX*, WOLFSSL_BN_GENCB*); WOLFSSL_API WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM*, @@ -151,11 +161,13 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_num_bytes wolfSSL_BN_num_bytes #define BN_num_bits wolfSSL_BN_num_bits -#define BN_is_zero wolfSSL_BN_is_zero -#define BN_is_one wolfSSL_BN_is_one -#define BN_is_odd wolfSSL_BN_is_odd +#define BN_zero wolfSSL_BN_zero +#define BN_one wolfSSL_BN_one +#define BN_is_zero wolfSSL_BN_is_zero +#define BN_is_one wolfSSL_BN_is_one +#define BN_is_odd wolfSSL_BN_is_odd #define BN_is_negative wolfSSL_BN_is_negative -#define BN_is_word wolfSSL_BN_is_word +#define BN_is_word wolfSSL_BN_is_word #define BN_cmp wolfSSL_BN_cmp @@ -166,6 +178,9 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_mod_exp wolfSSL_BN_mod_exp #define BN_mod_mul wolfSSL_BN_mod_mul #define BN_sub wolfSSL_BN_sub +#define BN_mul wolfSSL_BN_mul +#define BN_div wolfSSL_BN_div +#define BN_gcd wolfSSL_BN_gcd #define BN_value_one wolfSSL_BN_value_one #define BN_mask_bits wolfSSL_mask_bits @@ -187,13 +202,14 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_lshift wolfSSL_BN_lshift #define BN_add_word wolfSSL_BN_add_word +#define BN_sub_word wolfSSL_BN_sub_word #define BN_add wolfSSL_BN_add #define BN_mod_add wolfSSL_BN_mod_add #define BN_set_word wolfSSL_BN_set_word #define BN_set_bit wolfSSL_BN_set_bit #define BN_clear_bit wolfSSL_BN_clear_bit - +#define BN_generate_prime_ex wolfSSL_BN_generate_prime_ex #define BN_is_prime_ex wolfSSL_BN_is_prime_ex #define BN_print_fp wolfSSL_BN_print_fp #define BN_rshift wolfSSL_BN_rshift @@ -217,6 +233,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_get_rfc3526_prime_8192 wolfSSL_DH_8192_prime #endif +#define BN_prime_checks 0 #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/cmac.h b/wolfssl/openssl/cmac.h new file mode 100644 index 000000000..a022e3762 --- /dev/null +++ b/wolfssl/openssl/cmac.h @@ -0,0 +1,58 @@ +/* cmac.h + * + * Copyright (C) 2006-2021 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_CMAC_H_ +#define WOLFSSL_CMAC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct WOLFSSL_CMAC_CTX { + void* internal; /* internal Cmac object */ + WOLFSSL_EVP_CIPHER_CTX* cctx; +} WOLFSSL_CMAC_CTX; + +typedef WOLFSSL_CMAC_CTX CMAC_CTX; + +WOLFSSL_API WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void); +WOLFSSL_API void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx); +WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx( + WOLFSSL_CMAC_CTX*); +WOLFSSL_API int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX*, const void*, size_t , + const WOLFSSL_EVP_CIPHER*, WOLFSSL_ENGINE*); +WOLFSSL_API int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX*, const void*, size_t); +WOLFSSL_API int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX*, unsigned char*, size_t*); + +#define CMAC_CTX_new wolfSSL_CMAC_CTX_new +#define CMAC_CTX_free wolfSSL_CMAC_CTX_free +#define CMAC_CTX_get0_cipher_ctx wolfSSL_CMAC_CTX_get0_cipher_ctx +#define CMAC_Init wolfSSL_CMAC_Init +#define CMAC_Update wolfSSL_CMAC_Update +#define CMAC_Final wolfSSL_CMAC_Final + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WOLFSSL_CMAC_H_ */ diff --git a/wolfssl/openssl/dsa.h b/wolfssl/openssl/dsa.h index 12b947572..b0ff4f70e 100644 --- a/wolfssl/openssl/dsa.h +++ b/wolfssl/openssl/dsa.h @@ -57,6 +57,9 @@ struct WOLFSSL_DSA { WOLFSSL_API WOLFSSL_DSA* wolfSSL_DSA_new(void); WOLFSSL_API void wolfSSL_DSA_free(WOLFSSL_DSA*); +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +WOLFSSL_API int wolfSSL_DSA_print_fp(XFILE, WOLFSSL_DSA*, int); +#endif /* !NO_FILESYSTEM && NO_STDIO_FILESYSTEM */ WOLFSSL_API int wolfSSL_DSA_generate_key(WOLFSSL_DSA*); @@ -109,11 +112,16 @@ WOLFSSL_API WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, WOLFSSL_API int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa); +WOLFSSL_API int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA*, unsigned char**); +WOLFSSL_API WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA**, + const unsigned char **, long); + #define WOLFSSL_DSA_LOAD_PRIVATE 1 #define WOLFSSL_DSA_LOAD_PUBLIC 2 #define DSA_new wolfSSL_DSA_new #define DSA_free wolfSSL_DSA_free +#define DSA_print_fp wolfSSL_DSA_print_fp #define DSA_LoadDer wolfSSL_DSA_LoadDer #define DSA_generate_key wolfSSL_DSA_generate_key @@ -132,7 +140,8 @@ WOLFSSL_API int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest #define d2i_DSA_SIG wolfSSL_d2i_DSA_SIG #define DSA_do_sign wolfSSL_DSA_do_sign_ex #define DSA_do_verify wolfSSL_DSA_do_verify_ex - +#define i2d_DSAparams wolfSSL_i2d_DSAparams +#define d2i_DSAparams wolfSSL_d2i_DSAparams #define DSA_SIG WOLFSSL_DSA_SIG diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 1a412ca37..4137f63c0 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -252,6 +252,7 @@ enum { NID_md4 = 257, NID_md5 = 4, NID_hmac = 855, + NID_cmac = 894, NID_dhKeyAgreement= 28, EVP_PKEY_DH = NID_dhKeyAgreement, EVP_PKEY_HMAC = NID_hmac, @@ -435,9 +436,10 @@ typedef WOLFSSL_EVP_PKEY_CTX EVP_PKEY_CTX; #define EVP_PKEY_PRINT_INDENT_MAX 128 WOLFSSL_API void wolfSSL_EVP_init(void); -WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* md); -WOLFSSL_API int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md); -WOLFSSL_API int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD *md); +WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* ); +WOLFSSL_API int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD*); +WOLFSSL_API int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD*); +WOLFSSL_API int wolfSSL_EVP_MD_pkey_type(const WOLFSSL_EVP_MD*); WOLFSSL_API WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new (void); WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX* ctx); @@ -785,6 +787,7 @@ typedef WOLFSSL_ASN1_PCTX ASN1_PCTX; #define EVP_enc_null wolfSSL_EVP_enc_null #define EVP_MD_size wolfSSL_EVP_MD_size +#define EVP_MD_pkey_type wolfSSL_EVP_MD_pkey_type #define EVP_MD_CTX_new wolfSSL_EVP_MD_CTX_new #define EVP_MD_CTX_create wolfSSL_EVP_MD_CTX_new #define EVP_MD_CTX_free wolfSSL_EVP_MD_CTX_free diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 8a1209429..deeb9bdac 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/cmac.h \ wolfssl/openssl/cms.h \ wolfssl/openssl/conf.h \ wolfssl/openssl/crypto.h \ diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 730fd0d60..e41fb1263 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -215,6 +215,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); #define PEM_write_X509 wolfSSL_PEM_write_X509 #define PEM_write_bio_PrivateKey wolfSSL_PEM_write_bio_PrivateKey #define PEM_write_bio_PKCS8PrivateKey wolfSSL_PEM_write_bio_PKCS8PrivateKey +#define PEM_write_PKCS8PrivateKey wolfSSL_PEM_write_PKCS8PrivateKey /* DH */ #define PEM_write_DHparams wolfSSL_PEM_write_DHparams diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 86c4dae9d..800400115 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -106,6 +106,7 @@ WOLFSSL_API int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA*, int bits, WOLFSSL_BIGN void* cb); WOLFSSL_API int wolfSSL_RSA_blinding_on(WOLFSSL_RSA*, WOLFSSL_BN_CTX*); +WOLFSSL_API int wolfSSL_RSA_check_key(const WOLFSSL_RSA*); WOLFSSL_API int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr, unsigned char* to, WOLFSSL_RSA*, int padding); WOLFSSL_API int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr, @@ -184,6 +185,7 @@ WOLFSSL_API int wolfSSL_RSA_set_ex_data_with_cleanup( #define RSA_generate_key_ex wolfSSL_RSA_generate_key_ex #define RSA_blinding_on wolfSSL_RSA_blinding_on +#define RSA_check_key wolfSSL_RSA_check_key #define RSA_public_encrypt wolfSSL_RSA_public_encrypt #define RSA_private_decrypt wolfSSL_RSA_private_decrypt #define RSA_private_encrypt wolfSSL_RSA_private_encrypt diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 2f1cbb4b9..0c0e73418 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -205,6 +205,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define i2d_PUBKEY wolfSSL_i2d_PUBKEY #define d2i_PUBKEY wolfSSL_d2i_PUBKEY #define d2i_PUBKEY_bio wolfSSL_d2i_PUBKEY_bio +#define d2i_PublicKey wolfSSL_d2i_PublicKey #define d2i_PrivateKey wolfSSL_d2i_PrivateKey #define d2i_AutoPrivateKey wolfSSL_d2i_AutoPrivateKey #define SSL_use_PrivateKey wolfSSL_use_PrivateKey @@ -378,7 +379,6 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data #define X509_EXTENSION_new wolfSSL_X509_EXTENSION_new #define X509_EXTENSION_free wolfSSL_X509_EXTENSION_free - #define X509_gmtime_adj wolfSSL_X509_gmtime_adj #endif #define DSA_dup_DH wolfSSL_DSA_dup_DH @@ -405,6 +405,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define PEM_write_bio_X509_AUX wolfSSL_PEM_write_bio_X509_AUX #define PEM_X509_INFO_read_bio wolfSSL_PEM_X509_INFO_read_bio #define i2d_PrivateKey wolfSSL_i2d_PrivateKey +#define i2d_PublicKey wolfSSL_i2d_PublicKey #define i2d_X509_REQ wolfSSL_i2d_X509_REQ #define d2i_X509_REQ wolfSSL_d2i_X509_REQ @@ -554,6 +555,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_cmp_time wolfSSL_X509_cmp_time #define X509_time_adj wolfSSL_X509_time_adj #define X509_time_adj_ex wolfSSL_X509_time_adj_ex +#define X509_gmtime_adj wolfSSL_X509_gmtime_adj #define sk_ACCESS_DESCRIPTION_num wolfSSL_sk_ACCESS_DESCRIPTION_num #define sk_ACCESS_DESCRIPTION_value wolfSSL_sk_ACCESS_DESCRIPTION_value @@ -843,6 +845,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define RSA_generate_key wolfSSL_RSA_generate_key #define SSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback #define RSA_print wolfSSL_RSA_print +#define RSA_print_fp wolfSSL_RSA_print_fp #define RSA_bits wolfSSL_RSA_bits #define RSA_up_ref wolfSSL_RSA_up_ref #define RSA_padding_add_PKCS1_PSS wolfSSL_RSA_padding_add_PKCS1_PSS @@ -1400,6 +1403,11 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define NID_pkcs9_emailAddress 48 #define OBJ_pkcs9_emailAddress 1L,2L,840L,113539L,1L,9L,1L +#define LN_basic_constraints "X509v3 Basic Constraints" +#define LN_key_usage "X509v3 Key Usage" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define LN_ext_key_usage "X509v3 Extended Key Usage" + #define SSL_get_rbio wolfSSL_SSL_get_rbio #define SSL_get_wbio wolfSSL_SSL_get_wbio #define SSL_do_handshake wolfSSL_SSL_do_handshake diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index d9b0812fe..600a426c6 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1556,8 +1556,14 @@ WOLFSSL_API int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, WOLFSSL_API WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name, unsigned char **in, long length); #ifndef NO_RSA +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +WOLFSSL_API int wolfSSL_RSA_print_fp(XFILE, WOLFSSL_RSA*, int); +#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */ +#ifndef NO_BIO WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset); -#endif +#endif /* !NO_BIO */ +#endif /* !NO_RSA */ + WOLFSSL_API int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, unsigned long nmflags, unsigned long cflag); #ifndef NO_FILESYSTEM @@ -1679,7 +1685,6 @@ WOLFSSL_API void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ct 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_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*); @@ -1691,12 +1696,16 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio, WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** key, const unsigned char** in, long inSz); WOLFSSL_API int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PublicKey(int, WOLFSSL_EVP_PKEY**, + const unsigned char **, long); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** key, unsigned char** in, long inSz); WOLFSSL_API int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der); +WOLFSSL_API int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY* key, + unsigned char** der); #if defined(OPENSSL_EXTRA) WOLFSSL_API int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, const WOLFSSL_EVP_PKEY* pkey, @@ -1710,6 +1719,8 @@ WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTi int offset_day, long offset_sec, time_t *in_tm); WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime, long offset_sec, time_t *in_tm); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME*, + long); WOLFSSL_API int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED*); WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX*, unsigned long flags, @@ -4467,6 +4478,10 @@ WOLFSSL_API int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509* x); WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, pem_password_cb* cb, void* ctx); +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +WOLFSSL_API int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE, WOLFSSL_EVP_PKEY*, + const WOLFSSL_EVP_CIPHER*, char*, int, pem_password_cb*, void*); +#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY** pkey, pem_password_cb* cb, void* u); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey( diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 0be5b9b7f..15c8e445d 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1275,6 +1275,10 @@ WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*); WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s); #endif +#ifndef NO_DSA +WOLFSSL_LOCAL int StoreDSAParams(byte*, word32*, const mp_int*, const mp_int*, + const mp_int*); +#endif #if defined HAVE_ECC && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) WOLFSSL_API int EccEnumToNID(int n); #endif diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 695d48c3d..4c652ca18 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -529,7 +529,10 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); /* DSA parameter DER helper functions */ WOLFSSL_API int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey*, word32); - WOLFSSL_API int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen); + WOLFSSL_API int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, + word32 inLen); + WOLFSSL_API int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, + word32* inLen); #endif #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)