diff --git a/certs/csr.attr.der b/certs/csr.attr.der new file mode 100644 index 000000000..e8c5baee6 Binary files /dev/null and b/certs/csr.attr.der differ 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/certs/csr.ext.der b/certs/csr.ext.der new file mode 100644 index 000000000..fd39dea6c Binary files /dev/null and b/certs/csr.ext.der differ diff --git a/certs/csr.signed.der b/certs/csr.signed.der new file mode 100644 index 000000000..7ae007f52 Binary files /dev/null and b/certs/csr.signed.der differ diff --git a/certs/include.am b/certs/include.am index 28c5e8515..c7e70ad1a 100644 --- a/certs/include.am +++ b/certs/include.am @@ -52,7 +52,11 @@ 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 \ + certs/csr.ext.der EXTRA_DIST += \ certs/ca-key.der \ diff --git a/configure.ac b/configure.ac index 45842cd3d..5d1f382f3 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) HAVE_LIBEST # asio (--enable-asio) WOLFSSL_ASIO # libwebsockets (--enable-libwebsockets) WOLFSSL_LIBWEBSOCKETS # qt (--enable-qt) WOLFSSL_QT @@ -856,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 @@ -4103,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 @@ -4240,6 +4241,91 @@ 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 + 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" + 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 + 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 + 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" + 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 + + # 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 + + if test "x$ENABLED_DSA" = "xno" + then + AC_MSG_WARN([Enabling DSA with --enable-dsa is recommended for libest]) + fi +fi + # MD4 AC_ARG_ENABLE([md4], [AS_HELP_STRING([--enable-md4],[Enable MD4 (default: disabled)])], diff --git a/src/bio.c b/src/bio.c index 02ac5b353..d80b7c096 100644 --- a/src/bio.c +++ b/src/bio.c @@ -229,7 +229,13 @@ 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); + #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) + else + ret = (int)XREAD(bio->num, buf, len); + #endif } #endif @@ -580,8 +586,14 @@ 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); + #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ + && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) + else + ret = (int)XWRITE(bio->num, data, len); + #endif } #endif @@ -940,11 +952,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; } } @@ -1320,6 +1334,31 @@ 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; + + 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"); @@ -1679,16 +1718,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; - if (p) { - *(byte**)p = (byte*)bio->ptr; + mem_bio = bio; + /* Return pointer from last memory BIO in chain */ + while (bio->next) { + bio = bio->next; + 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/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 c600c7b9d..5b46a1661 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; @@ -3432,6 +3428,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 */ @@ -3458,6 +3457,11 @@ void FreeX509(WOLFSSL_X509* x509) x509->key.pkey = NULL; } #endif /* OPENSSL_ALL */ + #if defined(WOLFSSL_CERT_REQ) && defined(OPENSSL_ALL) + if (x509->challengePwAttr) { + wolfSSL_X509_ATTRIBUTE_free(x509->challengePwAttr); + } + #endif /* WOLFSSL_CERT_REQ */ if (x509->altNames) { FreeAltNames(x509->altNames, x509->heap); x509->altNames = NULL; @@ -5263,6 +5267,64 @@ 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) { + 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; + 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; @@ -5271,10 +5333,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 @@ -9564,6 +9622,40 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) else x509->subjectCN[0] = '\0'; +#ifdef WOLFSSL_CERT_REQ + x509->isCSR = dCert->isCSR; + /* CSR attributes */ + if (dCert->cPwd) { + 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); + } + 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; + } +#endif + } + else { + WOLFSSL_MSG("Challenge password too long"); + ret = MEMORY_E; + } + } +#endif + #ifdef WOLFSSL_SEP { int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE); @@ -12106,6 +12198,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; @@ -15567,7 +15667,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, @@ -16756,6 +16860,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)) { @@ -20416,7 +20528,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/src/ssl.c b/src/ssl.c index b2aa70d4c..b457913b3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -110,6 +110,8 @@ #include #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) #include + #include + #include #endif /* WITH_STUNNEL */ #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #include @@ -440,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 @@ -1684,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) @@ -3584,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) { @@ -3621,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) /****************************************************************************** @@ -7397,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; } @@ -7507,7 +7540,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; } @@ -8001,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; } @@ -8032,7 +8065,12 @@ 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, +#ifdef WOLFSSL_CERT_REQ + passedCert->isCSR ? CERTREQ_TYPE : +#endif + CA_TYPE, + NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); return WOLFSSL_FAILURE; } @@ -8046,16 +8084,21 @@ 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; - } +#ifdef WOLFSSL_CERT_REQ + if (!passedCert->isCSR) +#endif + { + 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) { @@ -8224,6 +8267,67 @@ 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; + WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x; + 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 = generateExtStack(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) +{ + return generateExtStack(x); +} + /* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509. * * x509 : The X509 structure to look for the extension. @@ -8250,6 +8354,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* @@ -8294,7 +8422,12 @@ 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, +#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); return NULL; @@ -8310,18 +8443,23 @@ 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; - } +#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); + 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) { @@ -8691,6 +8829,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. */ @@ -8798,6 +9032,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) { @@ -9190,7 +9438,12 @@ 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, +#ifdef WOLFSSL_CERT_REQ + x509->isCSR ? CERTREQ_TYPE : +#endif + CA_TYPE, + NO_VERIFY, NULL) < 0) { WOLFSSL_MSG("\tCertificate parsing failed"); return WOLFSSL_FATAL_ERROR; } @@ -9204,16 +9457,21 @@ 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; - } +#ifdef WOLFSSL_CERT_REQ + if (!x509->isCSR) +#endif + { + 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) { @@ -9412,16 +9670,15 @@ 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; } } else { @@ -9691,18 +9948,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; @@ -9717,7 +9977,7 @@ err: wolfSSL_GENERAL_NAME_free(gn); } if (sk) { - wolfSSL_sk_ASN1_OBJECT_free(sk); + wolfSSL_sk_free(sk); } return NULL; } @@ -9780,15 +10040,13 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type) return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type); } - #ifndef NO_WOLFSSL_STUB -int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc) +WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc) { - WOLFSSL_STUB("wolfSSL_X509_add_ext"); + WOLFSSL_STUB("wolfSSL_X509_delete_ext"); (void)x509; - (void)ext; (void)loc; - return WOLFSSL_FAILURE; + return NULL; } /* currently LHASH is not implemented (and not needed for Apache port) */ @@ -12940,7 +13198,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"); @@ -13025,6 +13284,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 @@ -13209,7 +13469,8 @@ int AddSession(WOLFSSL* ssl) } for (i=0; ioptions.side) { WOLFSSL_MSG("Session already exists. Overwriting."); overwrite = 1; idx = i; @@ -13226,6 +13487,8 @@ int AddSession(WOLFSSL* ssl) session = &SessionCache[row].Sessions[idx]; } + session->side = (byte)ssl->options.side; + #ifdef WOLFSSL_TLS13 if (ssl->options.tls1_3) { XMEMCPY(session->masterSecret, ssl->session.masterSecret, SECRET_LEN); @@ -15040,6 +15303,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 */ @@ -15217,21 +15508,22 @@ 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) { - /* 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 @@ -15394,6 +15686,84 @@ 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; + 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; + } + + /** + * 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; + 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; + } + +#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; + WOLFSSL_ENTER("wolfSSL_BIO_do_connect"); + + if (!b) { + WOLFSSL_ENTER("Bad parameter"); + 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; + } + + b->num = sfd; + b->shutdown = BIO_CLOSE; + return WOLFSSL_SUCCESS; + } +#endif /* HAVE_HTTP_CLIENT */ int wolfSSL_BIO_eof(WOLFSSL_BIO* b) { @@ -15461,6 +15831,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 && @@ -15569,6 +15940,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 @@ -15765,6 +16142,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 */ @@ -15862,12 +16240,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) { @@ -15909,20 +16300,90 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) break; #endif default: - return BAD_FUNC_ARG; + return WOLFSSL_FAILURE; } - return WOLFSSL_SUCCESS; + switch (version) { + case TLS1_3_VERSION: +#ifdef WOLFSSL_TLS13 + 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 sanityCheckProtoVersion(ctx); } 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; - return WOLFSSL_SUCCESS; + if (!ctx || !ctx->method) { + 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; +#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 sanityCheckProtoVersion(ctx); } #endif /* OPENSSL_EXTRA */ @@ -17839,14 +18300,21 @@ 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* d2i_X509orX509REQ(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"); - 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 @@ -17861,7 +18329,10 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) #endif InitDecodedCert(cert, (byte*)in, len, NULL); - if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) { + #ifdef WOLFSSL_CERT_REQ + cert->isCSR = req; + #endif + if (ParseCertRelative(cert, type, 0, NULL) == 0) { newX509 = wolfSSL_X509_new(); if (newX509 != NULL) { if (CopyDecodedToX509(newX509, cert) != 0) { @@ -17895,6 +18366,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 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 d2i_X509orX509REQ(x509, in, len, 1); +} +#endif #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -18292,38 +18776,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_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_X509); - 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; - 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); } @@ -18448,39 +18907,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 @@ -18604,39 +19033,90 @@ 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; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + WOLFSSL_CIPHER ciph; +#endif 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 +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) case STACK_TYPE_CIPHER: - ret = wolfSSL_sk_CIPHER_push(sk, (WOLFSSL_CIPHER*) 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; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(&sk->data.cipher); + } + return WOLFSSL_SUCCESS; + } 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); - break; - #endif +#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; +#ifdef OPENSSL_ALL + if (sk->hash_fn) { + sk->hash = sk->hash_fn(sk->data.generic); + } +#endif + 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; +#ifdef OPENSSL_ALL + if (sk->hash_fn) { + sk->hash = sk->hash_fn(sk->data.generic); + } +#endif + break; + } + + return WOLFSSL_SUCCESS; } /* Creates and returns new GENERAL_NAME structure */ @@ -18948,33 +19428,793 @@ 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) + +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 WOLFSSL_FATAL_ERROR; + } + + 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 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; + int strLen; + byte digest[WC_MD5_DIGEST_SIZE]; + WOLFSSL_ENTER("wolfSSL_LH_strhash"); + + if (!str) + return 0; + +#ifndef NO_MD5 + 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 = (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 + 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."); + (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; +} + +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 = (int)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; + } + XMEMCPY(ret->section, section, slen+1); + + 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 (!val->name && XSTRCMP(section, val->section) == 0) { + return val; + } + } + sk = sk->next; + } + + return NULL; +} + +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)); + ret->data = wolfSSL_sk_CONF_VALUE_new(NULL); + if (!ret->data) { + wolfSSL_NCONF_free(ret); + return NULL; + } + } + 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; +} + +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 || !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 + * 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; +} + +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 = (int)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 = (int)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 = (int)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) +{ + int strLen = (int)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. + * format: ${section_name::var_name} */ + 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 && (XISALNUM(*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 = (int)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++;} +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 + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("malloc error"); + goto cleanup; + } + if (wolfSSL_BIO_read(in, buf, bufLen) != bufLen) { + 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", (unsigned int)(bufEnd - idx)); + char* maxIdx; + if (!lineEnd) + lineEnd = bufEnd; /* Last line in file */ + maxIdx = XSTRNSTR(idx, "#", (unsigned int)(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; + + if (idx < maxIdx) + idx++; + else { + WOLFSSL_MSG("Invalid section definition."); + goto cleanup; + } + + SKIP_WHITESPACE(idx, maxIdx); + sectionName = idx; + /* Find end of section name */ + while (idx < maxIdx && *idx != ' ' && *idx != ']') + idx++; + sectionNameLen = (int)(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; + char* exValue; /* expanded 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 = (int)(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-1; + while (idx >= value && (*idx == ' ' || *idx == '\t')) + idx--; + valueLen = (int)(idx - value + 1); + + /* Sanity checks */ + if (nameLen <= 0 || valueLen <= 0) { + WOLFSSL_MSG("Sanity checks failed"); + goto cleanup; + } + name[nameLen] = '\0'; + value[valueLen] = '\0'; + + if (!(exValue = expandValue(conf, section->section, value))) { + WOLFSSL_MSG("Variable expansion failed"); + goto cleanup; + } + + if (!(newVal = wolfSSL_CONF_VALUE_new_values(NULL, + 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"); + 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); + XFREE(conf, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +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; + 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* tmp; + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free"); + + if (sk == NULL) + return; + + /* parse through stack freeing each node */ + while (sk) { + tmp = sk->next; + wolfSSL_X509V3_conf_free(sk->data.conf); + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + sk = tmp; + } +} + +int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_num"); + if (sk) + return 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; +} + +/* 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); @@ -19429,9 +20669,10 @@ 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) +static WOLFSSL_X509* loadX509orX509REQFromBuffer( + const unsigned char* buf, int sz, int format, int type) { + int ret; WOLFSSL_X509* x509 = NULL; DerBuffer* der = NULL; @@ -19440,7 +20681,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 @@ -19448,7 +20689,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); } @@ -19470,7 +20711,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) { @@ -19494,7 +20735,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 loadX509orX509REQFromBuffer(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 loadX509orX509REQFromBuffer(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 */ @@ -19643,39 +20900,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); } @@ -19799,6 +21030,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) @@ -20242,19 +21511,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"); @@ -20321,6 +21585,267 @@ 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(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'; + idx = buf; + 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", (unsigned int)(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 */ + XMEMSET(strBuf, 0, fieldsSz); + /* Check for appropriate number of fields */ + fieldPtr = (char**)strBuf; + fieldCheckIdx = strBuf + fieldsSz; + fieldPtr[fieldPtrIdx++] = fieldCheckIdx; + while (*fieldCheckIdx != '\0') { + /* Handle escaped tabs */ + if (*fieldCheckIdx == '\t' && fieldCheckIdx[-1] != '\\') { + 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; +} + +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++) { + const char* fieldValue = fields[i]; + if (!fieldValue) { + fieldValue = ""; + } + + /* 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 = (int)(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); + } + 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) +{ + WOLFSSL_ENTER("wolfSSL_TXT_DB_get_by_index"); + + if (!db || !db->data || 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; + } + + /* 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; + } + } + return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value); +} #endif #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ @@ -20417,7 +21942,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; } @@ -21022,6 +22547,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) || \ @@ -21854,10 +23399,78 @@ 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; + 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 /* NO_FILESYSTEM */ + #endif /* XSNPRINTF */ #endif /* !NO_BIO */ + 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) { + 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 /* OPENSSL_EXTRA */ + #endif /* !NO_CERTS */ #ifdef OPENSSL_EXTRA @@ -22647,9 +24260,64 @@ 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. + * + * 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 + */ +static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req) +{ + int ret = WOLFSSL_FAILURE; + /* Get large buffer to hold cert der */ + int derSz = X509_BUFFER_SZ; +#ifdef WOLFSSL_SMALL_STACK + byte* der; +#else + byte der[X509_BUFFER_SZ]; +#endif + WOLFSSL_ENTER("wolfSSL_i2d_X509_bio"); + + if (bio == NULL || x509 == NULL) { + return WOLFSSL_FAILURE; + } + +#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(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) { + goto cleanup; + } + + 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 @@ -22659,25 +24327,16 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, */ int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) { - 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; - - if (wolfSSL_BIO_write(bio, der, len) == (int)len) { - return WOLFSSL_SUCCESS; - } - } - - return WOLFSSL_FAILURE; + return loadX509orX509REQFromBio(bio, x509, 0); } -#endif /* !NO_BIO */ +#ifdef WOLFSSL_CERT_REQ +int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509) +{ + return loadX509orX509REQFromBio(bio, x509, 1); +} +#endif /* WOLFSSL_CERT_REQ */ +#endif /* WOLFSSL_CERT_GEN */ /* Converts an internal structure to a DER buffer * @@ -22720,21 +24379,20 @@ 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* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio, + WOLFSSL_X509** x509, int req) { WOLFSSL_X509* localX509 = NULL; - unsigned char* mem = NULL; - int ret; - word32 size; + byte* mem = NULL; + int size; WOLFSSL_ENTER("wolfSSL_d2i_X509_bio"); @@ -22743,15 +24401,36 @@ 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_get_len(bio); + if (size == 0) { + WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data."); return NULL; } - size = ret; - localX509 = wolfSSL_X509_d2i(NULL, mem, size); + 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; + } + + 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); return NULL; } @@ -22759,10 +24438,22 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) *x509 = localX509; } + XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); return localX509; } #endif /* !NO_BIO */ +WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) +{ + 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 d2i_X509orX509REQ_bio(bio, x509, 1); +} +#endif #if !defined(NO_ASN) && !defined(NO_PWDBASED) #ifndef NO_BIO @@ -23232,6 +24923,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 */ @@ -23265,7 +24969,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); @@ -23315,7 +25018,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } } #endif - + ctx->chain = sk; } #endif /* SESSION_CERTS */ @@ -23342,6 +25045,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) { @@ -23447,9 +25159,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; } @@ -23549,13 +25258,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; @@ -23658,22 +25366,28 @@ 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; } - /* 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 verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req) { int ret; const byte* der; int derSz = 0; int type; + (void)req; + if (x509 == NULL || pkey == NULL) { return WOLFSSL_FATAL_ERROR; } @@ -23702,13 +25416,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 verifyX509orX509REQ(x509, pkey, 0); +} + +#ifdef WOLFSSL_CERT_REQ +int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) +{ + return verifyX509orX509REQ(x509, pkey, 1); +} +#endif /* WOLFSSL_CERT_REQ */ #endif /* !NO_CERTS */ #if !defined(NO_FILESYSTEM) @@ -23863,8 +25595,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) */ @@ -25819,6 +27551,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; @@ -25920,10 +27659,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; } @@ -26008,6 +27751,127 @@ 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, cls; + 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, &cls, 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 + * @param len Length of parsed ASN1 object + * @param tag Tag value 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 + * 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 *cls, long inLen) +{ + word32 inOutIdx = 0; + int l; + byte t; + int ret = 0x80; + + WOLFSSL_ENTER("wolfSSL_ASN1_get_object"); + + if (!in || !*in || !len || !tag || !cls || inLen == 0) { + WOLFSSL_MSG("Bad parameter"); + return ret; + } + + if (GetASNTag(*in, &inOutIdx, &t, (word32)inLen) != 0) { + WOLFSSL_MSG("GetASNTag error"); + return ret; + } + + if (GetLength(*in, &inOutIdx, &l, (word32)inLen) < 0) { + WOLFSSL_MSG("GetLength error"); + return ret; + } + + *tag = t & 0x1F; /* Tag number is 5 lsb */ + *cls = t & 0xC0; /* Class is 2 msb */ + *len = l; + ret = t & ASN_CONSTRUCTED; + + if (l > (int)(inLen - inOutIdx)) { + /* Still return other values but indicate error in msb */ + ret |= 0x80; + } + + *in += inOutIdx; + return ret; +} + +WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, + const unsigned char **pp, long len) +{ + WOLFSSL_ASN1_OBJECT* ret = NULL; + + WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT"); + + 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 = (unsigned int)len; + ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; + + *pp += len; + + if (a) + *a = ret; + return ret; +} + #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, @@ -26087,29 +27951,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 @@ -27318,13 +29194,35 @@ 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) +{ + int slen; + WOLFSSL_ENTER("wolfSSL_ASN1_TIME_set_string"); + + if (!str) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + slen = (int)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 */ #ifndef NO_BIO @@ -27388,7 +29286,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) @@ -27396,7 +29294,7 @@ int wolfSSL_sk_num(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"); @@ -27419,7 +29317,7 @@ void* wolfSSL_sk_value(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; @@ -27542,6 +29440,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); @@ -27590,38 +29491,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) { @@ -27682,33 +29554,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) @@ -27868,9 +29713,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; @@ -27922,6 +29768,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; @@ -28040,11 +29887,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++]; @@ -28406,6 +30254,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 */ @@ -28435,6 +30287,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 @@ -29121,6 +30975,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) { @@ -29145,9 +31002,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); @@ -29159,7 +31017,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)) { @@ -29169,6 +31026,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; @@ -29396,7 +31259,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) { @@ -29420,14 +31283,15 @@ 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; } - void wolfSSL_DH_free(WOLFSSL_DH* dh) { - WOLFSSL_MSG("wolfSSL_DH_free"); + WOLFSSL_ENTER("wolfSSL_DH_free"); if (dh) { if (dh->internal) { @@ -29551,6 +31415,46 @@ 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; + + 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; +} +#endif /* WOLFSSL_DH_EXTRA */ + /* Set the members of DhKey into WOLFSSL_DH * DhKey was populated from wc_DhKeyDecode */ @@ -30196,8 +32100,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; @@ -37010,10 +38912,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 */ @@ -37026,10 +38928,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 */ @@ -37648,7 +39550,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"); @@ -37768,6 +39670,14 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) cert->keyUsage = req->keyUsage; /* Extended Key Usage not supported. */ #endif + #ifdef WOLFSSL_CERT_REQ + 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; @@ -38001,10 +39911,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) + static 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; @@ -38013,6 +39924,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; @@ -38070,6 +39984,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"); @@ -38091,14 +40020,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; @@ -38107,12 +40042,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) @@ -38123,13 +40080,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) wc_ecc_free(&ecc); #endif - if (ret > 0) { - *derSz = ret; - return WOLFSSL_SUCCESS; - } - else { - return ret; - } + return ret; } @@ -38150,6 +40101,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) int sigType; WC_RNG rng; + (void)req; + sigType = wolfSSL_sigTypeFromPKEY(md, pkey); if (sigType == WOLFSSL_FAILURE) return WOLFSSL_FATAL_ERROR; @@ -38169,7 +40122,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) } #endif - /* Sign the certificate request body. */ + /* Sign the certificate (request) body. */ ret = wc_InitRng(&rng); if (ret != 0) return ret; @@ -38177,22 +40130,62 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) wc_FreeRng(&rng); if (ret < 0) return ret; + derSz = ret; + + /* 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; + } /* Put in the new certificate encoding into the x509 object. */ FreeDer(&x509->derCert); type = CERT_TYPE; - #ifdef WOLFSSL_REQ_CERT + #ifdef WOLFSSL_CERT_REQ if (req) { type = CERTREQ_TYPE; } #endif - - if (AllocDer(&x509->derCert, ret, type, NULL) != 0) + if (AllocDer(&x509->derCert, derSz, type, NULL) != 0) return WOLFSSL_FATAL_ERROR; - XMEMCPY(x509->derCert->buffer, der, ret); - x509->derCert->length = ret; + XMEMCPY(x509->derCert->buffer, der, derSz); + x509->derCert->length = derSz; - (void)req; return ret; } @@ -38208,7 +40201,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"); @@ -38219,7 +40212,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); @@ -38242,8 +40235,19 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return ret; } -#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)); + } +#endif /* WOLFSSL_CERT_GEN */ #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name, @@ -38327,22 +40331,21 @@ 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 *loadX509orX509REQFromPemBio(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"); + WOLFSSL_ENTER("loadX509orX509REQFromPemBio"); - if (bp == NULL) { + if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) { WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG); return NULL; } @@ -38360,21 +40363,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 = (long)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; } @@ -38384,8 +40393,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; @@ -38402,6 +40417,21 @@ cleanup: return x509; } + + WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, + pem_password_cb *cb, void *u) + { + 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 loadX509orX509REQFromPemBio(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) { @@ -38560,6 +40590,7 @@ err: } #endif +#ifdef WOLFSSL_CERT_GEN #ifndef NO_BIO int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x) { @@ -38586,6 +40617,7 @@ err: return ret; } #endif /* !NO_BIO */ +#endif /* WOLFSSL_CERT_GEN */ #endif /* !NO_FILESYSTEM */ #define PEM_BEGIN "-----BEGIN " @@ -38992,8 +41024,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); } @@ -39037,6 +41069,161 @@ 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 = pem_struct_min_sz, 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[0], pem_struct_min_sz) != + pem_struct_min_sz) { + goto err; + } + + /* Read the header and footer */ + while ((l = wolfSSL_BIO_read(bio, &pem[i], 1)) == 1) { + i++; + if (!header) + header = XSTRNSTR(pem, "-----BEGIN ", (unsigned int)i); + else if (header) { + if (!headerEnd) { + headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "), + "-----", + (unsigned int) + (i - (header + XSTR_SIZEOF("-----BEGIN ") - 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 ", + (unsigned int)(i - (headerEnd - pem))); + } + else if (!footerEnd) { + footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"), + "-----", (unsigned int)(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); + goto err; + } + 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, + (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-----", + 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; + } + } +#endif + 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 @@ -39050,44 +41237,76 @@ 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); +#ifdef HAVE_CRL + wolfSSL_X509_CRL_free(crl); +#endif + 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; } @@ -39179,6 +41398,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) { @@ -39393,6 +41617,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) @@ -39401,8 +41626,28 @@ err: wolfSSL_X509_NAME_ENTRY_free(entry); return ret; } - #endif /* !NO_CERTS */ + 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; + } + name->entry[loc].set = 0; + return ret; + } + +#endif /* !NO_CERTS */ /* NID variables are dependent on compatibility header files currently * @@ -39649,6 +41894,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) || \ @@ -39855,6 +42102,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, @@ -39986,6 +42237,7 @@ err: { word32 oid = 0; word32 idx = 0; + int ret; WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid"); @@ -40003,9 +42255,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 = (byte*)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); @@ -40062,10 +42334,36 @@ 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); + if (a && b && a->obj && b->obj) { + if (a->objSz == b->objSz) { + return XMEMCMP(a->obj, b->obj, a->objSz); + } + 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; + } + } + } } return WOLFSSL_FATAL_ERROR; @@ -40155,7 +42453,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"); @@ -40164,10 +42462,27 @@ 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 (ret == 0 && outSz > 0) { + /* 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); @@ -40177,11 +42492,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; } @@ -40273,17 +42584,20 @@ 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"); - return WOLFSSL_SUCCESS; + if (!x509 || !key) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz, + x509->pubKey.buffer, x509->pubKey.length, + (enum Key_Sum)x509->pubKeyOID) == 1 ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } -#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. @@ -40578,7 +42892,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) @@ -40651,6 +42964,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 || !dst || !src) + 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 */ @@ -41304,14 +43648,18 @@ 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) { - byte* pem; + byte* pem = NULL; int pemSz = 0; - const unsigned char* der; - int derSz; + /* Get large buffer to hold cert der */ + int derSz = X509_BUFFER_SZ; +#ifdef WOLFSSL_SMALL_STACK + byte* der; +#else + byte der[X509_BUFFER_SZ]; +#endif int ret; WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()"); @@ -41321,25 +43669,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 */ @@ -41348,11 +43702,19 @@ 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 /* 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) @@ -41684,9 +44046,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; } @@ -41734,7 +44096,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); @@ -41841,9 +44203,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; } @@ -41881,7 +44243,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); @@ -42313,7 +44675,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; @@ -42783,6 +45145,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) { @@ -44392,6 +46774,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"); @@ -44492,14 +46875,104 @@ WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl) #endif /* NO_SESSION_CACHE */ -#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; + byte intTag[MAX_LENGTH_SZ + 1]; + int idx = 0; + + 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 = (byte*)XREALLOC(asn1->data, len + extraTagSz, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!tmp) { + WOLFSSL_MSG("realloc error"); + return WOLFSSL_FAILURE; + } + asn1->data = tmp; + } + else { + asn1->data = (byte*)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 */ + 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; +} + 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"); @@ -44507,32 +46980,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. */ @@ -44541,14 +46991,12 @@ 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 || + bufLen <= 0) { + return 0; } - /* Two nibbles written for each byte. */ - return len * 2; + return wolfSSL_BIO_write(bp, buf, bufLen - 1); /* Don't write out NULL char */ } #endif /* !NO_BIO */ @@ -44969,7 +47417,35 @@ 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, +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; +} + +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) { for (; idx > 0 && strings != NULL; idx--) @@ -44979,10 +47455,15 @@ char* wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings, return strings->data.string; } +int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) +{ + if (strings) + return (int)strings->num; + return 0; +} #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"); @@ -44994,7 +47475,6 @@ 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 */ #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ @@ -45262,6 +47742,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, (word32)len); +} + int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p, unsigned int p_len) { @@ -45353,6 +47839,7 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, int oid2nid(word32 oid, int grp) { + size_t i; /* get OID type */ switch (grp) { /* oidHashType */ @@ -45393,6 +47880,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: @@ -45674,9 +48163,25 @@ int oid2nid(word32 oid, int grp) } break; +#ifdef WOLFSSL_CERT_REQ + case oidCsrAttrType: + switch (oid) { + case CHALLENGE_PASSWORD_OID: + return NID_pkcs9_challengePassword; + case SERIAL_NUMBER_OID: + return NID_serialNumber; + } + break; +#endif + 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; @@ -48263,8 +50768,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; } @@ -48299,20 +50806,26 @@ 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); } } + 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; word32 idx = 0; - if (in == NULL) + WOLFSSL_ENTER("wolfSSL_d2i_PKCS7"); + + if (in == NULL || *in == NULL) return NULL; if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL) @@ -48330,10 +50843,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; } @@ -48342,6 +50858,9 @@ 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"); if (bio == NULL) return NULL; @@ -48349,23 +50868,83 @@ 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); 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; + } if (p7 != NULL) *p7 = (PKCS7*)pkcs7; return (PKCS7*)pkcs7; } +int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7) +{ + byte* output = NULL; + int len; + WC_RNG rng; + int ret = WOLFSSL_FAILURE; + WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio"); + + if (!bio || !p7) { + WOLFSSL_MSG("Bad parameter"); + 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"); + goto cleanup; + } + + output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!output) { + WOLFSSL_MSG("malloc error"); + goto cleanup; + } + + if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) { + WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error"); + goto cleanup; + } + + if (wolfSSL_BIO_write(bio, output, len) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + goto cleanup; + } + + 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, WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags) @@ -48375,6 +50954,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; @@ -48393,8 +50974,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; @@ -48409,8 +50989,136 @@ 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; + WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs"); + + if (!pkcs7 || !certs || !out) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + p7 = (WOLFSSL_PKCS7*)pkcs7; + + /* 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; + } + + if (certs) { + /* Save some of the values */ + 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(pkcs7, certs->data.x509->derCert->buffer, + certs->data.x509->derCert->length) != 0) { + WOLFSSL_MSG("wc_PKCS7_InitWithCert error"); + return WOLFSSL_FAILURE; + } + certs = certs->next; + + pkcs7->hashOID = hashOID; + pkcs7->version = version; + } + + /* 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(pkcs7, certs->data.x509->derCert->buffer, + certs->data.x509->derCert->length) != 0) { + WOLFSSL_MSG("wc_PKCS7_AddCertificate error"); + return WOLFSSL_FAILURE; + } + certs = certs->next; + } + + if (wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID) != 0) { + WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error"); + return WOLFSSL_FAILURE; + } + + ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7); + + return ret; +} #endif /* !NO_BIO */ +/** + * 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)* + */ +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 NULL; + } + + if (p7->certs) + 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]); + if (!ret) + ret = wolfSSL_sk_X509_new(); + 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, int flags) { @@ -49040,7 +51748,7 @@ 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; WOLFSSL_ENTER("wolfSSL_X509_set_pubkey"); if (cert == NULL || pkey == NULL) @@ -49050,18 +51758,39 @@ 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; - p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (p == NULL) - 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) { + 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 +#endif + { + 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; } @@ -49079,7 +51808,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, @@ -49091,6 +51820,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); @@ -49117,29 +51852,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) @@ -49163,7 +51914,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) != WOLFSSL_SUCCESS) { + if (wolfssl_x509_make_der(req, 1, der, &derSz, 0) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } @@ -49174,17 +51925,286 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, return WOLFSSL_SUCCESS; } - -#ifndef NO_WOLFSSL_STUB -int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, - WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext) +int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, + WOLFSSL_EVP_MD_CTX* md_ctx) { - (void)req; - (void)ext; - return WOLFSSL_FATAL_ERROR; + 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; } + +static int regenX509REQDerBuffer(WOLFSSL_X509* x509) +{ + 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 + 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("Unable to make DER for X509 REQ"); + } +#ifdef WOLFSSL_SMALL_STACK + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; +} + +int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, + WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk) +{ + if (!req || !ext_sk) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + while (ext_sk) { + WOLFSSL_X509_EXTENSION* ext = ext_sk->data.ext; + + 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 regenX509REQDerBuffer(req); +} + +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"); + +#ifdef HAVE_LIBEST + if (!req || !attrname || !bytes || type != MBSTRING_ASC) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (len < 0) { + len = (int)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 */ + return WOLFSSL_SUCCESS; +#else + (void)req; + (void)attrname; + (void)type; + (void)bytes; + (void)len; + return WOLFSSL_FAILURE; +#endif +} + +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 = (int)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; + case NID_serialNumber: + if (len < 0) + len = (int)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; + } + 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"); + + /* 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"); + + 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; +} + +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) { @@ -49195,7 +52215,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, @@ -49326,4 +52346,4 @@ int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo, #endif /* WOLFSSL_STATIC_EPHEMERAL */ -#endif /* WOLFCRYPT_ONLY */ +#endif /* !WOLFCRYPT_ONLY */ 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 3f9a2f7a3..5af0d206d 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 @@ -4903,6 +4907,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 @@ -25282,6 +25288,21 @@ static int test_wc_HashGetFlags(void) | Compatibility Tests *----------------------------------------------------------------------------*/ +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) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \ @@ -25917,6 +25938,39 @@ 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 = NULL; + 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); + pkey = NULL; + + /* 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) { @@ -26241,6 +26295,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)); @@ -26260,6 +26315,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; } @@ -26272,6 +26332,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)); @@ -26289,6 +26351,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; } @@ -26751,6 +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; @@ -26779,6 +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 @@ -26790,6 +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); @@ -27583,8 +27662,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); @@ -27597,6 +27675,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) && defined(HAVE_PKCS7) + 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); + AssertNotNull(d2i_PKCS7(&p7, &p, buflen)); + /* 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)); + } + + BIO_free(bio); + PKCS7_free(p7); + } + + printf(resultFmt, passed); +#endif /* defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(HAVE_PKCS7) */ +} static void test_wolfSSL_X509_STORE_CTX(void) { @@ -27630,6 +27763,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); @@ -27658,7 +27794,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 @@ -27995,6 +28132,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; @@ -28013,6 +28151,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); @@ -29247,9 +29391,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); @@ -29308,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()); @@ -29405,6 +29549,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; @@ -29472,6 +29617,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 @@ -29539,6 +29689,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); @@ -29548,7 +29704,7 @@ static void test_wolfSSL_X509_sign(void) AssertIntEQ(X509_get_ext_count(x509), SSL_FAILURE); #endif - + EVP_MD_CTX_free(mctx); EVP_PKEY_free(priv); EVP_PKEY_free(pub); X509_free(x509); @@ -29705,6 +29861,7 @@ static void test_wolfSSL_X509_PUBKEY(void) X509_PUBKEY_free(pubKey2); X509_free(x509); + EVP_PKEY_free(evpKey); printf(resultFmt, passed); #endif @@ -30080,7 +30237,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); @@ -31088,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()"); @@ -31103,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); @@ -33168,6 +33329,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) @@ -33276,10 +33467,13 @@ static void test_wolfSSL_X509_PUBKEY_get(void) { WOLFSSL_X509_PUBKEY pubkey; WOLFSSL_X509_PUBKEY* key; - WOLFSSL_EVP_PKEY evpkey; + 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; @@ -34772,6 +34966,96 @@ 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", + }; + char** fields_copy; + + 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)); + 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 */ + 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 */ @@ -36406,6 +36690,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 +36733,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); @@ -36488,6 +36780,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), @@ -36513,6 +36810,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); @@ -37871,6 +38180,147 @@ static void test_wolfSSL_X509_CRL(void) return; } +static void test_wolfSSL_d2i_X509_REQ(void) +{ +#if defined(WOLFSSL_CERT_REQ) && (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) + /* ./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.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 \ + * -outform PEM + * with the passphrase "wolfSSL" + */ +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) + const char* csrDsaFile = "./certs/csr.dsa.pem"; +#endif + 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)); + + /* + * 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); + 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)); + + /* + * 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), "2xIE+qqp/rhyTXP+"); + AssertIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1); +#endif + + X509_free(req); + BIO_free(bio); + EVP_PKEY_free(pub_key); + } + { +#ifdef OPENSSL_ALL + X509_ATTRIBUTE* attr; + ASN1_TYPE *at; + 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. */ + 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 + AssertNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(req)); + AssertIntEQ(sk_X509_EXTENSION_num(exts), 2); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + /* + * 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"); + 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); + } +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) + { + 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); + EVP_PKEY_free(pub_key); + } +#endif /* !NO_DSA && !HAVE_SELFTEST */ +#endif /* WOLFSSL_CERT_REQ && (OPENSSL_ALL || OPENSSL_EXTRA) */ +} + static void test_wolfSSL_PEM_read_X509(void) { #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \ @@ -38628,6 +39078,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 printf(testingFmt, "wolfSSL_X509_print"); x509 = X509_load_certificate_file(svrCertFile, WOLFSSL_FILETYPE_PEM); @@ -38644,13 +39097,21 @@ static void test_wolfSSL_X509_print() #endif BIO_free(bio); + AssertNotNull(bio = BIO_new_fd(STDOUT_FILENO, 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 */ - 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 } @@ -38665,8 +39126,7 @@ static void test_wolfSSL_RSA_print() 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 = BIO_new_fd(STDOUT_FILENO, BIO_NOCLOSE)); AssertIntEQ(RSA_print(bio, rsa, 0), SSL_SUCCESS); BIO_free(bio); @@ -38750,6 +39210,64 @@ static void test_wolfSSL_ASN1_STRING_print(void){ #endif /* !NO_BIO */ +static void test_wolfSSL_ASN1_get_object(void) +{ +#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, 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, &cls, len) & 0x80, 0); + AssertIntEQ(asnLen, 863); + AssertIntEQ(tag, 0x10); + AssertIntEQ(cls, 0); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 772); + AssertIntEQ(tag, 0x10); + AssertIntEQ(cls, 0); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 3); + AssertIntEQ(tag, 0); + AssertIntEQ(cls, 0x80); + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 1); + AssertIntEQ(tag, 0x2); + AssertIntEQ(cls, 0); + derBuf += asnLen; + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 20); + AssertIntEQ(tag, 0x2); + AssertIntEQ(cls, 0); + derBuf += asnLen; + + AssertIntEQ(ASN1_get_object(&derBuf, &asnLen, &tag, &cls, + len - (derBuf - cliecc_cert_der_256)) & 0x80, 0); + AssertIntEQ(asnLen, 10); + AssertIntEQ(tag, 0x10); + AssertIntEQ(cls, 0); + + /* Read an ASN OBJECT */ + AssertNotNull(d2i_ASN1_OBJECT(&a, &derBuf, len)); + ASN1_OBJECT_free(a); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA && HAVE_ECC && USE_CERT_BUFFERS_256 */ +} + static void test_wolfSSL_RSA_verify() { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && \ @@ -39424,6 +39942,7 @@ void ApiTest(void) test_wolfSSL_mcast(); /* compatibility tests */ + test_wolfSSL_lhash(); test_wolfSSL_X509_NAME(); #ifndef NO_BIO test_wolfSSL_X509_INFO(); @@ -39433,6 +39952,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(); @@ -39467,6 +39987,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(); @@ -39551,6 +40072,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 @@ -39589,6 +40111,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(); @@ -39627,6 +40150,8 @@ void ApiTest(void) test_IncCtr(); test_wolfSSL_OBJ_ln(); test_wolfSSL_OBJ_sn(); + test_wolfSSL_TXT_DB(); + test_wolfSSL_NCONF(); #endif /* OPENSSL_ALL */ @@ -39659,6 +40184,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/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 70b473dfc..6a635ce82 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 @@ -524,6 +530,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 +584,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 @@ -647,7 +656,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; @@ -934,7 +943,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; @@ -1469,6 +1478,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 @@ -1660,6 +1670,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}; @@ -1752,6 +1769,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 @@ -2287,6 +2308,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 +2489,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; } @@ -2866,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; @@ -2919,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) @@ -2953,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; @@ -2983,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)) @@ -2992,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 @@ -3018,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 @@ -3039,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 */ @@ -3061,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 @@ -3082,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 */ @@ -3106,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 @@ -5453,6 +5510,7 @@ static int GetKey(DecodedCert* cert) } #endif /* NO_DSA */ default: + WOLFSSL_MSG("Unknown or not compiled in key OID"); return ASN_UNKNOWN_OID_E; } } @@ -6673,19 +6731,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; @@ -6988,10 +7052,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 @@ -7003,6 +7067,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); @@ -7083,6 +7153,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; @@ -7190,9 +7261,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, @@ -7208,7 +7279,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 @@ -7217,6 +7288,59 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* !NO_RSA */ + #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) + 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 && !HAVE_SELFTEST */ #ifdef HAVE_ECC case ECDSAk: { @@ -7324,7 +7448,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); } @@ -7334,7 +7458,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, @@ -7351,12 +7475,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 */ + #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 && !HAVE_SELFTEST */ #if defined(HAVE_ECC) case ECDSAk: { @@ -7455,6 +7587,19 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* NO_RSA */ + #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) + 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 && !HAVE_SELFTEST */ #ifdef HAVE_ECC case ECDSAk: { @@ -8766,18 +8911,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) { @@ -9091,6 +9241,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. @@ -9098,7 +9249,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]; @@ -9175,13 +9326,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; } @@ -9189,14 +9341,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 */ @@ -9210,123 +9362,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) @@ -9352,6 +9518,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) @@ -9396,15 +9565,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 */ @@ -9414,16 +9591,24 @@ 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 byte* tsip_encRsaKeyIdx; +#ifdef WOLFSSL_CERT_REQ + int len = 0; +#endif if (cert == NULL) { 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; @@ -9436,6 +9621,103 @@ 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) { + 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; + } + 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; + if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) { + XMEMCPY(cert->serial, cert->sNum, cert->sNumLen); + 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; + } + } + } + } +#endif + if (cert->srcIdx < cert->sigIndex) { #ifndef ALLOW_V1_EXTENSIONS if (cert->version < 2) { @@ -9465,14 +9747,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 @@ -9985,8 +10276,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 @@ -10029,11 +10321,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) { @@ -10559,8 +10849,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 { @@ -12104,83 +12394,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 */ @@ -13172,9 +13385,84 @@ 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, + WC_RNG* rng, const byte* ntruKey, word16 ntruSz, DsaKey* dsaKey, ed25519_key* ed25519Key, ed448_key* ed448Key) { int ret; @@ -13184,7 +13472,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; } @@ -13232,6 +13520,15 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, } #endif +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) + 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) @@ -13707,7 +14004,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]; @@ -13736,7 +14033,7 @@ static 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; @@ -13746,12 +14043,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); @@ -13759,7 +14067,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) @@ -13781,12 +14089,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) @@ -13794,14 +14105,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); } @@ -13811,7 +14122,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); } @@ -13823,9 +14134,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 }; @@ -13845,7 +14153,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]) { @@ -13856,8 +14164,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) { @@ -13872,8 +14183,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); @@ -13898,8 +14211,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; @@ -13909,7 +14222,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; } @@ -13956,6 +14269,15 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, } #endif +#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) + 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) @@ -13996,6 +14318,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) { @@ -14057,6 +14393,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) { @@ -14146,8 +14493,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 @@ -14156,8 +14503,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, @@ -14166,7 +14523,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) @@ -14186,12 +14543,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) @@ -14199,14 +14559,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/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index e19d5a49b..0c9f18275 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -2079,6 +2079,45 @@ 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 ((ret = mp_copy(&src->p, &dst->p)) != MP_OKAY) { + WOLFSSL_MSG("mp_copy 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 ((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; + } + + dst->heap = src->heap; + + return MP_OKAY; +} + /* 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/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 77d579349..6ef7214ca 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; } @@ -1385,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; } @@ -1432,7 +1427,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) { @@ -1873,6 +1880,89 @@ 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->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; + } + 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; + } +#if defined(HAVE_ECC) || !defined(NO_DSA) + return WOLFSSL_SUCCESS; +#endif +} + #ifndef NO_WOLFSSL_STUB WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey) { @@ -2202,7 +2292,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. */ @@ -2212,6 +2301,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; @@ -2282,21 +2384,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; } @@ -2306,10 +2403,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; @@ -2328,12 +2422,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; @@ -2437,7 +2528,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); @@ -2468,10 +2559,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) { @@ -2501,7 +2589,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; @@ -2586,9 +2674,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); @@ -2600,7 +2686,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; @@ -3171,11 +3257,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] = (char)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; @@ -5314,7 +5410,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; } @@ -5328,7 +5424,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 @@ -5594,6 +5693,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"); @@ -5663,11 +5766,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) { @@ -6482,7 +6589,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; @@ -6490,13 +6597,39 @@ 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) +{ + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get_default_digest_nid"); + + if (!pkey || !pnid) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + 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 */ int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey) @@ -6508,10 +6641,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/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/pkcs12.c b/wolfcrypt/src/pkcs12.c index 705c63bfb..10bb8b3cc 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 @@ -940,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/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 7dbd4aace..bb560b1b0 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; @@ -1260,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; @@ -2234,6 +2241,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) @@ -2268,9 +2276,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 || - output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 || + if (pkcs7 == NULL || pkcs7->hashOID == 0 || + outputSz == NULL || hashSz == 0 || hashBuf == NULL) { return BAD_FUNC_ARG; } @@ -2441,7 +2448,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); @@ -2506,11 +2513,16 @@ 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); #endif + if (*outputSz == 0 && *output2Sz == 0) { + *outputSz = totalSz; + *output2Sz = total2Sz; + return 0; + } return BUFFER_E; } @@ -2524,7 +2536,20 @@ 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); + #endif + if (*outputSz == 0) { + *outputSz = totalSz; + return totalSz; + } + return BUFFER_E; + } + + if (output == NULL) { + if (flatSignedAttribs) XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); #ifdef WOLFSSL_SMALL_STACK XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -2746,7 +2771,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; } @@ -4890,15 +4915,22 @@ 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; 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/internal.h b/wolfssl/internal.h index 084beceea..532a68f29 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2031,6 +2031,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*); @@ -3238,6 +3240,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 */ }; @@ -3622,6 +3626,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 { @@ -3633,7 +3639,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; @@ -3687,6 +3695,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) @@ -3758,9 +3767,15 @@ struct WOLFSSL_X509 { byte authKeyIdCrit:1; byte issuerSet: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 +#ifdef OPENSSL_ALL + WOLFSSL_X509_ATTRIBUTE* challengePwAttr; +#endif char challengePw[CTC_NAME_SIZE]; /* for REQ certs */ #endif WOLFSSL_X509_NAME issuer; @@ -4292,6 +4307,15 @@ struct WOLFSSL { #ifdef WOLFSSL_STATIC_EPHEMERAL 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 }; @@ -4451,6 +4475,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); diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index f9f806b89..8085f0c93 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -32,6 +32,10 @@ #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 d2i_ASN1_OBJECT wolfSSL_d2i_ASN1_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 */ #define V_ASN1_NEG 0x100 @@ -66,10 +70,21 @@ #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_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 #define ASN1_STRING_FLAG_BITS_LEFT 0x008 #define ASN1_STRING_FLAG_NDEF 0x010 @@ -83,6 +98,12 @@ 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 *cls, 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/bio.h b/wolfssl/openssl/bio.h index 62841a744..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 @@ -57,6 +64,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 +131,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 @@ -149,6 +158,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..5f1946dda 100644 --- a/wolfssl/openssl/buffer.h +++ b/wolfssl/openssl/buffer.h @@ -34,12 +34,18 @@ 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 #define BUF_MEM_grow wolfSSL_BUF_MEM_grow #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" */ #endif diff --git a/wolfssl/openssl/cms.h b/wolfssl/openssl/cms.h new file mode 100644 index 000000000..e86a21f0a --- /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_CMS_H_ +#define WOLFSSL_CMS_H_ + + +#endif /* WOLFSSL_CMS_H_ */ diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index 373239ff6..a56983ef1 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -28,18 +28,76 @@ extern "C" { #endif -struct WOLFSSL_CONF_VALUE { +#include +#include + +typedef struct WOLFSSL_CONF_VALUE { char *section; char *name; char *value; -}; +} WOLFSSL_CONF_VALUE; -struct WOLFSSL_INIT_SETTINGS { - char* appname; -}; +/* ssl.h requires WOLFSSL_CONF_VALUE */ +#include -typedef struct WOLFSSL_CONF_VALUE CONF_VALUE; -typedef struct WOLFSSL_INIT_SETTINGS OPENSSL_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; + +#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_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); +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_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 +#define _CONF_new_section wolfSSL_CONF_new_section +#define _CONF_get_section wolfSSL_CONF_get_section + +#define X509V3_conf_free wolfSSL_X509V3_conf_free + +#endif /* OPENSSL_EXTRA */ #ifdef __cplusplus } /* extern "C" */ 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/dh.h b/wolfssl/openssl/dh.h index ff021ed8b..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" { @@ -58,6 +59,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/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/evp.h b/wolfssl/openssl/evp.h index fa1065a9d..b84058b03 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); @@ -569,11 +572,13 @@ 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); -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); @@ -825,11 +830,14 @@ 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 #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 #define EVP_SignInit wolfSSL_EVP_SignInit #define EVP_SignInit_ex wolfSSL_EVP_SignInit_ex @@ -917,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 diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index c4ab3948f..8a1209429 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 \ @@ -41,10 +42,12 @@ 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 \ 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/lhash.h b/wolfssl/openssl/lhash.h index 01f8535f8..ee0fba18e 100644 --- a/wolfssl/openssl/lhash.h +++ b/wolfssl/openssl/lhash.h @@ -1,2 +1,64 @@ +/* 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 wolfSSL_##name##_LHASH_HASH(const void *arg) \ + { \ + const type *a = arg; \ + return name##_hash(a); \ + } +#define IMPLEMENT_LHASH_COMP_FN(name, type) \ + 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 + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WOLFSSL_lhash_H_ */ 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/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/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/pkcs7.h b/wolfssl/openssl/pkcs7.h index 94ddf2494..ce444d51d 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; @@ -53,8 +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* 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); @@ -65,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/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 d1e4dfbb8..49189d057 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 @@ -104,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; @@ -305,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 @@ -341,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 @@ -356,11 +362,14 @@ 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_REQ_bio #define d2i_X509_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 #define PEM_read_bio_X509 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 @@ -371,10 +380,18 @@ 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 +#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_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 #define PEM_write_bio_X509_REQ wolfSSL_PEM_write_bio_X509_REQ @@ -387,14 +404,19 @@ 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_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 #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_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 #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 @@ -416,12 +438,22 @@ 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_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 +#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 +#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 @@ -429,6 +461,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 @@ -460,6 +493,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 @@ -476,9 +510,11 @@ 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 +#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 @@ -519,6 +555,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 @@ -571,6 +608,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 @@ -618,6 +656,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 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 #define BIO_eof wolfSSL_BIO_eof @@ -660,15 +703,22 @@ 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 #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 @@ -681,13 +731,22 @@ 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 +#ifndef NO_WOLFSSL_STUB +#define ASN1_STRING_set_default_mask_asc(...) 1 +#endif + +#define ASN1_PRINTABLE_type(...) V_ASN1_PRINTABLESTRING #define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr @@ -912,6 +971,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 @@ -939,8 +999,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 @@ -1106,6 +1164,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 @@ -1143,6 +1207,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 @@ -1179,6 +1244,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 @@ -1191,7 +1257,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_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 #define SSL_CTX_set_alpn_select_cb wolfSSL_CTX_set_alpn_select_cb @@ -1213,8 +1283,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" @@ -1246,6 +1318,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/stack.h b/wolfssl/openssl/stack.h index b13923916..559a79670 100644 --- a/wolfssl/openssl/stack.h +++ b/wolfssl/openssl/stack.h @@ -28,15 +28,12 @@ extern "C" { #endif -#include - typedef void (*wolfSSL_sk_freefunc)(void *); WOLFSSL_API void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, wolfSSL_sk_freefunc); 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 new file mode 100644 index 000000000..a3e0fd362 --- /dev/null +++ b/wolfssl/openssl/txt_db.h @@ -0,0 +1,59 @@ +/* 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_ + +#include + +#define WOLFSSL_TXT_DB_MAX_FIELDS 10 + +struct WOLFSSL_TXT_DB { + int num_fields; + WOLF_STACK_OF(WOLFSSL_STRING) *data; + 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 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); +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_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 + +#endif /* WOLFSSL_TXT_DB_H_ */ diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index 77a8bca54..bf7ae25e3 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) @@ -23,4 +24,21 @@ #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_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/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index 65d8037e7..75e128a4f 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; @@ -99,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 @@ -107,11 +111,20 @@ 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_parse_list(...) NULL +#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 -#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 +#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 #ifdef __cplusplus } diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 1e6e6a31f..de194f612 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -102,6 +102,19 @@ extern "C" { #endif +/* LHASH is implemented as a stack */ +typedef struct WOLFSSL_STACK 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; @@ -175,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; @@ -189,6 +201,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 +331,12 @@ struct WOLFSSL_ASN1_TYPE { } value; }; +struct WOLFSSL_X509_ATTRIBUTE { + WOLFSSL_ASN1_OBJECT *object; + WOLFSSL_ASN1_TYPE *value; + WOLF_STACK_OF(WOLFSSL_ASN1_TYPE) *set; +}; + struct WOLFSSL_EVP_PKEY { void* heap; int type; /* openssh dereference */ @@ -472,6 +491,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) */ @@ -1088,20 +1109,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); @@ -1166,6 +1173,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); @@ -1281,11 +1289,16 @@ 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); 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); @@ -1347,6 +1360,13 @@ 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, + 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); @@ -1371,6 +1391,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*, @@ -1387,6 +1410,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*); @@ -1401,6 +1425,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); @@ -1430,6 +1455,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*); @@ -1443,7 +1470,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*); @@ -1598,6 +1625,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); @@ -1805,12 +1835,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, @@ -2078,10 +2102,11 @@ 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(WOLFSSL_STACK* sk); -WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i); +WOLFSSL_API int wolfSSL_sk_num(const WOLFSSL_STACK* sk); +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)) @@ -2181,6 +2206,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); @@ -2199,6 +2228,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* @@ -2226,6 +2259,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, @@ -2748,6 +2783,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); @@ -3341,6 +3377,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); @@ -3373,6 +3411,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); @@ -3396,7 +3435,11 @@ 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); 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); @@ -3418,6 +3461,9 @@ WOLFSSL_API int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, WOLFSSL_API int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses); 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); @@ -3425,6 +3471,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) @@ -3448,6 +3498,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 @@ -3527,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*); @@ -3546,12 +3600,31 @@ 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); + 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, 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); +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); +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 @@ -3611,8 +3684,9 @@ 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); WOLFSSL_API int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)*, @@ -3632,6 +3706,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) @@ -3775,6 +3861,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 @@ -3861,8 +3948,12 @@ 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 char* wolfSSL_sk_WOLFSSL_STRING_value( +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( + 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, @@ -3911,8 +4002,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); @@ -3931,6 +4022,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)); @@ -3955,6 +4049,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); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 26eeee647..1537ccc7e 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, @@ -142,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; @@ -202,6 +206,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, @@ -228,6 +233,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 */ @@ -300,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 @@ -425,6 +431,7 @@ enum Oid_Types { oidCertNameType = 17, oidTlsExtType = 18, oidCrlExtType = 19, + oidCsrAttrType = 20, oidIgnoreType }; @@ -591,6 +598,14 @@ enum KeyIdType { }; #endif +#ifdef WOLFSSL_CERT_REQ +enum CsrAttrType { + CHALLENGE_PASSWORD_OID = 659, + SERIAL_NUMBER_OID = 94, + EXTENSION_REQUEST_OID = 666, +}; +#endif + /* Key usage extension bits (based on RFC 5280) */ #define KEYUSE_DIGITAL_SIG 0x0080 #define KEYUSE_CONTENT_COMMIT 0x0040 @@ -663,7 +678,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; @@ -672,6 +689,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 @@ -892,6 +912,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; @@ -943,7 +971,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 }; @@ -1040,6 +1070,12 @@ 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); WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify); WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate); @@ -1112,6 +1148,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, @@ -1146,6 +1184,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); @@ -1158,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*); @@ -1208,7 +1249,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 */ 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, diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index a92d7b3ce..8bc1dd3d4 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -121,8 +121,8 @@ 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 */ - +WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst); +#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); 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/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index ea6b40ddb..537856114 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -48,8 +48,12 @@ /* 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 #define MAX_ORI_TYPE_SZ MAX_OID_SZ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index aef56f987..7148e1d24 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 @@ -649,9 +650,12 @@ 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)) - #define XISALPHA(c) isalpha((c)) + #endif + #ifdef OPENSSL_ALL + #define XISALNUM(c) isalnum((c)) #endif /* needed by wolfSSL_check_domain_name() */ #define XTOLOWER(c) tolower((c)) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 1e8aabca2..da89676bf 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -604,6 +604,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #else #define XFOPEN fopen #endif + #define XFDOPEN fdopen #define XFSEEK fseek #define XFTELL ftell #define XREWIND rewind @@ -619,6 +620,9 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #include #include #include + #define XWRITE write + #define XREAD read + #define XCLOSE close #endif #endif