diff --git a/.gitignore b/.gitignore index b22328702c..cd9de3c0f9 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ testsuite/testsuite tests/unit testsuite/testsuite.test tests/unit.test +tests/bio_write_test.txt testsuite/*.der testsuite/*.pem testsuite/*.raw @@ -188,4 +189,4 @@ wolfcrypt/user-crypto/lib/libusercrypto.* wrapper/CSharp/x64/ # Visual Studio Code Workspace Files -*.vscode \ No newline at end of file +*.vscode diff --git a/certs/dsaparams.pem b/certs/dsaparams.pem new file mode 100644 index 0000000000..973e896824 --- /dev/null +++ b/certs/dsaparams.pem @@ -0,0 +1,9 @@ +-----BEGIN DSA PARAMETERS----- +MIIBHwKBgQDN3iVogFMN5XfW0pA5P5CiPzOUbuhPK2OrMKsVuhHqil2NzLjUodXB +R51ac2piSdEGB2f2L6M5vU4NtNMiI4TskyZaSe58iUhmTejo2FD7pXGfIhjl5gtG +h2buUo9GT7UDzu3jvuW1gdJZ6cCtTdBNJve6UOjJj/4kGT0up1I8bQIVAPtH++yB +IMgc6Uq6BG8Zm5TugmfTAoGBAJuVu4XFWEoynKpEhdZo3D4U9M5to0k46tZhSJJa +QJVJOKrhOSloWEeKSwHhLo5sY29AylA/jAuZ5HJCuLHCJkjxnIPGNy5arhEJ2fOt +H2+trVDjeDLm3o6qv9EAn7MCEhmiFewUGFwOJs75rsx7tdEm/IX+FJO2nX124zWX +Ht7E +-----END DSA PARAMETERS----- diff --git a/certs/include.am b/certs/include.am index eedd53aa22..b7fad51e5f 100644 --- a/certs/include.am +++ b/certs/include.am @@ -31,7 +31,8 @@ EXTRA_DIST += \ certs/server-revoked-cert.pem \ certs/server-revoked-key.pem \ certs/wolfssl-website-ca.pem \ - certs/test-servercert.p12 + certs/test-servercert.p12 \ + certs/dsaparams.pem EXTRA_DIST += \ certs/ca-key.der \ certs/ca-cert.der \ diff --git a/examples/client/client.c b/examples/client/client.c index 7d5b43e2a9..e0cc24125f 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1288,6 +1288,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); #endif + #if defined(OPENSSL_EXTRA) + if (wolfSSL_CTX_get_read_ahead(ctx) != 0) { + err_sys("bad read ahead default value"); + } + if (wolfSSL_CTX_set_read_ahead(ctx, 1) != SSL_SUCCESS) { + err_sys("error setting read ahead value"); + } + #endif + ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); @@ -1445,13 +1454,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef OPENSSL_EXTRA { - byte* rnd; - byte* pt; - int size; + byte* rnd; + byte* pt; + size_t size; /* get size of buffer then print */ size = wolfSSL_get_client_random(NULL, NULL, 0); - if (size < 0) { + if (size == 0) { err_sys("error getting client random buffer size"); } @@ -1461,7 +1470,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } size = wolfSSL_get_client_random(ssl, rnd, size); - if (size < 0) { + if (size == 0) { XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER); err_sys("error getting client random buffer"); } diff --git a/examples/server/server.c b/examples/server/server.c index d39db80703..13bf579181 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -882,6 +882,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) ssl = SSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL"); + #ifdef OPENSSL_EXTRA + wolfSSL_KeepArrays(ssl); + #endif #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) { @@ -1022,6 +1025,39 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } showPeer(ssl); + if (SSL_state(ssl) != 0) { + err_sys("SSL in error state"); + } + +#ifdef OPENSSL_EXTRA + { + byte* rnd; + byte* pt; + size_t size; + + /* get size of buffer then print */ + size = wolfSSL_get_server_random(NULL, NULL, 0); + if (size == 0) { + err_sys("error getting server random buffer size"); + } + + rnd = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rnd == NULL) { + err_sys("error creating server random buffer"); + } + + size = wolfSSL_get_server_random(ssl, rnd, size); + if (size == 0) { + XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + err_sys("error getting server random buffer"); + } + + printf("Server Random : "); + for (pt = rnd; pt < rnd + size; pt++) printf("%02X", *pt); + printf("\n"); + XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif #ifdef HAVE_ALPN if (alpnList != NULL) { diff --git a/rpm/spec.in b/rpm/spec.in index e7871d05be..ae8fc8ad84 100644 --- a/rpm/spec.in +++ b/rpm/spec.in @@ -231,6 +231,7 @@ mkdir -p $RPM_BUILD_ROOT/ %{_includedir}/wolfssl/wolfcrypt/wolfevent.h %{_includedir}/wolfssl/error-ssl.h %{_includedir}/wolfssl/ocsp.h +%{_includedir}/wolfssl/openssl/aes.h %{_includedir}/wolfssl/openssl/asn1.h %{_includedir}/wolfssl/openssl/bio.h %{_includedir}/wolfssl/openssl/bn.h @@ -275,6 +276,8 @@ mkdir -p $RPM_BUILD_ROOT/ %{_libdir}/pkgconfig/wolfssl.pc %changelog +* Fri Nov 11 2016 Jacob Barthelmeh +- Added header for wolfssl/openssl/aes.h * Fri Oct 28 2016 Jacob Barthelmeh - Added header for pkcs12 * Fri Sep 23 2016 John Safranek diff --git a/src/bio.c b/src/bio.c new file mode 100644 index 0000000000..aa02a9adac --- /dev/null +++ b/src/bio.c @@ -0,0 +1,446 @@ +/* bio.c + * + * Copyright (C) 2006-2016 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 + */ + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg) +{ + (void)bio; + (void)cmd; + (void)larg; + (void)parg; + + WOLFSSL_ENTER("BIO_ctrl"); + return 1; +} + + +/* Return the number of pending bytes in read and write buffers */ +size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) +{ + WOLFSSL_ENTER("BIO_ctrl_pending"); + if (bio == NULL) { + return 0; + } + + if (bio->ssl != NULL) { + return (long)wolfSSL_pending(bio->ssl); + } + + if (bio->type == BIO_MEMORY) { + return bio->memLen; + } + + /* type BIO_BIO then check paired buffer */ + if (bio->type == BIO_BIO && bio->pair != NULL) { + WOLFSSL_BIO* pair = bio->pair; + if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) { + /* in wrap around state where begining of buffer is being + * overwritten */ + return pair->wrSz - pair->rdIdx + pair->wrIdx; + } + else { + /* simple case where has not wrapped around */ + return pair->wrIdx - pair->rdIdx; + } + } + + return 0; +} + + +long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr) +{ + WOLFSSL_ENTER("BIO_get_mem_ptr"); + + if (bio == NULL || ptr == NULL) { + return SSL_FAILURE; + } + + *ptr = (WOLFSSL_BUF_MEM*)(bio->mem); + return SSL_SUCCESS; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg) +{ + (void) bp; + (void) cmd; + (void) larg; + (void) iarg; + WOLFSSL_ENTER("BIO_int_ctrl"); + return 0; +} + + +int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) +{ + WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size"); + + if (bio == NULL || bio->type != BIO_BIO || size < 0) { + return SSL_FAILURE; + } + + /* if already in pair then do not change size */ + if (bio->pair != NULL) { + WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing"); + return SSL_FAILURE; + } + + bio->wrSz = (int)size; + if (bio->wrSz < 0) { + WOLFSSL_MSG("Unexpected negative size value"); + return SSL_FAILURE; + } + + if (bio->mem != NULL) { + XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL); + } + + bio->mem = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL); + if (bio->mem == NULL) { + WOLFSSL_MSG("Memory allocation error"); + return SSL_FAILURE; + } + bio->wrIdx = 0; + bio->rdIdx = 0; + + return SSL_SUCCESS; +} + + +/* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vise + * versa. Creating something similar to a two way pipe. + * Reading and writing between the two BIOs is not thread safe, they are + * expected to be used by the same thread. */ +int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2) +{ + WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair"); + + if (b1 == NULL || b2 == NULL) { + WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG); + return SSL_FAILURE; + } + + /* both are expected to be of type BIO and not already paired */ + if (b1->type != BIO_BIO || b2->type != BIO_BIO || + b1->pair != NULL || b2->pair != NULL) { + WOLFSSL_MSG("Expected type BIO and not already paired"); + return SSL_FAILURE; + } + + /* set default write size if not already set */ + if (b1->mem == NULL && wolfSSL_BIO_set_write_buf_size(b1, + WOLFSSL_BIO_SIZE) != SSL_SUCCESS) { + return SSL_FAILURE; + } + + if (b2->mem == NULL && wolfSSL_BIO_set_write_buf_size(b2, + WOLFSSL_BIO_SIZE) != SSL_SUCCESS) { + return SSL_FAILURE; + } + + b1->pair = b2; + b2->pair = b1; + + return SSL_SUCCESS; +} + + +int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b) +{ + WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request"); + + if (b == NULL) { + return SSL_FAILURE; + } + + b->readRq = 0; + + return SSL_SUCCESS; +} + + +/* Does not advance read index pointer */ +int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf) +{ + WOLFSSL_ENTER("wolfSSL_BIO_nread0"); + + if (bio == NULL || buf == NULL) { + WOLFSSL_MSG("NULL argument passed in"); + return 0; + } + + /* if paired read from pair */ + if (bio->pair != NULL) { + WOLFSSL_BIO* pair = bio->pair; + + /* case where have wrapped around write buffer */ + *buf = (char*)pair->mem + pair->rdIdx; + if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) { + return pair->wrSz - pair->rdIdx; + } + else { + return pair->wrIdx - pair->rdIdx; + } + } + + return 0; +} + + +/* similar to wolfSSL_BIO_nread0 but advances the read index */ +int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num) +{ + int sz = WOLFSSL_BIO_UNSET; + + WOLFSSL_ENTER("wolfSSL_BIO_nread"); + + if (bio == NULL || buf == NULL) { + WOLFSSL_MSG("NULL argument passed in"); + return SSL_FAILURE; + } + + if (bio->pair != NULL) { + /* special case if asking to read 0 bytes */ + if (num == 0) { + *buf = (char*)bio->pair->mem + bio->pair->rdIdx; + return 0; + } + + /* get amount able to read and set buffer pointer */ + sz = wolfSSL_BIO_nread0(bio, buf); + if (sz == 0) { + return WOLFSSL_BIO_ERROR; + } + + if (num < sz) { + sz = num; + } + bio->pair->rdIdx += sz; + + /* check if have read to the end of the buffer and need to reset */ + if (bio->pair->rdIdx == bio->pair->wrSz) { + bio->pair->rdIdx = 0; + if (bio->pair->wrIdx == bio->pair->wrSz) { + bio->pair->wrIdx = 0; + } + } + + /* check if read up to write index, if so then reset indexs */ + if (bio->pair->rdIdx == bio->pair->wrIdx) { + bio->pair->rdIdx = 0; + bio->pair->wrIdx = 0; + } + } + + return sz; +} + + +int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num) +{ + int sz = WOLFSSL_BIO_UNSET; + + WOLFSSL_ENTER("wolfSSL_BIO_nwrite"); + + if (bio == NULL || buf == NULL) { + WOLFSSL_MSG("NULL argument passed in"); + return 0; + } + + if (bio->pair != NULL) { + if (num == 0) { + *buf = (char*)bio->mem + bio->wrIdx; + return 0; + } + + if (bio->wrIdx < bio->rdIdx) { + /* if wrapped around only write up to read index. In this case + * rdIdx is always greater then wrIdx so sz will not be negative. */ + sz = bio->rdIdx - bio->wrIdx; + } + else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) { + return WOLFSSL_BIO_ERROR; /* no more room to write */ + } + else { + /* write index is past read index so write to end of buffer */ + sz = bio->wrSz - bio->wrIdx; + + if (sz <= 0) { + /* either an error has occured with write index or it is at the + * end of the write buffer. */ + if (bio->rdIdx == 0) { + /* no more room, nothing has been read */ + return WOLFSSL_BIO_ERROR; + } + + bio->wrIdx = 0; + + /* check case where read index is not at 0 */ + if (bio->rdIdx > 0) { + sz = bio->rdIdx; /* can write up to the read index */ + } + else { + sz = bio->wrSz; /* no restriction other then buffer size */ + } + } + } + + if (num < sz) { + sz = num; + } + *buf = (char*)bio->mem + bio->wrIdx; + bio->wrIdx += sz; + + /* if at the end of the buffer and space for wrap around then set + * write index back to 0 */ + if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) { + bio->wrIdx = 0; + } + } + + return sz; +} + + +/* Reset BIO to initial state */ +int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) +{ + WOLFSSL_ENTER("wolfSSL_BIO_reset"); + + if (bio == NULL) { + WOLFSSL_MSG("NULL argument passed in"); + /* -1 is consistent failure even for FILE type */ + return WOLFSSL_BIO_ERROR; + } + + switch (bio->type) { + #ifndef NO_FILESYSTEM + case BIO_FILE: + XREWIND(bio->file); + return 0; + #endif + + case BIO_BIO: + bio->rdIdx = 0; + bio->wrIdx = 0; + return 0; + + default: + WOLFSSL_MSG("Unknown BIO type needs added to reset function"); + } + + return WOLFSSL_BIO_ERROR; +} + +#ifndef NO_FILESYSTEM +long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c) +{ + WOLFSSL_ENTER("wolfSSL_BIO_set_fp"); + + if (bio == NULL || fp == NULL) { + WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG); + return SSL_FAILURE; + } + + if (bio->type != BIO_FILE) { + return SSL_FAILURE; + } + + bio->close = (byte)c; + bio->file = fp; + + return SSL_SUCCESS; +} + + +long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp) +{ + WOLFSSL_ENTER("wolfSSL_BIO_get_fp"); + + if (bio == NULL || fp == NULL) { + return SSL_FAILURE; + } + + if (bio->type != BIO_FILE) { + return SSL_FAILURE; + } + + *fp = bio->file; + + return SSL_SUCCESS; +} + +/* overwrites file */ +int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name) +{ + WOLFSSL_ENTER("wolfSSL_BIO_write_filename"); + + if (bio == NULL || name == NULL) { + return SSL_FAILURE; + } + + if (bio->type == BIO_FILE) { + if (bio->file != NULL && bio->close == BIO_CLOSE) { + XFCLOSE(bio->file); + } + + bio->file = XFOPEN(name, "w"); + if (bio->file == NULL) { + return SSL_FAILURE; + } + bio->close = BIO_CLOSE; + + return SSL_SUCCESS; + } + + return SSL_FAILURE; +} + + +int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs) +{ + WOLFSSL_ENTER("wolfSSL_BIO_seek"); + + if (bio == NULL) { + return -1; + } + + /* offset ofs from begining of file */ + if (bio->type == BIO_FILE && XFSEEK(bio->file, ofs, SEEK_SET) < 0) { + return -1; + } + + return 0; +} +#endif /* NO_FILESYSTEM */ + + +long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) +{ + WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return"); + + if (bio != NULL) { + bio->eof = v; + } + + return 0; +} diff --git a/src/internal.c b/src/internal.c index 9459c231e4..e0cf2fb5cd 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1386,6 +1386,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) WOLFSSL_MSG("Bad Cert Manager New"); return BAD_CERT_MANAGER_ERROR; } + #ifdef OPENSSL_EXTRA + /* setup WOLFSSL_X509_STORE */ + ctx->x509_store.cm = ctx->cm; + #endif #endif #if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) @@ -2573,6 +2577,13 @@ void FreeX509Name(WOLFSSL_X509_NAME* name, void* heap) /* Initialize wolfSSL X509 type */ void InitX509(WOLFSSL_X509* x509, int dynamicFlag, void* heap) { + if (x509 == NULL) { + WOLFSSL_MSG("Null parameter passed in!"); + return; + } + + XMEMSET(x509, 0, sizeof(WOLFSSL_X509)); + x509->heap = heap; InitX509Name(&x509->issuer, 0); InitX509Name(&x509->subject, 0); @@ -2628,6 +2639,12 @@ void FreeX509(WOLFSSL_X509* x509) #ifdef OPENSSL_EXTRA XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT); XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT); + if (x509->authInfo != NULL) { + XFREE(x509->authInfo, x509->heap, DYNAMIC_TYPE_X509_EXT); + } + if (x509->extKeyUsageSrc != NULL) { + XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT); + } #endif /* OPENSSL_EXTRA */ if (x509->altNames) FreeAltNames(x509->altNames, NULL); @@ -3299,6 +3316,10 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #endif #endif +#ifdef OPENSSL_EXTRA + ssl->readAhead = ctx->readAhead; +#endif + return SSL_SUCCESS; } @@ -5295,6 +5316,32 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif +#ifdef OPENSSL_EXTRA + /* case where specific protocols are turned off */ + if (!ssl->options.dtls && ssl->options.mask > 0) { + if (rh->pvMinor == SSLv3_MINOR && + (ssl->options.mask & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) { + WOLFSSL_MSG("Option set to not allow SSLv3"); + return VERSION_ERROR; + } + if (rh->pvMinor == TLSv1_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) { + WOLFSSL_MSG("Option set to not allow TLSv1"); + return VERSION_ERROR; + } + if (rh->pvMinor == TLSv1_1_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) { + WOLFSSL_MSG("Option set to not allow TLSv1.1"); + return VERSION_ERROR; + } + if (rh->pvMinor == TLSv1_2_MINOR && + (ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) { + WOLFSSL_MSG("Option set to not allow TLSv1.2"); + return VERSION_ERROR; + } + } +#endif /* OPENSSL_EXTRA */ + /* catch version mismatch */ if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){ if (ssl->options.side == WOLFSSL_SERVER_END && @@ -6293,6 +6340,23 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) x509->pathLength = dCert->pathLength; x509->keyUsage = dCert->extKeyUsage; + x509->CRLdistSet = dCert->extCRLdistSet; + x509->CRLdistCrit = dCert->extCRLdistCrit; + x509->CRLInfo = dCert->extCrlInfo; + x509->CRLInfoSz = dCert->extCrlInfoSz; + x509->authInfoSet = dCert->extAuthInfoSet; + x509->authInfoCrit = dCert->extAuthInfoCrit; + if (dCert->extAuthInfo != NULL && dCert->extAuthInfoSz > 0) { + x509->authInfo = (byte*)XMALLOC(dCert->extAuthInfoSz, x509->heap, + DYNAMIC_TYPE_X509_EXT); + if (x509->authInfo != NULL) { + XMEMCPY(x509->authInfo, dCert->extAuthInfo, dCert->extAuthInfoSz); + x509->authInfoSz = dCert->extAuthInfoSz; + } + else { + ret = MEMORY_E; + } + } x509->basicConstSet = dCert->extBasicConstSet; x509->basicConstCrit = dCert->extBasicConstCrit; x509->basicConstPlSet = dCert->pathLengthSet; @@ -6326,10 +6390,33 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) } x509->keyUsageSet = dCert->extKeyUsageSet; x509->keyUsageCrit = dCert->extKeyUsageCrit; + if (dCert->extExtKeyUsageSrc != NULL && dCert->extExtKeyUsageSz > 0) { + x509->extKeyUsageSrc = (byte*)XMALLOC(dCert->extExtKeyUsageSz, + x509->heap, DYNAMIC_TYPE_X509_EXT); + if (x509->extKeyUsageSrc != NULL) { + XMEMCPY(x509->extKeyUsageSrc, dCert->extExtKeyUsageSrc, + dCert->extExtKeyUsageSz); + x509->extKeyUsageSz = dCert->extExtKeyUsageSz; + x509->extKeyUsageCrit = dCert->extExtKeyUsageCrit; + x509->extKeyUsageCount = dCert->extExtKeyUsageCount; + } + else { + ret = MEMORY_E; + } + } #ifdef WOLFSSL_SEP x509->certPolicySet = dCert->extCertPolicySet; x509->certPolicyCrit = dCert->extCertPolicyCrit; #endif /* WOLFSSL_SEP */ + #ifdef WOLFSSL_CERT_EXT + { + int i; + for (i = 0; i < dCert->extCertPoliciesNb && i < MAX_CERTPOL_NB; i++) + XMEMCPY(x509->certPolicies[i], dCert->extCertPolicies[i], + MAX_CERTPOL_SZ); + x509->certPoliciesNb = dCert->extCertPoliciesNb; + } + #endif /* WOLFSSL_CERT_EXT */ #endif /* OPENSSL_EXTRA */ #ifdef HAVE_ECC x509->pkCurveOID = dCert->pkCurveOID; @@ -6389,8 +6476,12 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, while (listSz) { word32 certSz; - if (totalCerts >= MAX_CHAIN_DEPTH) + if (totalCerts >= MAX_CHAIN_DEPTH) { + #ifdef OPENSSL_EXTRA + ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; + #endif return MAX_CHAIN_ERROR; + } if ((*inOutIdx - begin) + OPAQUE24_LEN > size) return BUFFER_ERROR; @@ -6611,6 +6702,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret == 0) { WOLFSSL_MSG("Verified Peer's cert"); + #ifdef OPENSSL_EXTRA + ssl->peerVerifyRet = X509_V_OK; + #endif fatal = 0; } else if (ret == ASN_PARSE_E) { @@ -6748,6 +6842,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif ssl->error = ret; + #ifdef OPENSSL_EXTRA + ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; + #endif return ret; } ssl->options.havePeerCert = 1; @@ -9383,7 +9480,7 @@ int ProcessReply(WOLFSSL* ssl) int ret = 0, type, readSz; int atomicUser = 0; word32 startIdx = 0; -#ifdef WOLFSSL_DTLS +#if defined(WOLFSSL_DTLS) int used; #endif diff --git a/src/ssl.c b/src/ssl.c index 303c441516..6397d65ab2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1932,6 +1932,17 @@ int wolfSSL_shutdown(WOLFSSL* ssl) } +/* get current error state value */ +int wolfSSL_state(WOLFSSL* ssl) +{ + if (ssl == NULL) { + return BAD_FUNC_ARG; + } + + return ssl->error; +} + + int wolfSSL_get_error(WOLFSSL* ssl, int ret) { WOLFSSL_ENTER("SSL_get_error"); @@ -2132,7 +2143,6 @@ const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl) return NULL; } - int wolfSSL_GetKeySize(WOLFSSL* ssl) { if (ssl) @@ -2464,31 +2474,147 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +static struct cipher{ + unsigned char type; + const char *name; +} cipher_tbl[] = { + #ifndef NO_AES -static const char *EVP_AES_128_CBC = "AES-128-CBC"; -static const char *EVP_AES_192_CBC = "AES-192-CBC"; -static const char *EVP_AES_256_CBC = "AES-256-CBC"; + {AES_128_CBC_TYPE, "AES-128-CBC"}, + {AES_192_CBC_TYPE, "AES-192-CBC"}, + {AES_256_CBC_TYPE, "AES-256-CBC"}, #if defined(OPENSSL_EXTRA) - static const char *EVP_AES_128_CTR = "AES-128-CTR"; - static const char *EVP_AES_192_CTR = "AES-192-CTR"; - static const char *EVP_AES_256_CTR = "AES-256-CTR"; + {AES_128_CTR_TYPE, "AES-128-CTR"}, + {AES_192_CTR_TYPE, "AES-192-CTR"}, + {AES_256_CTR_TYPE, "AES-256-CTR"}, + + {AES_128_ECB_TYPE, "AES-128-ECB"}, + {AES_192_ECB_TYPE, "AES-192-ECB"}, + {AES_256_ECB_TYPE, "AES-256-ECB"}, +#endif + +#endif + +#ifndef NO_DES3 + {DES_CBC_TYPE, "DES-CBC"}, + {DES_ECB_TYPE, "DES-ECB"}, + + {DES_EDE3_CBC_TYPE, "DES-EDE3-CBC"}, + {DES_EDE3_ECB_TYPE, "DES-EDE3-ECB"}, +#endif + +#ifdef HAVE_IDEA + {IDEA_CBC_TYPE, "IDEA-CBC"}, +#endif + { 0, NULL} +} ; + +const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name) +{ + + static const struct alias { + const char *name; + const char *alias; + } alias_tbl[] = + { + {"DES-CBC", "DES"}, + {"DES-CBC", "des"}, + {"DES-EDE3-CBC", "DES3"}, + {"DES-EDE3-CBC", "des3"}, + {"DES-EDE3-ECB", "des-ede3-ecb"}, + {"IDEA-CBC", "IDEA"}, + {"IDEA-CBC", "idea"}, + {"AES-128-CBC", "AES128"}, + {"AES-128-CBC", "aes128"}, + {"AES-192-CBC", "AES192"}, + {"AES-192-CBC", "aes192"}, + {"AES-256-CBC", "AES256"}, + {"AES-256-CBC", "aes256"}, + { NULL, NULL} + }; + + const struct cipher *ent ; + const struct alias *al ; + + WOLFSSL_ENTER("EVP_get_cipherbyname"); + + for( al = alias_tbl; al->name != NULL; al++) + if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) { + name = al->name; + break; + } + + for( ent = cipher_tbl; ent->name != NULL; ent++) + if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) { + return (WOLFSSL_EVP_CIPHER *)ent->name; + } + + return NULL; +} + + +#ifndef NO_AES +static char *EVP_AES_128_CBC; +static char *EVP_AES_192_CBC; +static char *EVP_AES_256_CBC; +#if defined(OPENSSL_EXTRA) + static char *EVP_AES_128_CTR; + static char *EVP_AES_192_CTR; + static char *EVP_AES_256_CTR; + + static char *EVP_AES_128_ECB; + static char *EVP_AES_192_ECB; + static char *EVP_AES_256_ECB; #endif static const int EVP_AES_SIZE = 11; #endif #ifndef NO_DES3 -static const char *EVP_DES_CBC = "DES-CBC"; +static char *EVP_DES_CBC; +static char *EVP_DES_ECB; static const int EVP_DES_SIZE = 7; -static const char *EVP_DES_EDE3_CBC = "DES-EDE3-CBC"; +static char *EVP_DES_EDE3_CBC; +static char *EVP_DES_EDE3_ECB; static const int EVP_DES_EDE3_SIZE = 12; #endif #ifdef HAVE_IDEA -static const char *EVP_IDEA_CBC = "IDEA-CBC"; +static char *EVP_IDEA_CBC; static const int EVP_IDEA_SIZE = 8; #endif +void wolfSSL_EVP_init(void) +{ +#ifndef NO_AES + EVP_AES_128_CBC = (char *)EVP_get_cipherbyname("AES-128-CBC"); + EVP_AES_192_CBC = (char *)EVP_get_cipherbyname("AES-192-CBC"); + EVP_AES_256_CBC = (char *)EVP_get_cipherbyname("AES-256-CBC"); + +#if defined(OPENSSL_EXTRA) + EVP_AES_128_CTR = (char *)EVP_get_cipherbyname("AES-128-CTR"); + EVP_AES_192_CTR = (char *)EVP_get_cipherbyname("AES-192-CTR"); + EVP_AES_256_CTR = (char *)EVP_get_cipherbyname("AES-256-CTR"); + + EVP_AES_128_ECB = (char *)EVP_get_cipherbyname("AES-128-ECB"); + EVP_AES_192_ECB = (char *)EVP_get_cipherbyname("AES-192-ECB"); + EVP_AES_256_ECB = (char *)EVP_get_cipherbyname("AES-256-ECB"); +#endif +#endif + +#ifndef NO_DES3 + EVP_DES_CBC = (char *)EVP_get_cipherbyname("DES-CBC"); + EVP_DES_ECB = (char *)EVP_get_cipherbyname("DES-ECB"); + + EVP_DES_EDE3_CBC = (char *)EVP_get_cipherbyname("DES-EDE3-CBC"); + EVP_DES_EDE3_ECB = (char *)EVP_get_cipherbyname("DES-EDE3-ECB"); +#endif + +#ifdef HAVE_IDEA + EVP_IDEA_CBC = (char *)EVP_get_cipherbyname("IDEA-CBC"); +#endif +} + /* our KeyPemToDer password callback, password in userData */ static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata) { @@ -3568,6 +3694,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT; break; case CRL_TYPE: header=BEGIN_X509_CRL; footer=END_X509_CRL; break; case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM; break; + case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM; break; case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ; break; case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV; break; case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV; break; @@ -5652,6 +5779,529 @@ int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format) #ifdef OPENSSL_EXTRA /* put SSL type in extra for now, not very common */ +WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, + const unsigned char **in, long inSz) +{ + WOLFSSL_EVP_PKEY* local; + + WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey"); + + if (in == NULL || inSz < 0) { + WOLFSSL_MSG("Bad argument"); + return NULL; + } + + local = wolfSSL_PKEY_new(); + if (local == NULL) { + return NULL; + } + + local->type = type; + local->pkey_sz = (int)inSz; + local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY); + if (local->pkey.ptr == NULL) { + wolfSSL_EVP_PKEY_free(local); + local = NULL; + } + else { + XMEMCPY(local->pkey.ptr, *in, inSz); + } + + if (out != NULL) { + *out = local; + } + + return local; +} + + +long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt) +{ + WOLFSSL_STUB("wolfSSL_ctrl"); + (void)ssl; + (void)cmd; + (void)opt; + (void)pt; + return SSL_FAILURE; +} + + +long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) +{ + WOLFSSL_STUB("wolfSSL_CTX_ctrl"); + (void)ctx; + (void)cmd; + (void)opt; + (void)pt; + return SSL_FAILURE; +} + +#ifndef NO_CERTS +int wolfSSL_check_private_key(const WOLFSSL* ssl) +{ + DecodedCert der; + word32 size; + byte* buff; + int ret; + + if (ssl == NULL) { + return SSL_FAILURE; + } + + size = ssl->buffers.certificate->length; + buff = ssl->buffers.certificate->buffer; + InitDecodedCert(&der, buff, size, ssl->heap); + if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) { + FreeDecodedCert(&der); + return SSL_FAILURE; + } + + size = ssl->buffers.key->length; + buff = ssl->buffers.key->buffer; + ret = wc_CheckPrivateKey(buff, size, &der); + FreeDecodedCert(&der); + return ret; +} + + +/* Looks for the extension matching the passed in nid + * + * c : if not null then is set to status value -2 if multiple occurances + * of the extension are found, -1 if not found, 0 if found and not + * critical, and 1 if found and critical. + * nid : Extension OID to be found. + * idx : if NULL return first extension found match, otherwise start search at + * idx location and set idx to the location of extension returned. + * returns NULL or a pointer to an WOLFSSL_STACK holding extension structure + * + * NOTE code for decoding extensions is in asn.c DecodeCertExtensions -- + * use already decoded extension in this function to avoid decoding twice. + * Currently we do not make use of idx since getting pre decoded extensions. + */ +void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, + int nid, int* c, int* idx) +{ + WOLFSSL_STACK* sk = NULL; + WOLFSSL_ASN1_OBJECT* obj = NULL; + + WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i"); + + if (x509 == NULL) { + return NULL; + } + + if (c != NULL) { + *c = -1; /* default to not found */ + } + + sk = (STACK_OF(WOLFSSL_ASN1_OBJECT)*)XMALLOC( + sizeof(STACK_OF(WOLFSSL_ASN1_OBJECT)), NULL, DYNAMIC_TYPE_ASN1); + if (sk == NULL) { + return NULL; + } + XMEMSET(sk, 0, sizeof(STACK_OF(WOLFSSL_ASN1_OBJECT))); + + switch (nid) { + case BASIC_CA_OID: + if (x509->basicConstSet) { + obj = wolfSSL_ASN1_OBJECT_new(); + if (c != NULL) { + *c = x509->basicConstCrit; + } + obj->type = BASIC_CA_OID; + } + else { + WOLFSSL_MSG("No Basic Constraint set"); + } + break; + + case ALT_NAMES_OID: + { + DNS_entry* dns; + + if (x509->subjAltNameSet && x509->altNames != NULL) { + /* alt names are DNS_entry structs */ + if (c != NULL) { + if (x509->altNames->next != NULL) { + *c = -2; /* more then one found */ + } + else { + *c = x509->subjAltNameCrit; + } + } + + dns = x509->altNames; + while (dns != NULL) { + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = ALT_NAMES_OID; + obj->obj = (byte*)dns->name; + dns = dns->next; + /* last dns in list add at end of function */ + if (dns != NULL) { + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != + SSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1 object onto stack"); + wolfSSL_ASN1_OBJECT_free(obj); + wolfSSL_sk_ASN1_OBJECT_free(sk); + sk = NULL; + } + } + } + } + else { + WOLFSSL_MSG("No Alt Names set"); + } + } + break; + + case CRL_DIST_OID: + if (x509->CRLdistSet && x509->CRLInfo != NULL) { + if (c != NULL) { + *c = x509->CRLdistCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = CRL_DIST_OID; + obj->obj = x509->CRLInfo; + obj->objSz = x509->CRLInfoSz; + } + else { + WOLFSSL_MSG("No CRL dist set"); + } + break; + + case AUTH_INFO_OID: + if (x509->authInfoSet && x509->authInfo != NULL) { + if (c != NULL) { + *c = x509->authInfoCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = AUTH_INFO_OID; + obj->obj = x509->authInfo; + obj->objSz = x509->authInfoSz; + } + else { + WOLFSSL_MSG("No Auth Info set"); + } + break; + + case AUTH_KEY_OID: + if (x509->authKeyIdSet) { + if (c != NULL) { + *c = x509->authKeyIdCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = AUTH_KEY_OID; + obj->obj = x509->authKeyId; + obj->objSz = x509->authKeyIdSz; + } + else { + WOLFSSL_MSG("No Auth Key set"); + } + break; + + case SUBJ_KEY_OID: + if (x509->subjKeyIdSet) { + if (c != NULL) { + *c = x509->subjKeyIdCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = SUBJ_KEY_OID; + obj->obj = x509->subjKeyId; + obj->objSz = x509->subjKeyIdSz; + } + else { + WOLFSSL_MSG("No Subject Key set"); + } + break; + + case CERT_POLICY_OID: + #ifdef WOLFSSL_CERT_EXT + { + int i; + + if (x509->certPoliciesNb > 0) { + if (c != NULL) { + if (x509->certPoliciesNb > 1) { + *c = -2; + } + else { + *c = 0; + } + } + + for (i = 0; i < x509->certPoliciesNb - 1; i++) { + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = CERT_POLICY_OID; + obj->obj = (byte*)(x509->certPolicies[i]); + obj->objSz = MAX_CERTPOL_SZ; + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) + != SSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1 object onto stack"); + wolfSSL_ASN1_OBJECT_free(obj); + wolfSSL_sk_ASN1_OBJECT_free(sk); + sk = NULL; + } + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = CERT_POLICY_OID; + obj->obj = (byte*)(x509->certPolicies[i]); + obj->objSz = MAX_CERTPOL_SZ; + } + else { + WOLFSSL_MSG("No Cert Policy set"); + } + } + #else + #ifdef WOLFSSL_SEP + if (x509->certPolicySet) { + if (c != NULL) { + *c = x509->certPolicyCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = CERT_POLICY_OID; + } + else { + WOLFSSL_MSG("No Cert Policy set"); + } + #else + WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT"); + #endif /* WOLFSSL_SEP */ + #endif /* WOLFSSL_CERT_EXT */ + break; + + case KEY_USAGE_OID: + if (x509->keyUsageSet) { + if (c != NULL) { + *c = x509->keyUsageCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = KEY_USAGE_OID; + obj->obj = (byte*)&(x509->keyUsage); + obj->objSz = sizeof(word16); + } + else { + WOLFSSL_MSG("No Key Usage set"); + } + break; + + case INHIBIT_ANY_OID: + WOLFSSL_MSG("INHIBIT ANY extension not supported"); + break; + + case EXT_KEY_USAGE_OID: + if (x509->extKeyUsageSrc != NULL) { + if (c != NULL) { + if (x509->extKeyUsageCount > 1) { + *c = -2; + } + else { + *c = x509->extKeyUsageCrit; + } + } + obj = wolfSSL_ASN1_OBJECT_new(); + obj->type = EXT_KEY_USAGE_OID; + obj->obj = x509->extKeyUsageSrc; + obj->objSz = x509->extKeyUsageSz; + } + else { + WOLFSSL_MSG("No Extended Key Usage set"); + } + break; + + case NAME_CONS_OID: + WOLFSSL_MSG("Name Constraint OID extension not supported"); + break; + + case PRIV_KEY_USAGE_PERIOD_OID: + WOLFSSL_MSG("Private Key Usage Period extension not supported"); + break; + + case SUBJECT_INFO_ACCESS: + WOLFSSL_MSG("Subject Info Access extension not supported"); + break; + + case POLICY_MAP_OID: + WOLFSSL_MSG("Policy Map extension not supported"); + break; + + case POLICY_CONST_OID: + WOLFSSL_MSG("Policy Constraint extension not supported"); + break; + + case ISSUE_ALT_NAMES_OID: + WOLFSSL_MSG("Issue Alt Names extension not supported"); + break; + + case TLS_FEATURE_OID: + WOLFSSL_MSG("TLS Feature extension not supported"); + break; + + default: + WOLFSSL_MSG("Unsupported/Unknown extension OID"); + } + + if (obj != NULL) { + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != SSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1 object onto stack"); + wolfSSL_ASN1_OBJECT_free(obj); + wolfSSL_sk_ASN1_OBJECT_free(sk); + sk = NULL; + } + } + else { /* no ASN1 object found for extension, free stack */ + wolfSSL_sk_ASN1_OBJECT_free(sk); + sk = NULL; + } + + (void)idx; + + return sk; +} + + +/* this function makes the assumption that out buffer is big enough for digest*/ +static int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, + unsigned int* outSz, const WOLFSSL_EVP_MD* evp, + WOLFSSL_ENGINE* eng) +{ + enum wc_HashType hash = WC_HASH_TYPE_NONE; + int hashSz; + + if (XSTRLEN(evp) < 3) { + /* do not try comparing strings if size is too small */ + return SSL_FAILURE; + } + + if (XSTRNCMP("SHA", evp, 3) == 0) { + if (XSTRLEN(evp) > 3) { + if (XSTRNCMP("SHA256", evp, 6) == 0) { + hash = WC_HASH_TYPE_SHA256; + } + else if (XSTRNCMP("SHA384", evp, 6) == 0) { + hash = WC_HASH_TYPE_SHA384; + } + else if (XSTRNCMP("SHA512", evp, 6) == 0) { + hash = WC_HASH_TYPE_SHA512; + } + else { + WOLFSSL_MSG("Unknown SHA hash"); + } + } + else { + hash = WC_HASH_TYPE_SHA; + } + } + else if (XSTRNCMP("MD2", evp, 3) == 0) { + hash = WC_HASH_TYPE_MD2; + } + else if (XSTRNCMP("MD4", evp, 3) == 0) { + hash = WC_HASH_TYPE_MD4; + } + else if (XSTRNCMP("MD5", evp, 3) == 0) { + hash = WC_HASH_TYPE_MD5; + } + + hashSz = wc_HashGetDigestSize(hash); + if (hashSz < 0) { + WOLFSSL_LEAVE("wolfSSL_EVP_Digest", hashSz); + return SSL_FAILURE; + } + *outSz = hashSz; + + (void)eng; + if (wc_Hash(hash, in, inSz, out, *outSz) == 0) { + return SSL_SUCCESS; + } + else { + return SSL_FAILURE; + } +} + + +int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest, + unsigned char* buf, unsigned int* len) +{ + WOLFSSL_ENTER("wolfSSL_X509_digest"); + + if (x509 == NULL || digest == NULL) { + return SSL_FAILURE; + } + + return wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf, + len, digest, NULL); +} + + +int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey) +{ + WOLFSSL_ENTER("wolfSSL_use_PrivateKey"); + if (ssl == NULL || pkey == NULL ) { + return SSL_FAILURE; + } + + return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr, + pkey->pkey_sz, SSL_FILETYPE_ASN1); +} + + +int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, unsigned char* der, + long derSz) +{ + WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1"); + if (ssl == NULL || der == NULL ) { + return SSL_FAILURE; + } + + (void)pri; /* type of private key */ + return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, SSL_FILETYPE_ASN1); +} + + +#ifndef NO_RSA +int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz) +{ + WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1"); + if (ssl == NULL || der == NULL ) { + return SSL_FAILURE; + } + + return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, SSL_FILETYPE_ASN1); +} +#endif + +int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, unsigned char* der, int derSz) +{ + long idx; + + WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1"); + if (der != NULL && ssl != NULL) { + if (ProcessBuffer(NULL, der, derSz, SSL_FILETYPE_ASN1, CERT_TYPE, ssl, + &idx, 0) == SSL_SUCCESS) + return SSL_SUCCESS; + } + + (void)idx; + return SSL_FAILURE; +} + + +int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509) +{ + long idx; + + WOLFSSL_ENTER("wolfSSL_use_certificate"); + if (x509 != NULL && ssl != NULL && x509->derCert != NULL) { + if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length, + SSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0) == SSL_SUCCESS) + return SSL_SUCCESS; + } + + (void)idx; + return SSL_FAILURE; +} +#endif /* NO_CERTS */ + + int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format) { WOLFSSL_ENTER("wolfSSL_use_certificate_file"); @@ -5686,45 +6336,6 @@ int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file) } - -#if !defined(NO_WOLFSSL_CLIENT) -/* Return the amount of random bytes copied over or error case. - * ssl : ssl struct after handshake - * out : buffer to hold random bytes - * outSz : either 0 (return max buffer sz) or size of out buffer - * - * NOTE: wolfSSL_KeepArrays(ssl) must be called to retain handshake information. - */ -int wolfSSL_get_client_random(WOLFSSL* ssl, unsigned char* out, int outSz) -{ - int size; - - /* return max size of buffer */ - if (outSz == 0) { - return RAN_LEN; - } - - if (ssl == NULL || out == NULL || outSz < 0) { - return BAD_FUNC_ARG; - } - - if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) { - WOLFSSL_MSG("Arrays struct not saved after handshake"); - return BAD_FUNC_ARG; - } - - if (outSz > RAN_LEN) { - size = RAN_LEN; - } - else { - size = outSz; - } - - XMEMCPY(out, ssl->arrays->clientRandom, size); - return size; -} -#endif /* !defined(NO_WOLFSSL_CLIENT) */ - #ifdef HAVE_ECC /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */ @@ -5771,6 +6382,47 @@ int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format) return wolfSSL_use_PrivateKey_file(ssl, file, format); } + +/* Copies the master secret over to out buffer. If outSz is 0 returns the size + * of master secret. + * + * ses : a session from completed TLS/SSL handshake + * out : buffer to hold copy of master secret + * outSz : size of out buffer + * returns : number of bytes copied into out buffer on success + * less then or equal to 0 is considered a failure case + */ +int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, + unsigned char* out, int outSz) +{ + int size; + + if (outSz == 0) { + return SECRET_LEN; + } + + if (ses == NULL || out == NULL || outSz < 0) { + return 0; + } + + if (outSz > SECRET_LEN) { + size = SECRET_LEN; + } + else { + size = outSz; + } + + XMEMCPY(out, ses->masterSecret, size); + return size; +} + + +int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses) +{ + (void)ses; + return SECRET_LEN; +} + #endif /* OPENSSL_EXTRA */ #ifdef HAVE_NTRU @@ -6913,6 +7565,20 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */ +#ifdef OPENSSL_EXTRA + WOLFSSL_METHOD* wolfSSLv23_method(void) { + WOLFSSL_METHOD* m; + WOLFSSL_ENTER("wolfSSLv23_method"); +#ifndef NO_WOLFSSL_CLIENT + m = wolfSSLv23_client_method(); +#else + m = wolfSSLv23_server_method(); +#endif + m->side = WOLFSSL_NEITHER_END; + + return m; + } +#endif /* OPENSSL_EXTRA */ /* client only parts */ #ifndef NO_WOLFSSL_CLIENT @@ -9010,12 +9676,18 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + /* returns previous set cache size which stays constant */ long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz) { /* cache size fixed at compile time in wolfSSL */ (void)ctx; (void)sz; - return 0; + WOLFSSL_MSG("session cache is set at compile time"); + #ifndef NO_SESSION_CACHE + return SESSIONS_PER_ROW * SESSION_ROWS; + #else + return 0; + #endif } @@ -9157,6 +9829,16 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx) + { + (void)ctx; + WOLFSSL_ENTER("wolfSSL_CTX_get_options"); + WOLFSSL_MSG("wolfSSL options are set through API calls and macros"); + + return 0; + } + + long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt) { /* goahead calls with 0, do nothing */ @@ -9201,6 +9883,31 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx) + { + if (ctx == NULL) { + return NULL; + } + + return &(ctx->x509_store); + } + + +#ifndef NO_CERTS + void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str) + { + if (ctx == NULL || str == NULL) { + return; + } + + /* free cert manager if have one */ + if (ctx->cm != NULL) { + wolfSSL_CertManagerFree(ctx->cm); + } + ctx->cm = str->cm; + ctx->x509_store.cache = str->cache; + } + WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert( WOLFSSL_X509_STORE_CTX* ctx) @@ -9228,6 +9935,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return ctx->error_depth; return SSL_FATAL_ERROR; } +#endif WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void) @@ -9250,6 +9958,30 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void) + { + static WOLFSSL_BIO_METHOD bio_meth; + + WOLFSSL_ENTER("wolfSSL_BIO_f_bio"); + bio_meth.type = BIO_BIO; + + return &bio_meth; + } + + +#ifndef NO_FILESYSTEM + WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void) + { + static WOLFSSL_BIO_METHOD file_meth; + + WOLFSSL_ENTER("wolfSSL_BIO_f_file"); + file_meth.type = BIO_FILE; + + return &file_meth; + } +#endif + + WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void) { static WOLFSSL_BIO_METHOD meth; @@ -9261,6 +9993,17 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void) + { + static WOLFSSL_BIO_METHOD meth; + + WOLFSSL_ENTER("BIO_s_socket"); + meth.type = BIO_SOCKET; + + return &meth; + } + + WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF) { WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0, @@ -9268,15 +10011,11 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_ENTER("BIO_new_socket"); if (bio) { + XMEMSET(bio, 0, sizeof(WOLFSSL_BIO)); bio->type = BIO_SOCKET; bio->close = (byte)closeF; - bio->eof = 0; - bio->ssl = 0; bio->fd = sfd; - bio->prev = 0; - bio->next = 0; bio->mem = NULL; - bio->memLen = 0; } return bio; } @@ -9294,28 +10033,41 @@ int wolfSSL_set_compression(WOLFSSL* ssl) long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF) { - WOLFSSL_ENTER("BIO_set_ssl"); - b->ssl = ssl; - b->close = (byte)closeF; + WOLFSSL_ENTER("wolfSSL_BIO_set_ssl"); + + if (b != NULL) { + b->ssl = ssl; + b->close = (byte)closeF; /* add to ssl for bio free if SSL_free called before/instead of free_all? */ + } return 0; } + long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int closeF) + { + WOLFSSL_ENTER("wolfSSL_BIO_set_fd"); + + if (b != NULL) { + b->fd = fd; + b->close = (byte)closeF; + } + + return SSL_SUCCESS; + } + + WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method) { WOLFSSL_BIO* bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0, DYNAMIC_TYPE_OPENSSL); WOLFSSL_ENTER("BIO_new"); if (bio) { + XMEMSET(bio, 0, sizeof(WOLFSSL_BIO)); bio->type = method->type; - bio->close = 0; - bio->eof = 0; bio->ssl = NULL; bio->mem = NULL; - bio->memLen = 0; - bio->fd = 0; bio->prev = NULL; bio->next = NULL; } @@ -9369,17 +10121,31 @@ int wolfSSL_set_compression(WOLFSSL* ssl) int wolfSSL_BIO_free(WOLFSSL_BIO* bio) { /* unchain?, doesn't matter in goahead since from free all */ - WOLFSSL_ENTER("BIO_free"); + WOLFSSL_ENTER("wolfSSL_BIO_free"); if (bio) { + /* remove from pair by setting the paired bios pair to NULL */ + if (bio->pair != NULL) { + bio->pair->pair = NULL; + } + if (bio->close) { if (bio->ssl) wolfSSL_free(bio->ssl); if (bio->fd) CloseSocket(bio->fd); } + + #ifndef NO_FILESYSTEM + if (bio->type == BIO_FILE && bio->close == BIO_CLOSE) { + if (bio->file) { + XFCLOSE(bio->file); + } + } + #endif + if (bio->mem) - XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL); - XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); + XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL); + XFREE(bio, bio->heap, DYNAMIC_TYPE_OPENSSL); } return 0; } @@ -9397,15 +10163,41 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) + { + int sz; + char* pt; + + sz = wolfSSL_BIO_nread(bio, &pt, len); + + if (sz > 0) { + XMEMCPY(buf, pt, sz); + } + + return sz; + } + + int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) { int ret; WOLFSSL* ssl = 0; WOLFSSL_BIO* front = bio; - WOLFSSL_ENTER("BIO_read"); + WOLFSSL_ENTER("wolfSSL_BIO_read"); + + if (bio && bio->type == BIO_BIO) { + return wolfSSL_BIO_BIO_read(bio, buf, len); + } + + #ifndef NO_FILESYSTEM + if (bio && bio->type == BIO_FILE) { + return (int)XFREAD(buf, 1, len, bio->file); + } + #endif + /* already got eof, again is error */ - if (front->eof) + if (bio && front->eof) return SSL_FATAL_ERROR; while(bio && ((ssl = bio->ssl) == 0) ) @@ -9425,15 +10217,47 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } + static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, + int len) + { + /* internal function where arguments have already been sanity checked */ + int sz; + char* buf; + + sz = wolfSSL_BIO_nwrite(bio, &buf, len); + + /* test space for write */ + if (sz <= 0) { + WOLFSSL_MSG("No room left to write"); + return sz; + } + + XMEMCPY(buf, data, sz); + + return sz; + } + + int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) { int ret; WOLFSSL* ssl = 0; WOLFSSL_BIO* front = bio; - WOLFSSL_ENTER("BIO_write"); + WOLFSSL_ENTER("wolfSSL_BIO_write"); + + if (bio && bio->type == BIO_BIO) { + return wolfSSL_BIO_BIO_write(bio, data, len); + } + + #ifndef NO_FILESYSTEM + if (bio && bio->type == BIO_FILE) { + return (int)XFWRITE(data, 1, len, bio->file); + } + #endif + /* already got eof, again is error */ - if (front->eof) + if (bio && front->eof) return SSL_FATAL_ERROR; while(bio && ((ssl = bio->ssl) == 0) ) @@ -9635,6 +10459,79 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA +#if !defined(NO_WOLFSSL_SERVER) +size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out, + size_t outSz) +{ + size_t size; + + /* return max size of buffer */ + if (outSz == 0) { + return RAN_LEN; + } + + if (ssl == NULL || out == NULL) { + return 0; + } + + if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) { + WOLFSSL_MSG("Arrays struct not saved after handshake"); + return 0; + } + + if (outSz > RAN_LEN) { + size = RAN_LEN; + } + else { + size = outSz; + } + + XMEMCPY(out, ssl->arrays->serverRandom, size); + return size; +} +#endif /* !defined(NO_WOLFSSL_SERVER) */ + + +#if !defined(NO_WOLFSSL_CLIENT) +/* Return the amount of random bytes copied over or error case. + * ssl : ssl struct after handshake + * out : buffer to hold random bytes + * outSz : either 0 (return max buffer sz) or size of out buffer + * + * NOTE: wolfSSL_KeepArrays(ssl) must be called to retain handshake information. + */ +size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, + size_t outSz) +{ + size_t size; + + /* return max size of buffer */ + if (outSz == 0) { + return RAN_LEN; + } + + if (ssl == NULL || out == NULL) { + return 0; + } + + if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) { + WOLFSSL_MSG("Arrays struct not saved after handshake"); + return 0; + } + + if (outSz > RAN_LEN) { + size = RAN_LEN; + } + else { + size = outSz; + } + + XMEMCPY(out, ssl->arrays->clientRandom, size); + return size; +} +#endif /* !defined(NO_WOLFSSL_CLIENT) */ + + unsigned long wolfSSLeay(void) { return SSLEAY_VERSION_NUMBER; @@ -9843,12 +10740,89 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif /* WOLFSSL_SHA512 */ + static struct s_ent{ + const unsigned char macType; + const char *name; + } md_tbl[] = { + #ifndef NO_MD5 + {MD5, "MD5"}, + #endif /* NO_MD5 */ + + #ifndef NO_SHA + {SHA, "SHA"}, + #endif /* NO_SHA */ + + #ifdef WOLFSSL_SHA224 + {SHA224, "SHA224"}, + #endif /* WOLFSSL_SHA224 */ + + {SHA256, "SHA256"}, + + #ifdef WOLFSSL_SHA384 + {SHA384, "SHA384"}, + #endif /* WOLFSSL_SHA384 */ + + #ifdef WOLFSSL_SHA512 + {SHA512, "SHA512"}, + #endif /* WOLFSSL_SHA512 */ + + {0, NULL} + } ; + +const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) +{ + static const struct alias { + const char *name; + const char *alias; + } alias_tbl[] = + { + {"MD5", "ssl3-md5"}, + {"SHA1", "ssl3-sha1"}, + { NULL, NULL} + }; + + const struct alias *al ; + const struct s_ent *ent ; + + for( al = alias_tbl; al->name != NULL; al++) + if(XSTRNCMP(name, al->alias, XSTRLEN(al->alias)+1) == 0) { + name = al->name; + break; + } + + for( ent = md_tbl; ent->name != NULL; ent++) + if(XSTRNCMP(name, ent->name, XSTRLEN(ent->name)+1) == 0) { + return (EVP_MD *)ent->name; + } + return NULL; +} + +static WOLFSSL_EVP_MD *wolfSSL_EVP_get_md(const unsigned char type) +{ + const struct s_ent *ent ; + for( ent = md_tbl; ent->macType != 0; ent++) + if(type == ent->macType) { + return (WOLFSSL_EVP_MD *)ent->name; + } + return 0; +} + +int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) +{ + const struct s_ent *ent ; + for( ent = md_tbl; ent->name != NULL; ent++) + if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) { + return ent->macType; + } + return 0; +} + #ifndef NO_MD5 const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void) { - static const char* type = "MD5"; + const char* type = EVP_get_digestbyname("MD5"); WOLFSSL_ENTER("EVP_md5"); return type; } @@ -9859,7 +10833,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifndef NO_SHA const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void) { - static const char* type = "SHA"; + const char* type = EVP_get_digestbyname("SHA"); WOLFSSL_ENTER("EVP_sha1"); return type; } @@ -9869,7 +10843,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void) { - static const char* type = "SHA224"; + const char* type = EVP_get_digestbyname("SHA224"); WOLFSSL_ENTER("EVP_sha224"); return type; } @@ -9879,7 +10853,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void) { - static const char* type = "SHA256"; + const char* type = EVP_get_digestbyname("SHA256"); WOLFSSL_ENTER("EVP_sha256"); return type; } @@ -9888,7 +10862,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void) { - static const char* type = "SHA384"; + const char* type = EVP_get_digestbyname("SHA384"); WOLFSSL_ENTER("EVP_sha384"); return type; } @@ -9899,13 +10873,33 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void) { - static const char* type = "SHA512"; + const char* type = EVP_get_digestbyname("SHA512"); WOLFSSL_ENTER("EVP_sha512"); return type; } #endif /* WOLFSSL_SHA512 */ + WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void) + { + WOLFSSL_EVP_MD_CTX* ctx; + WOLFSSL_ENTER("EVP_MD_CTX_new"); + ctx = (WOLFSSL_EVP_MD_CTX*)XMALLOC(sizeof *ctx, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (ctx){ + wolfSSL_EVP_MD_CTX_init(ctx); + } + return ctx; + } + + WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx) + { + if (ctx) { + WOLFSSL_ENTER("EVP_MD_CTX_free"); + wolfSSL_EVP_MD_CTX_cleanup(ctx); + XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + } void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx) { @@ -9914,6 +10908,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) /* do nothing */ } + const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx) + { + if (!ctx) + return NULL; + return (const WOLFSSL_EVP_MD *)wolfSSL_EVP_get_md(ctx->macType); + } + #ifndef NO_AES const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void) @@ -9957,6 +10958,25 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return EVP_AES_256_CTR; } + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ecb"); + return EVP_AES_128_ECB; + } + + + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ecb"); + return EVP_AES_192_ECB; + } + + + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ecb"); + return EVP_AES_256_ECB; + } #endif /* NO_AES */ #ifndef NO_DES3 @@ -9965,13 +10985,25 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_ENTER("wolfSSL_EVP_des_cbc"); return EVP_DES_CBC; } - - +#ifdef WOLFSSL_DES_ECB + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_des_ecb"); + return EVP_DES_ECB; + } +#endif const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void) { WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc"); return EVP_DES_EDE3_CBC; } +#ifdef WOLFSSL_DES_ECB + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_ecb"); + return EVP_DES_EDE3_ECB; + } +#endif #endif /* NO_DES3 */ const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void) @@ -10050,13 +11082,19 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_MSG("no type set"); return 0; /* failure */ } + ctx->bufUsed = 0; + ctx->lastUsed = 0; + ctx->flags = 0; #ifndef NO_AES + /* printf("cipherType=%d\n", ctx->cipherType); */ if (ctx->cipherType == AES_128_CBC_TYPE || (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) { WOLFSSL_MSG(EVP_AES_128_CBC); ctx->cipherType = AES_128_CBC_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 16; + ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -10075,7 +11113,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) { WOLFSSL_MSG(EVP_AES_192_CBC); ctx->cipherType = AES_192_CBC_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 24; + ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -10094,7 +11134,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) { WOLFSSL_MSG(EVP_AES_256_CBC); ctx->cipherType = AES_256_CBC_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 32; + ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -10114,12 +11156,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) { WOLFSSL_MSG(EVP_AES_128_CTR); ctx->cipherType = AES_128_CTR_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 16; + ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION); if (ret != 0) return ret; } @@ -10133,12 +11177,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) { WOLFSSL_MSG(EVP_AES_192_CTR); ctx->cipherType = AES_192_CTR_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 24; + ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); + AES_ENCRYPTION); if (ret != 0) return ret; } @@ -10152,12 +11198,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) { WOLFSSL_MSG(EVP_AES_256_CTR); ctx->cipherType = AES_256_CTR_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 32; + ctx->block_size = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); + AES_ENCRYPTION); if (ret != 0) return ret; } @@ -10168,6 +11216,55 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } #endif /* WOLFSSL_AES_CTR */ + else if (ctx->cipherType == AES_128_ECB_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_128_ECB); + ctx->cipherType = AES_128_ECB_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_ECB_MODE; + ctx->keyLen = 16; + ctx->block_size = AES_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL, + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + } + if (ret != 0) + return ret; + } + else if (ctx->cipherType == AES_192_ECB_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_ECB, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_192_ECB); + ctx->cipherType = AES_192_ECB_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_ECB_MODE; + ctx->keyLen = 24; + ctx->block_size = AES_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + if(ctx->enc) + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL, + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + } + if (ret != 0) + return ret; + } + else if (ctx->cipherType == AES_256_ECB_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_ECB, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_256_ECB); + ctx->cipherType = AES_256_ECB_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_ECB_MODE; + ctx->keyLen = 32; + ctx->block_size = AES_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, NULL, + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + } + if (ret != 0) + return ret; + } #endif /* NO_AES */ #ifndef NO_DES3 @@ -10175,7 +11272,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) { WOLFSSL_MSG(EVP_DES_CBC); ctx->cipherType = DES_CBC_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 8; + ctx->block_size = DES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -10188,12 +11287,32 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (iv && key == NULL) wc_Des_SetIV(&ctx->cipher.des, iv); } +#ifdef WOLFSSL_DES_ECB + else if (ctx->cipherType == DES_ECB_TYPE || + (type && XSTRNCMP(type, EVP_DES_ECB, EVP_DES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_DES_ECB); + ctx->cipherType = DES_ECB_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_ECB_MODE; + ctx->keyLen = 8; + ctx->block_size = DES_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_Des_SetKey(&ctx->cipher.des, key, NULL, + ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION); + if (ret != 0) + return ret; + } + } +#endif else if (ctx->cipherType == DES_EDE3_CBC_TYPE || (type && XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) { WOLFSSL_MSG(EVP_DES_EDE3_CBC); ctx->cipherType = DES_EDE3_CBC_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 24; + ctx->block_size = DES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -10209,12 +11328,30 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return ret; } } + else if (ctx->cipherType == DES_EDE3_ECB_TYPE || + (type && + XSTRNCMP(type, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0)) { + WOLFSSL_MSG(EVP_DES_EDE3_ECB); + ctx->cipherType = DES_EDE3_ECB_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_ECB_MODE; + ctx->keyLen = 24; + ctx->block_size = DES_BLOCK_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_Des3_SetKey(&ctx->cipher.des3, key, NULL, + ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION); + if (ret != 0) + return ret; + } + } #endif /* NO_DES3 */ #ifndef NO_RC4 if (ctx->cipherType == ARC4_TYPE || (type && XSTRNCMP(type, "ARC4", 4) == 0)) { WOLFSSL_MSG("ARC4"); ctx->cipherType = ARC4_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_STREAM_CIPHER; if (ctx->keyLen == 0) /* user may have already set */ ctx->keyLen = 16; /* default to 128 */ if (key) @@ -10227,6 +11364,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) { WOLFSSL_MSG(EVP_IDEA_CBC); ctx->cipherType = IDEA_CBC_TYPE; + ctx->flags = WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = IDEA_KEY_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; @@ -10313,6 +11451,17 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len); break; #endif /* HAVE_AES_CBC */ +#ifdef HAVE_AES_ECB + case AES_128_ECB_TYPE : + case AES_192_ECB_TYPE : + case AES_256_ECB_TYPE : + WOLFSSL_MSG("AES ECB"); + if (ctx->enc) + ret = wc_AesEcbEncrypt(&ctx->cipher.aes, dst, src, len); + else + ret = wc_AesEcbDecrypt(&ctx->cipher.aes, dst, src, len); + break; +#endif #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : case AES_192_CTR_TYPE : @@ -10330,13 +11479,28 @@ int wolfSSL_set_compression(WOLFSSL* ssl) else wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len); break; - +#ifdef WOLFSSL_DES_ECB + case DES_ECB_TYPE : + if (ctx->enc) + ret = wc_Des_EcbEncrypt(&ctx->cipher.des, dst, src, len); + else + ret = wc_Des_EcbDecrypt(&ctx->cipher.des, dst, src, len); + break; +#endif case DES_EDE3_CBC_TYPE : if (ctx->enc) ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len); else ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len); break; +#ifdef WOLFSSL_DES_ECB + case DES_EDE3_ECB_TYPE : + if (ctx->enc) + ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, dst, src, len); + else + ret = wc_Des3_EcbDecrypt(&ctx->cipher.des3, dst, src, len); + break; +#endif #endif #ifndef NO_RC4 @@ -10372,6 +11536,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return SSL_SUCCESS; /* success */ } +#include "wolfcrypt/src/evp.c" + /* store for external read of iv, SSL_SUCCESS on success */ int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx) @@ -10511,6 +11677,11 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const WOLFSSL_EVP_MD* type) { WOLFSSL_ENTER("EVP_DigestInit"); + + if (ctx == NULL || type == NULL) { + return BAD_FUNC_ARG; + } + if (XSTRNCMP(type, "SHA256", 6) == 0) { ctx->macType = SHA256; wolfSSL_SHA256_Init((SHA256_CTX*)&ctx->hash); @@ -10912,9 +12083,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx) { - /* TODO: maybe? */ (void)ctx; - return (~0); + #ifndef NO_SESSION_CACHE + return SESSIONS_PER_ROW * SESSION_ROWS; + #else + return 0; + #endif } unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line, @@ -10928,6 +12102,27 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return 0; } + WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb( + WOLFSSL_CTX *ctx) + { + if (ctx == NULL || ctx->passwd_cb == NULL) { + return NULL; + } + + return &(ctx->passwd_cb); + } + + + WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata( + WOLFSSL_CTX *ctx) + { + if (ctx == NULL) { + return NULL; + } + + return ctx->userdata; + } + #endif /* OPENSSL_EXTRA */ @@ -11899,6 +13094,135 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA +/* return 1 on success 0 on fail */ +int wolfSSL_sk_ASN1_OBJECT_push(STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk, + WOLFSSL_ASN1_OBJECT* obj) +{ + WOLFSSL_STACK* node; + + if (sk == NULL || obj == NULL) { + return SSL_FAILURE; + } + + /* no previous values in stack */ + if (sk->data.obj == NULL) { + sk->data.obj = obj; + sk->num += 1; + return SSL_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 SSL_FAILURE; + } + XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); + + /* push new obj onto head of stack */ + node->data.obj = sk->data.obj; + node->next = sk->next; + sk->next = node; + sk->data.obj = obj; + sk->num += 1; + + return SSL_SUCCESS; +} + + +WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJCET_pop( + STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_ASN1_OBJECT* obj; + + if (sk == NULL) { + return NULL; + } + + node = sk->next; + obj = sk->data.obj; + + if (node != NULL) { /* update sk and remove node from stack */ + sk->data.obj = node->data.obj; + sk->next = node->next; + XFREE(node, NULL, DYNAMIC_TYPE_ASN1); + } + else { /* last obj in stack */ + sk->data.obj = NULL; + } + + if (sk->num > 0) { + sk->num -= 1; + } + + return obj; +} + + +#ifndef NO_ASN +WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void) +{ + WOLFSSL_ASN1_OBJECT* obj; + + obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL, + DYNAMIC_TYPE_ASN1); + if (obj == NULL) { + return NULL; + } + + XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT)); + return obj; +} + + +void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj) +{ + if (obj == NULL) { + return; + } + + if (obj->dynamic == 1) { + if (obj->obj != NULL) { + WOLFSSL_MSG("Freeing ASN1 OBJECT data"); + XFREE(obj->obj, obj->heap, DYNAMIC_TYPE_ASN1); + } + } + + XFREE(obj, NULL, DYNAMIC_TYPE_ASN1); +} + + +/* free structure for x509 stack */ +void wolfSSL_sk_ASN1_OBJECT_free(STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) +{ + WOLFSSL_STACK* node; + + if (sk == NULL) { + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while (sk->num > 1) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + wolfSSL_ASN1_OBJECT_free(tmp->data.obj); + XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + wolfSSL_ASN1_OBJECT_free(sk->data.obj); + } + XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} +#endif /* NO_ASN */ + + int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id, unsigned int len) { @@ -12057,6 +13381,10 @@ char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len) WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl) { + if (ssl == NULL) { + return NULL; + } + /* sessions are stored statically, no need for reference count */ return wolfSSL_get_session(ssl); } @@ -12307,6 +13635,39 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, #ifndef NO_CERTS +WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) +{ + WOLFSSL_X509* localX509 = NULL; + const unsigned char* mem = NULL; + int ret; + word32 size; + + WOLFSSL_ENTER("wolfSSL_d2i_X509_bio"); + + if (bio == NULL) { + WOLFSSL_MSG("Bad Function Argument bio is NULL"); + return NULL; + } + + ret = wolfSSL_BIO_get_mem_data(bio, &mem); + if (mem == NULL || ret <= 0) { + WOLFSSL_MSG("Failed to get data from bio struct"); + return NULL; + } + size = ret; + + localX509 = wolfSSL_X509_d2i(NULL, mem, size); + if (localX509 == NULL) { + return NULL; + } + + if (x509 != NULL) { + *x509 = localX509; + } + + return localX509; +} + #if !defined(NO_ASN) && !defined(NO_PWDBASED) WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12) @@ -12622,6 +13983,18 @@ void wolfSSL_PKCS12_PBE_add(void) WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add"); } + + +WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return ctx->chain; +} + + int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) { int result = SSL_FATAL_ERROR; @@ -12679,6 +14052,23 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) } +int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag) +{ + int ret = SSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags"); + + if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) { + ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag); + } + + (void)store; + (void)flag; + + return ret; +} + + int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store) { (void)store; @@ -12717,6 +14107,7 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, if (ctx != NULL) { ctx->store = store; ctx->current_cert = x509; + ctx->chain = sk; ctx->domain = NULL; ctx->ex_data = NULL; ctx->userCtx = NULL; @@ -12736,6 +14127,8 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) wolfSSL_X509_STORE_free(ctx->store); if (ctx->current_cert != NULL) wolfSSL_FreeX509(ctx->current_cert); + if (ctx->chain != NULL) + wolfSSL_sk_X509_free(ctx->chain); XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX); } } @@ -12826,6 +14219,20 @@ void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj) } +WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new() +{ + WOLFSSL_EVP_PKEY* pkey; + + pkey = (WOLFSSL_EVP_PKEY*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY), NULL, + DYNAMIC_TYPE_PUBLIC_KEY); + if (pkey != NULL) { + XMEMSET(pkey, 0, sizeof(WOLFSSL_EVP_PKEY)); + } + + return pkey; +} + + void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) { if (key != NULL) { @@ -12929,7 +14336,6 @@ long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i) } - void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx) { WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data"); @@ -13003,13 +14409,223 @@ int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key) } +unsigned long wolfSSL_set_options(WOLFSSL* ssl, unsigned long op) +{ + WOLFSSL_ENTER("wolfSSL_set_options"); + + if (ssl == NULL) { + return 0; + } + + /* if SSL_OP_ALL then turn all bug workarounds one */ + if ((op & SSL_OP_ALL) == SSL_OP_ALL) { + WOLFSSL_MSG("\tSSL_OP_ALL"); + + op |= SSL_OP_MICROSOFT_SESS_ID_BUG; + op |= SSL_OP_NETSCAPE_CHALLENGE_BUG; + op |= SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; + op |= SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG; + op |= SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER; + op |= SSL_OP_MSIE_SSLV2_RSA_PADDING; + op |= SSL_OP_SSLEAY_080_CLIENT_DH_BUG; + op |= SSL_OP_TLS_D5_BUG; + op |= SSL_OP_TLS_BLOCK_PADDING_BUG; + op |= SSL_OP_TLS_ROLLBACK_BUG; + op |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + } + + + /* by default cookie exchange is on with DTLS */ + if ((op & SSL_OP_COOKIE_EXCHANGE) == SSL_OP_COOKIE_EXCHANGE) { + WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default"); + } + + if ((op & SSL_OP_NO_SSLv2) == SSL_OP_NO_SSLv2) { + WOLFSSL_MSG("\tSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2"); + } + + if ((op & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) { + WOLFSSL_MSG("\tSSL_OP_NO_SSLv3"); + } + + if ((op & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) { + WOLFSSL_MSG("\tSSL_OP_NO_TLSv1"); + } + + if ((op & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) { + WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1"); + } + + if ((op & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) { + WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2"); + } + + if ((op & SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION) { + #ifdef HAVE_LIBZ + WOLFSSL_MSG("SSL_OP_NO_COMPRESSION"); + ssl->options.usingCompression = 0; + #else + WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in"); + #endif + } + + ssl->options.mask |= op; + + return ssl->options.mask; +} + + +unsigned long wolfSSL_get_options(const WOLFSSL* ssl) +{ + WOLFSSL_ENTER("wolfSSL_get_options"); + + return ssl->options.mask; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_clear_num_renegotiations(WOLFSSL *s) +{ + (void)s; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_total_renegotiations(WOLFSSL *s) +{ + (void)s; + return 0; +} + + +#ifndef NO_DH +long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh) +{ + int pSz, gSz; + byte *p, *g; + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_set_tmp_dh"); + + if (!ssl || !dh) + return BAD_FUNC_ARG; + + /* Get needed size for p and g */ + pSz = wolfSSL_BN_bn2bin(dh->p, NULL); + gSz = wolfSSL_BN_bn2bin(dh->g, NULL); + + if (pSz <= 0 || gSz <= 0) + return SSL_FATAL_ERROR; + + p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_DH); + if (!p) + return MEMORY_E; + + g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_DH); + if (!g) { + XFREE(p, ssl->heap, DYNAMIC_TYPE_DH); + return MEMORY_E; + } + + pSz = wolfSSL_BN_bn2bin(dh->p, p); + gSz = wolfSSL_BN_bn2bin(dh->g, g); + + if (pSz >= 0 && gSz >= 0) /* Conversion successful */ + ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz); + + XFREE(p, ssl->heap, DYNAMIC_TYPE_DH); + XFREE(g, ssl->heap, DYNAMIC_TYPE_DH); + + return pSz > 0 && gSz > 0 ? ret : SSL_FATAL_ERROR; +} +#endif /* !NO_DH */ + + +#ifdef HAVE_PK_CALLBACKS +long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg) +{ + if (ssl == NULL) { + return SSL_FAILURE; + } + + ssl->loggingCtx = arg; + return SSL_SUCCESS; +} +#endif /* HAVE_PK_CALLBACKS */ + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type) +{ + (void)s; + (void)type; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg) +{ + (void)s; + (void)arg; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg) +{ + (void)s; + (void)arg; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg) +{ + (void)s; + (void)arg; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg) +{ + (void)s; + (void)arg; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp) +{ + (void)s; + (void)resp; + return 0; +} + +/*** TBD ***/ +WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len) +{ + (void)s; + (void)resp; + (void)len; + return 0; +} + + +long wolfSSL_get_verify_result(const WOLFSSL *ssl) +{ + if (ssl == NULL) { + return SSL_FAILURE; + } + + return ssl->peerVerifyRet; +} + + long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx) { (void)ctx; return 0; } - long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx) { (void)ctx; @@ -13086,14 +14702,130 @@ long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx) return 0; } + +#ifndef NO_CERTS +long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509) +{ + byte* chain; + long chainSz = 0; + int derSz; + const byte* der; + int ret; + + WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert"); + + if (ctx == NULL || x509 == NULL) { + WOLFSSL_MSG("Bad Argument"); + return SSL_FAILURE; + } + + der = wolfSSL_X509_get_der(x509, &derSz); + if (der == NULL || derSz <= 0) { + WOLFSSL_MSG("Error getting X509 DER"); + return SSL_FAILURE; + } + + /* adding cert to existing chain */ + if (ctx->certChain != NULL && ctx->certChain->length > 0) { + chainSz += ctx->certChain->length; + } + chainSz += derSz; + + chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (chain == NULL) { + WOLFSSL_MSG("Memory Error"); + return SSL_FAILURE; + } + + if (ctx->certChain != NULL && ctx->certChain->length > 0) { + XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length); + XMEMCPY(chain + ctx->certChain->length, der, derSz); + } + else { + XMEMCPY(chain, der, derSz); + } + + ret = ProcessBuffer(ctx, chain, chainSz, SSL_FILETYPE_ASN1, CERT_TYPE, + NULL, NULL, 1); + if (ret != SSL_SUCCESS) { + WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret); + XFREE(chain, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + return SSL_FAILURE; + } + + /* on success WOLFSSL_X509 memory is responsibility of ctx */ + wolfSSL_X509_free(x509); + XFREE(chain, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + + return SSL_SUCCESS; +} + + +long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg) +{ + if (ctx == NULL || ctx->cm == NULL) { + return SSL_FAILURE; + } + + ctx->cm->ocspIOCtx = arg; + return SSL_SUCCESS; +} + +#endif /* NO_CERTS */ + + +/*** TBC ***/ +WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx) +{ + (void)ctx; + return 0; +} + + +int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx) +{ + if (ctx == NULL) { + return SSL_FAILURE; + } + + return ctx->readAhead; +} + + +int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v) +{ + if (ctx == NULL) { + return SSL_FAILURE; + } + + ctx->readAhead = (byte)v; + + return SSL_SUCCESS; +} + + +long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx, + void* arg) +{ + if (ctx == NULL) { + return SSL_FAILURE; + } + + ctx->userPRFArg = arg; + return SSL_SUCCESS; +} + + #ifndef NO_DES3 -void wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, +/* 0 on success */ +int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, WOLFSSL_DES_key_schedule* key) { #ifdef WOLFSSL_CHECK_DESKEY - wolfSSL_DES_set_key_checked(myDes, key); + return wolfSSL_DES_set_key_checked(myDes, key); #else wolfSSL_DES_set_key_unchecked(myDes, key); + return 0; #endif } @@ -13111,12 +14843,14 @@ static int DES_check(word32 mask, word32 mask2, unsigned char* key) } -/* check that the key is odd parity and is not a weak key */ -void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, +/* check that the key is odd parity and is not a weak key + * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */ +int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, WOLFSSL_DES_key_schedule* key) { if (myDes == NULL || key == NULL) { WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked"); + return -2; } else { word32 i, mask, mask2; @@ -13125,7 +14859,7 @@ void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, /* sanity check before call to DES_check */ if (sz != (sizeof(word32) * 2)) { WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size"); - return; + return -2; } /* check odd parity */ @@ -13140,7 +14874,7 @@ void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, ((c >> 6) & 0x01) ^ ((c >> 7) & 0x01)) != 1) { WOLFSSL_MSG("Odd parity test fail"); - return; + return -1; } } @@ -13151,25 +14885,25 @@ void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, mask = 0x01010101; mask2 = 0x01010101; if (DES_check(mask, mask2, *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE; if (DES_check(mask, mask2, *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1; if (DES_check(mask, mask2, *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E; if (DES_check(mask, mask2, *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } /* semi-weak *key check (list from same Nist paper) */ @@ -13177,39 +14911,41 @@ void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, if (DES_check(mask, mask2, *key) || DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0x01E001E0; mask2 = 0x01F101F1; if (DES_check(mask, mask2, *key) || DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0x01FE01FE; mask2 = 0x01FE01FE; if (DES_check(mask, mask2, *key) || DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0x1FE01FE0; mask2 = 0x0EF10EF1; if (DES_check(mask, mask2, *key) || DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } mask = 0x1FFE1FFE; mask2 = 0x0EFE0EFE; if (DES_check(mask, mask2, *key) || DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { WOLFSSL_MSG("Weak key found"); - return; + return -2; } /* passed tests, now copy over key */ XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock)); + + return 0; } } @@ -13622,6 +15358,29 @@ int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a, } +/* r = (a^p) % m */ +int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, + const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_BN_mod_exp"); + + (void) ctx; + if (r == NULL || a == NULL || p == NULL || m == NULL) { + WOLFSSL_MSG("Bad Argument"); + return SSL_FAILURE; + } + + if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal, + (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) { + return SSL_SUCCESS; + } + + WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret); + return SSL_FAILURE; +} + const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void) { static WOLFSSL_BIGNUM* bn_one = NULL; @@ -14254,7 +16013,7 @@ char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn) { (void)bn; - WOLFSSL_MSG("wolfSSL_BN_bn2hex not implemented"); + WOLFSSL_MSG("wolfSSL_BN_bn2hex need WOLFSSL_KEY_GEN or HAVE_COMP_KEY"); return (char*)""; } @@ -14656,6 +16415,7 @@ void wolfSSL_DSA_free(WOLFSSL_DSA* dsa) dsa = NULL; } } + #endif /* NO_DSA */ #ifndef NO_RSA @@ -14738,8 +16498,10 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) #endif /* NO_RSA */ -#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)) \ - || !defined(NO_DSA) || defined(HAVE_ECC) +/* these defines are to make sure the functions SetIndividualExternal is not + * declared and then not used. */ +#if !defined(NO_ASN) || !defined(NO_DSA) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)) static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi) { WOLFSSL_MSG("Entering SetIndividualExternal"); @@ -14786,6 +16548,76 @@ static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi) return SSL_SUCCESS; } + + +#ifndef NO_ASN +WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai, + WOLFSSL_BIGNUM *bn) +{ + mp_int mpi; + word32 idx = 0; + int ret; + + WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN"); + + if (ai == NULL) { + return NULL; + } + + if ((ret = GetInt(&mpi, ai->data, &idx, sizeof(ai->data))) != 0) { + /* expecting ASN1 format for INTEGER */ + WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret); + return NULL; + } + + if (SetIndividualExternal(&bn, &mpi) != SSL_SUCCESS) { + return NULL; + } + + return bn; +} +#endif /* !NO_ASN */ + +#if !defined(NO_DSA) && !defined(NO_DH) +WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa) +{ + WOLFSSL_DH* dh; + DhKey* key; + + dh = wolfSSL_DH_new(); + if (dh == NULL || dsa == NULL) { + return NULL; + } + key = (DhKey*)dh->internal; + + if (dsa->p != NULL && + SetIndividualInternal(((WOLFSSL_DSA*)dsa)->p, &key->p) != SSL_SUCCESS) { + WOLFSSL_MSG("rsa p key error"); + wolfSSL_DH_free(dh); + return NULL; + } + if (dsa->g != NULL && + SetIndividualInternal(((WOLFSSL_DSA*)dsa)->g, &key->g) != SSL_SUCCESS) { + WOLFSSL_MSG("rsa g key error"); + wolfSSL_DH_free(dh); + return NULL; + } + + if (SetIndividualExternal(&dh->p, &key->p) != SSL_SUCCESS) { + WOLFSSL_MSG("dsa p key error"); + wolfSSL_DH_free(dh); + return NULL; + } + if (SetIndividualExternal(&dh->g, &key->g) != SSL_SUCCESS) { + WOLFSSL_MSG("dsa g key error"); + wolfSSL_DH_free(dh); + return NULL; + } + + return dh; +} +#endif /* !defined(NO_DSA) && !defined(NO_DH) */ + #endif /* !NO_RSA && !NO_DSA */ @@ -16035,6 +17867,74 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, } #endif /* defined(WOLFSSL_KEY_GEN) */ +#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) + +int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, + const WOLFSSL_EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb* cb, void* arg) +{ + byte* keyDer; + int pemSz; + int type; + int ret; + + (void)cipher; + (void)passwd; + (void)len; + (void)cb; + (void)arg; + + WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey"); + + if (bio == NULL || key == NULL) { + return SSL_FAILURE; + } + + keyDer = (byte*)key->pkey.ptr; + + switch (key->type) { + case EVP_PKEY_RSA: + type = PRIVATEKEY_TYPE; + break; + +#ifndef NO_DSA + case EVP_PKEY_DSA: + type = DSA_PRIVATEKEY_TYPE; + break; +#endif + + case EVP_PKEY_EC: + type = ECC_PRIVATEKEY_TYPE; + break; + + default: + WOLFSSL_MSG("Unknown Key type!"); + type = PRIVATEKEY_TYPE; + } + + pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type); + if (pemSz < 0) { + WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz); + return SSL_FAILURE; + } + if (bio->mem != NULL) { + XFREE(bio->mem, NULL, DYNAMIC_TYPE_OPENSSL); + } + bio->mem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_OPENSSL); + bio->memLen = pemSz; + + ret = wc_DerToPemEx(keyDer, key->pkey_sz, bio->mem, bio->memLen, + NULL, type); + if (ret < 0) { + WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret); + return SSL_FAILURE; + } + + return SSL_SUCCESS; +} +#endif /* defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) */ + #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) /* return code compliant with OpenSSL : @@ -16186,7 +18086,7 @@ int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, - pem_password_cb cb, void* arg) + pem_password_cb* cb, void* arg) { (void)bio; (void)rsa; @@ -17429,7 +19329,7 @@ int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *x) int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc, const EVP_CIPHER* cipher, unsigned char* passwd, int len, - pem_password_cb cb, void* arg) + pem_password_cb* cb, void* arg) { (void)bio; (void)ecc; @@ -17604,7 +19504,7 @@ int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc, int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, - pem_password_cb cb, void* arg) + pem_password_cb* cb, void* arg) { (void)bio; (void)dsa; @@ -17784,7 +19684,7 @@ int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x) #endif /* #ifndef NO_DSA */ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, - WOLFSSL_EVP_PKEY** key, pem_password_cb cb, void* arg) + WOLFSSL_EVP_PKEY** key, pem_password_cb* cb, void* arg) { (void)bio; (void)key; @@ -18323,6 +20223,62 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA /*Lighttp compatibility*/ + + #ifndef NO_CERTS + WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, + pem_password_cb *cb, void *u) { + WOLFSSL_X509* x509 = NULL; + const unsigned char* pem = NULL; + int pemSz; + + WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509"); + + if (bp == NULL) { + WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG); + return NULL; + } + + pemSz = wolfSSL_BIO_get_mem_data(bp, &pem); + if (pemSz <= 0 || pem == NULL) { + WOLFSSL_MSG("Issue getting WOLFSSL_BIO mem"); + WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", pemSz); + return NULL; + } + + x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz, + SSL_FILETYPE_PEM); + + if (x != NULL) { + *x = x509; + } + + (void)cb; + (void)u; + + return x509; + } + + + /* + * bp : bio to read X509 from + * x : x509 to write to + * cb : password call back for reading PEM + * u : password + * _AUX is for working with a trusted X509 certificate + */ + WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp, + WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { + WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509"); + + /* AUX info is; trusted/rejected uses, friendly name, private key id, + * and potentially a stack of "other" info. wolfSSL does not store + * friendly name or private key id yet in WOLFSSL_X509 for human + * readibility and does not support extra trusted/rejected uses for + * root CA. */ + return wolfSSL_PEM_read_bio_X509(bp, x, cb, u); + } + #endif /* ifndef NO_CERTS */ + #if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md) @@ -18343,16 +20299,6 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) return 0; } - int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) { - (void)ctx; - (void)pkey; - WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey"); - WOLFSSL_STUB("wolfSSL_CTX_use_PrivateKey"); - - return 0; - } - - int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) { (void)b; (void)name; @@ -18362,17 +20308,10 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) return 0; } - WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void) { - WOLFSSL_ENTER("wolfSSL_BIO_s_file"); - WOLFSSL_STUB("wolfSSL_BIO_s_file"); - - return NULL; - } - #ifdef HAVE_ECC - const char * wolf_OBJ_nid2sn(int n) { + const char * wolfSSL_OBJ_nid2sn(int n) { int i; - WOLFSSL_ENTER("wolf_OBJ_nid2sn"); + WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn"); /* find based on NID and return name */ for (i = 0; i < ecc_sets[i].size; i++) { @@ -18383,17 +20322,17 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) return NULL; } - int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) { + int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) { (void)o; - WOLFSSL_ENTER("wolf_OBJ_obj2nid"); - WOLFSSL_STUB("wolf_OBJ_obj2nid"); + WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid"); + WOLFSSL_STUB("wolfSSL_OBJ_obj2nid"); return 0; } - int wolf_OBJ_sn2nid(const char *sn) { + int wolfSSL_OBJ_sn2nid(const char *sn) { int i; - WOLFSSL_ENTER("wolf_OBJ_osn2nid"); + WOLFSSL_ENTER("wolfSSL_OBJ_osn2nid"); /* find based on name and return NID */ for (i = 0; i < ecc_sets[i].size; i++) { @@ -18406,17 +20345,6 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) #endif /* HAVE_ECC */ - WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { - (void)bp; - (void)x; - (void)cb; - (void)u; - WOLFSSL_ENTER("PEM_read_bio_WOLFSSL_X509"); - WOLFSSL_STUB("PEM_read_bio_WOLFSSL_X509"); - - return NULL; - } - void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) { (void)ctx; (void)depth; @@ -18518,6 +20446,46 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA + +/* wolfSSL uses negative values for error states. This function returns an + * unsigned type so the value returned is the absolute value of the error. + */ +unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line) +{ + WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error"); + + (void)line; + (void)file; +#if defined(DEBUG_WOLFSSL) + if (line != NULL) { + *line = (int)wc_last_error_line; + } + if (file != NULL) { + *file = (char*)wc_last_error_file; + } + return wc_last_error; +#else + return (unsigned long)(0 - NOT_COMPILED_IN); +#endif +} + + +#ifndef NO_CERTS +int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) +{ + WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey"); + + if (ctx == NULL || pkey == NULL) { + return SSL_FAILURE; + } + + return wolfSSL_CTX_use_PrivateKey_buffer(ctx, + (const unsigned char*)pkey->pkey.ptr, + pkey->pkey_sz, PRIVATEKEY_TYPE); +} +#endif /* !NO_CERTS */ + + void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx) { WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); @@ -18607,23 +20575,122 @@ void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx) #endif return 0; } + +#ifndef NO_DSA +WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x, pem_password_cb *cb, void *u) +{ + WOLFSSL_DSA* dsa; + DsaKey* key; + int length; + const unsigned char* buf; + word32 bufSz; + int ret; + word32 idx = 0; + DerBuffer* pDer; + + WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams"); + + ret = wolfSSL_BIO_get_mem_data(bp, &buf); + if (ret <= 0) { + WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret); + return NULL; + } + + bufSz = (word32)ret; + + if (cb != NULL || u != NULL) { + /* + * cb is for a call back when encountering encrypted PEM files + * if cb == NULL and u != NULL then u = null terminated password string + */ + WOLFSSL_MSG("Not yet supporting call back or password for encrypted PEM"); + } + + if ((ret = PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL, + NULL)) < 0 ) { + WOLFSSL_MSG("Issue converting from PEM to DER"); + return NULL; + } + + if ((ret = GetSequence(pDer->buffer, &idx, &length, pDer->length)) < 0) { + WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret); + FreeDer(&pDer); + return NULL; + } + + dsa = wolfSSL_DSA_new(); + if (dsa == NULL) { + FreeDer(&pDer); + WOLFSSL_MSG("Error creating DSA struct"); + return NULL; + } + + key = (DsaKey*)dsa->internal; + if (key == NULL) { + FreeDer(&pDer); + wolfSSL_DSA_free(dsa); + WOLFSSL_MSG("Error finding DSA key struct"); + return NULL; + } + + if (GetInt(&key->p, pDer->buffer, &idx, pDer->length) < 0 || + GetInt(&key->q, pDer->buffer, &idx, pDer->length) < 0 || + GetInt(&key->g, pDer->buffer, &idx, pDer->length) < 0 ) { + WOLFSSL_MSG("dsa key error"); + FreeDer(&pDer); + wolfSSL_DSA_free(dsa); + return NULL; + } + + if (SetIndividualExternal(&dsa->p, &key->p) != SSL_SUCCESS) { + WOLFSSL_MSG("dsa p key error"); + FreeDer(&pDer); + wolfSSL_DSA_free(dsa); + return NULL; + } + + if (SetIndividualExternal(&dsa->q, &key->q) != SSL_SUCCESS) { + WOLFSSL_MSG("dsa q key error"); + FreeDer(&pDer); + wolfSSL_DSA_free(dsa); + return NULL; + } + + if (SetIndividualExternal(&dsa->g, &key->g) != SSL_SUCCESS) { + WOLFSSL_MSG("dsa g key error"); + FreeDer(&pDer); + wolfSSL_DSA_free(dsa); + return NULL; + } + + if (x != NULL) { + *x = dsa; + } + + FreeDer(&pDer); + return dsa; +} +#endif /* NO_DSA */ + +#include "src/bio.c" + #endif /* OPENSSL_EXTRA */ #if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \ - || defined(WOLFSSL_MYSQL_COMPATIBLE) -char * wolf_OBJ_nid2ln(int n) { + || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) +char * wolfSSL_OBJ_nid2ln(int n) { (void)n; - WOLFSSL_ENTER("wolf_OBJ_nid2ln"); - WOLFSSL_STUB("wolf_OBJ_nid2ln"); + WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln"); + WOLFSSL_STUB("wolfSSL_OBJ_nid2ln"); return NULL; } -int wolf_OBJ_txt2nid(const char* s) { +int wolfSSL_OBJ_txt2nid(const char* s) { (void)s; - WOLFSSL_ENTER("wolf_OBJ_txt2nid"); - WOLFSSL_STUB("wolf_OBJ_txt2nid"); + WOLFSSL_ENTER("wolfSSL_OBJ_txt2nid"); + WOLFSSL_STUB("wolfSSL_OBJ_txt2nid"); return 0; } @@ -18652,11 +20719,12 @@ WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_p return NULL; } -int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) { + +int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) { (void)bp; (void)x; - WOLFSSL_ENTER("PEM_write_bio_WOLFSSL_X509"); - WOLFSSL_STUB("PEM_write_bio_WOLFSSL_X509"); + WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509"); + WOLFSSL_STUB("wolfSSL_PEM_write_bio_X509"); return 0; } @@ -18715,6 +20783,11 @@ void WOLFSSL_ERR_remove_thread_state(void* pid) return; } +/***TBD ***/ +void wolfSSL_print_all_errors_fp(XFILE *fp) +{ + (void)fp; +} int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data) { @@ -18980,16 +21053,6 @@ STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl) } -long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx) -{ - (void)ctx; - WOLFSSL_ENTER("wolfSSL_CTX_get_options"); - WOLFSSL_STUB("wolfSSL_CTX_get_options"); - - return 0; -} - - WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl) { WOLFSSL_ENTER("wolfSSL_get_SSL_CTX"); diff --git a/tests/api.c b/tests/api.c index e20303cb2e..ad204ad11b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -46,6 +46,10 @@ #ifdef OPENSSL_EXTRA #include #include + #include + #include + #include + #include #ifndef NO_DES3 #include #endif @@ -632,7 +636,13 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #endif ((func_args*)args)->return_code = TEST_FAIL; - method = wolfSSLv23_server_method(); + if (((func_args*)args)->callbacks != NULL && + ((func_args*)args)->callbacks->method != NULL) { + method = ((func_args*)args)->callbacks->method(); + } + else { + method = wolfSSLv23_server_method(); + } ctx = wolfSSL_CTX_new(method); #if defined(USE_WINDOWS_API) @@ -774,7 +784,13 @@ static void test_client_nofail(void* args) #endif ((func_args*)args)->return_code = TEST_FAIL; - method = wolfSSLv23_client_method(); + if (((func_args*)args)->callbacks != NULL && + ((func_args*)args)->callbacks->method != NULL) { + method = ((func_args*)args)->callbacks->method(); + } + else { + method = wolfSSLv23_client_method(); + } ctx = wolfSSL_CTX_new(method); #ifdef OPENSSL_EXTRA @@ -1139,6 +1155,8 @@ static void test_wolfSSL_read_write(void) func_args server_args; THREAD_TYPE serverThread; + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif @@ -1194,6 +1212,8 @@ static void test_wolfSSL_dtls_export(void) #endif /* set using dtls */ + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); XMEMSET(&server_cbf, 0, sizeof(callback_functions)); XMEMSET(&client_cbf, 0, sizeof(callback_functions)); server_cbf.method = wolfDTLSv1_2_server_method; @@ -1237,6 +1257,9 @@ static void test_wolfSSL_client_server(callback_functions* client_callbacks, func_args server_args; THREAD_TYPE serverThread; + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); + StartTCP(); client_args.callbacks = client_callbacks; @@ -1971,7 +1994,7 @@ static void test_wolfSSL_DisableExtendedMasterSecret(void) *----------------------------------------------------------------------------*/ static void test_wolfSSL_X509_NAME_get_entry(void) { -#ifndef NO_CERTS +#if !defined(NO_CERTS) && !defined(NO_RSA) #if defined(OPENSSL_EXTRA) && (defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)) \ && (defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE)) printf(testingFmt, "wolfSSL_X509_NAME_get_entry()"); @@ -2019,7 +2042,7 @@ static void test_wolfSSL_PKCS12(void) { /* .p12 file is encrypted with DES3 */ #if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && !defined(NO_FILESYSTEM) && \ - !defined(NO_ASN) && !defined(NO_PWDBASED) + !defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA) byte buffer[5300]; char file[] = "./certs/test-servercert.p12"; FILE *f; @@ -2231,12 +2254,12 @@ static void test_wolfSSL_DES(void) /* check, check of odd parity */ XMEMSET(key, 4, sizeof(DES_key_schedule)); key[0] = 3; /*set even parity*/ XMEMSET(myDes, 5, sizeof(const_DES_cblock)); - DES_set_key_checked(&myDes, &key); + AssertIntEQ(DES_set_key_checked(&myDes, &key), -1); AssertIntNE(key[0], myDes[0]); /* should not have copied over key */ /* set odd parity for success case */ key[0] = 4; - DES_set_key_checked(&myDes, &key); + AssertIntEQ(DES_set_key_checked(&myDes, &key), 0); for (i = 0; i < sizeof(DES_key_schedule); i++) { AssertIntEQ(key[i], myDes[i]); } @@ -2244,7 +2267,7 @@ static void test_wolfSSL_DES(void) /* check weak key */ XMEMSET(key, 1, sizeof(DES_key_schedule)); XMEMSET(myDes, 5, sizeof(const_DES_cblock)); - DES_set_key_checked(&myDes, &key); + AssertIntEQ(DES_set_key_checked(&myDes, &key), -2); AssertIntNE(key[0], myDes[0]); /* should not have copied over key */ /* now do unchecked copy of a weak key over */ @@ -2258,6 +2281,745 @@ static void test_wolfSSL_DES(void) #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ } + +static void test_wolfSSL_certs(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + X509* x509; + WOLFSSL* ssl; + WOLFSSL_CTX* ctx; + STACK_OF(ASN1_OBJECT)* sk; + int crit; + + printf(testingFmt, "wolfSSL_certs()"); + + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + AssertTrue(SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)); + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + AssertIntEQ(wolfSSL_check_private_key(ssl), SSL_SUCCESS); + + #ifdef HAVE_PK_CALLBACKS + AssertIntEQ((int)SSL_set_tlsext_debug_arg(ssl, NULL), SSL_SUCCESS); + #endif /* HAVE_PK_CALLBACKS */ + + /* create and use x509 */ + x509 = wolfSSL_X509_load_certificate_file(cliCert, SSL_FILETYPE_PEM); + AssertNotNull(x509); + AssertIntEQ(SSL_use_certificate(ssl, x509), SSL_SUCCESS); + + #ifndef HAVE_USER_RSA + /* with loading in a new cert the check on private key should now fail */ + AssertIntNE(wolfSSL_check_private_key(ssl), SSL_SUCCESS); + #endif + + + #if defined(USE_CERT_BUFFERS_2048) + AssertIntEQ(SSL_use_certificate_ASN1(ssl, + (unsigned char*)server_cert_der_2048, + sizeof_server_cert_der_2048), SSL_SUCCESS); + #endif + + #if !defined(NO_SHA) && !defined(NO_SHA256) + /************* Get Digest of Certificate ******************/ + { + byte digest[64]; /* max digest size */ + word32 digestSz; + + XMEMSET(digest, 0, sizeof(digest)); + AssertIntEQ(X509_digest(x509, wolfSSL_EVP_sha1(), digest, &digestSz), + SSL_SUCCESS); + AssertIntEQ(X509_digest(x509, wolfSSL_EVP_sha256(), digest, &digestSz), + SSL_SUCCESS); + + AssertIntEQ(X509_digest(NULL, wolfSSL_EVP_sha1(), digest, &digestSz), + SSL_FAILURE); + } + #endif /* !NO_SHA && !NO_SHA256*/ + + /* test and checkout X509 extensions */ + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_basic_constraints, + &crit, NULL); + AssertNotNull(sk); + AssertIntEQ(crit, 0); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_key_usage, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_ext_key_usage, + &crit, NULL); + /* AssertNotNull(sk); no extension set */ + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + NID_authority_key_identifier, &crit, NULL); + AssertNotNull(sk); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + NID_private_key_usage_period, &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_subject_alt_name, + &crit, NULL); + /* AssertNotNull(sk); no alt names set */ + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_issuer_alt_name, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_info_access, &crit, + NULL); + /* AssertNotNull(sk); no auth info set */ + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_sinfo_access, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_name_constraints, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + NID_certificate_policies, &crit, NULL); + #if !defined(WOLFSSL_SEP) && !defined(WOLFSSL_CERT_EXT) + AssertNull(sk); + #else + /* AssertNotNull(sk); no cert policy set */ + #endif + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_policy_mappings, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_policy_constraints, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_inhibit_any_policy, + &crit, NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_tlsfeature, &crit, + NULL); + /* AssertNotNull(sk); NID not yet supported */ + AssertIntEQ(crit, -1); + wolfSSL_sk_ASN1_OBJECT_free(sk); + + /* test invalid cases */ + crit = 0; + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, -1, &crit, NULL); + AssertNull(sk); + AssertIntEQ(crit, -1); + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(NULL, NID_tlsfeature, + NULL, NULL); + AssertNull(sk); + + AssertIntEQ(SSL_get_hit(ssl), 0); + X509_free(x509); + SSL_free(ssl); + SSL_CTX_free(ctx); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ +} + + +static void test_wolfSSL_private_keys(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + WOLFSSL* ssl; + WOLFSSL_CTX* ctx; + EVP_PKEY* pkey = NULL; + + printf(testingFmt, "wolfSSL_private_keys()"); + + OpenSSL_add_all_digests(); + OpenSSL_add_all_algorithms(); + + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + AssertTrue(SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)); + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + AssertIntEQ(wolfSSL_check_private_key(ssl), SSL_SUCCESS); + +#ifdef USE_CERT_BUFFERS_2048 + { + const unsigned char* server_key = (const unsigned char*)server_key_der_2048; + + AssertIntEQ(SSL_use_RSAPrivateKey_ASN1(ssl, + (unsigned char*)client_key_der_2048, + sizeof_client_key_der_2048), SSL_SUCCESS); +#ifndef HAVE_USER_RSA + /* Should missmatch now that a different private key loaded */ + AssertIntNE(wolfSSL_check_private_key(ssl), SSL_SUCCESS); +#endif + + AssertIntEQ(SSL_use_PrivateKey_ASN1(0, ssl, + (unsigned char*)server_key, + sizeof_server_key_der_2048), SSL_SUCCESS); + /* After loading back in DER format of original key, should match */ + AssertIntEQ(wolfSSL_check_private_key(ssl), SSL_SUCCESS); + + /* pkey not set yet, expecting to fail */ + AssertIntEQ(SSL_use_PrivateKey(ssl, pkey), SSL_FAILURE); + + /* set PKEY and test again */ + AssertNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey, + &server_key, (long)sizeof_server_key_der_2048)); + AssertIntEQ(SSL_use_PrivateKey(ssl, pkey), SSL_SUCCESS); + } +#endif + + + EVP_PKEY_free(pkey); + SSL_free(ssl); /* frees x509 also since loaded into ssl */ + SSL_CTX_free(ctx); + + /* test existence of no-op macros in wolfssl/openssl/ssl.h */ + CONF_modules_free(); + ENGINE_cleanup(); + CONF_modules_unload(); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ +} + + +static void test_wolfSSL_PEM_PrivateKey(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \ + (defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)) && \ + defined(USE_CERT_BUFFERS_2048) + const unsigned char* server_key = (const unsigned char*)server_key_der_2048; + EVP_PKEY* pkey = NULL; + BIO* bio; + + printf(testingFmt, "wolfSSL_PEM_PrivateKey()"); + + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); + AssertNotNull(bio); + + AssertNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey, + &server_key, (long)sizeof_server_key_der_2048)); + AssertIntEQ(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL), + SSL_SUCCESS); + + BIO_free(bio); + EVP_PKEY_free(pkey); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ +} + + +static void test_wolfSSL_tmp_dh(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_DSA) && !defined(NO_RSA) + byte buffer[5300]; + char file[] = "./certs/dsaparams.pem"; + FILE *f; + int bytes; + DSA* dsa; + DH* dh; + BIO* bio; + SSL* ssl; + SSL_CTX* ctx; + + printf(testingFmt, "wolfSSL_tmp_dh()"); + + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + AssertTrue(SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)); + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + f = fopen(file, "rb"); + AssertNotNull(f); + bytes = (int)fread(buffer, 1, sizeof(buffer), f); + fclose(f); + + bio = BIO_new_mem_buf((void*)buffer, bytes); + AssertNotNull(bio); + + dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); + AssertNotNull(dsa); + + dh = wolfSSL_DSA_dup_DH(dsa); + AssertNotNull(dh); + + AssertIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), SSL_SUCCESS); + AssertIntEQ((int)SSL_set_tmp_dh(ssl, dh), SSL_SUCCESS); + + BIO_free(bio); + DSA_free(dsa); + DH_free(dh); + SSL_free(ssl); + SSL_CTX_free(ctx); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ +} + +static void test_wolfSSL_ctrl(void) +{ + #if defined(OPENSSL_EXTRA) + byte buffer[5300]; + BIO* bio; + int bytes; + BUF_MEM* ptr = NULL; + + printf(testingFmt, "wolfSSL_crtl()"); + + bytes = sizeof(buffer); + bio = BIO_new_mem_buf((void*)buffer, bytes); + AssertNotNull(bio); + AssertNotNull(BIO_s_socket()); + + AssertIntEQ((int)wolfSSL_BIO_get_mem_ptr(bio, &ptr), SSL_SUCCESS); + + /* needs tested after stubs filled out @TODO + SSL_ctrl + SSL_CTX_ctrl + */ + + BIO_free(bio); + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) */ +} + + +static void test_wolfSSL_CTX_add_extra_chain_cert(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + char caFile[] = "./certs/client-ca.pem"; + char clientFile[] = "./certs/client-cert.pem"; + SSL_CTX* ctx; + X509* x509 = NULL; + + printf(testingFmt, "wolfSSL_CTX_add_extra_chain_cert()"); + + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + + x509 = wolfSSL_X509_load_certificate_file(caFile, SSL_FILETYPE_PEM); + AssertNotNull(x509); + AssertIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), SSL_SUCCESS); + + x509 = wolfSSL_X509_load_certificate_file(clientFile, SSL_FILETYPE_PEM); + AssertNotNull(x509); + AssertIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), SSL_SUCCESS); + + AssertNull(SSL_CTX_get_default_passwd_cb(ctx)); + AssertNull(SSL_CTX_get_default_passwd_cb_userdata(ctx)); + + SSL_CTX_free(ctx); + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ +} + + +static void test_wolfSSL_ERR_peek_last_error_line(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL) + tcp_ready ready; + func_args client_args; + func_args server_args; + THREAD_TYPE serverThread; + callback_functions client_cb; + callback_functions server_cb; + int line = 0; + const char* file = NULL; + + printf(testingFmt, "wolfSSL_ERR_peek_last_error_line()"); + + /* create a failed connection and inspect the error */ +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + XMEMSET(&client_args, 0, sizeof(func_args)); + XMEMSET(&server_args, 0, sizeof(func_args)); + + StartTCP(); + InitTcpReady(&ready); + + client_cb.method = wolfTLSv1_1_client_method; + server_cb.method = wolfTLSv1_2_server_method; + + server_args.signal = &ready; + server_args.callbacks = &server_cb; + client_args.signal = &ready; + client_args.callbacks = &client_cb; + + start_thread(test_server_nofail, &server_args, &serverThread); + wait_tcp_ready(&server_args); + test_client_nofail(&client_args); + join_thread(serverThread); + + FreeTcpReady(&ready); + + /* check that error code was stored */ + AssertIntNE((int)ERR_peek_last_error_line(NULL, NULL), 0); + ERR_peek_last_error_line(NULL, &line); + AssertIntNE(line, 0); + ERR_peek_last_error_line(&file, NULL); + AssertNotNull(file); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(DEBUG_WOLFSSL) */ +} + + +static void test_wolfSSL_X509_STORE_set_flags(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + + X509_STORE* store; + X509* x509; + + printf(testingFmt, "wolfSSL_ERR_peek_last_error_line()"); + AssertNotNull((store = wolfSSL_X509_STORE_new())); + AssertNotNull((x509 = + wolfSSL_X509_load_certificate_file(svrCert, SSL_FILETYPE_PEM))); + AssertIntEQ(X509_STORE_add_cert(store, x509), SSL_SUCCESS); + +#ifdef HAVE_CRL + AssertIntEQ(X509_STORE_set_flags(store, WOLFSSL_CRL_CHECKALL), SSL_SUCCESS); +#else + AssertIntEQ(X509_STORE_set_flags(store, WOLFSSL_CRL_CHECKALL), + NOT_COMPILED_IN); +#endif + + wolfSSL_X509_free(x509); + wolfSSL_X509_STORE_free(store); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ +} + + +static void test_wolfSSL_BN(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) + BIGNUM* a; + BIGNUM* b; + BIGNUM* c; + BIGNUM* d; + ASN1_INTEGER ai; + unsigned char value[1]; + + printf(testingFmt, "wolfSSL_BN()"); + + AssertNotNull(b = BN_new()); + AssertNotNull(c = BN_new()); + AssertNotNull(d = BN_new()); + + value[0] = 0x03; + + /* at the moment hard setting since no set function */ + ai.data[0] = 0x02; /* tag for ASN_INTEGER */ + ai.data[1] = 0x01; /* length of integer */ + ai.data[2] = value[0]; + + AssertNotNull(a = ASN1_INTEGER_to_BN(&ai, NULL)); + + value[0] = 0x02; + AssertNotNull(BN_bin2bn(value, sizeof(value), b)); + + value[0] = 0x05; + AssertNotNull(BN_bin2bn(value, sizeof(value), c)); + + /* a^b mod c = */ + AssertIntEQ(BN_mod_exp(d, NULL, b, c, NULL), SSL_FAILURE); + AssertIntEQ(BN_mod_exp(d, a, b, c, NULL), SSL_SUCCESS); + + /* check result 3^2 mod 5 */ + value[0] = 0; + AssertIntEQ(BN_bn2bin(d, value), SSL_SUCCESS); + AssertIntEQ((int)(value[0] & 0x04), 4); + + BN_free(a); + BN_free(b); + BN_free(c); + BN_clear_free(d); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_ASN) */ +} + + +static void test_wolfSSL_set_options(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + SSL* ssl; + SSL_CTX* ctx; + + printf(testingFmt, "wolfSSL_set_options()"); + + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + AssertTrue(SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)); + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + AssertTrue(SSL_set_options(ssl, SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1); + AssertTrue(SSL_get_options(ssl) == SSL_OP_NO_TLSv1); + + AssertIntGT((int)SSL_set_options(ssl, (SSL_OP_COOKIE_EXCHANGE | + SSL_OP_NO_SSLv2)), 0); + AssertTrue((SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE) & + SSL_OP_COOKIE_EXCHANGE) == SSL_OP_COOKIE_EXCHANGE); + AssertTrue((SSL_set_options(ssl, SSL_OP_NO_TLSv1_2) & + SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2); + AssertTrue((SSL_set_options(ssl, SSL_OP_NO_COMPRESSION) & + SSL_OP_NO_COMPRESSION) == SSL_OP_NO_COMPRESSION); + + SSL_free(ssl); + SSL_CTX_free(ctx); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ +} + + +static void test_wolfSSL_PEM_read_bio(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + byte buffer[5300]; + FILE *f; + int bytes; + X509* x509; + BIO* bio = NULL; + + printf(testingFmt, "wolfSSL_PEM_read_bio()"); + + AssertNotNull(f = fopen(cliCert, "rb")); + bytes = (int)fread(buffer, 1, sizeof(buffer), f); + fclose(f); + + AssertNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); + AssertNotNull(bio = BIO_new_mem_buf((void*)buffer, bytes)); + AssertNotNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); + AssertIntEQ((int)BIO_set_fd(bio, 0, BIO_NOCLOSE), 1); + + BIO_free(bio); + X509_free(x509); + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ +} + + +static void test_wolfSSL_BIO(void) +{ + #if defined(OPENSSL_EXTRA) + byte buffer[20]; + BIO* bio1; + BIO* bio2; + BIO* bio3; + char* bufPt; + int i; + + printf(testingFmt, "wolfSSL_BIO()"); + + for (i = 0; i < 20; i++) { + buffer[i] = i; + } + + /* Creating and testing type BIO_s_bio */ + AssertNotNull(bio1 = BIO_new(BIO_s_bio())); + AssertNotNull(bio2 = BIO_new(BIO_s_bio())); + AssertNotNull(bio3 = BIO_new(BIO_s_bio())); + + /* read/write before set up */ + AssertIntEQ(BIO_read(bio1, buffer, 2), WOLFSSL_BIO_UNSET); + AssertIntEQ(BIO_write(bio1, buffer, 2), WOLFSSL_BIO_UNSET); + + AssertIntEQ(BIO_set_write_buf_size(bio1, 20), SSL_SUCCESS); + AssertIntEQ(BIO_set_write_buf_size(bio2, 8), SSL_SUCCESS); + AssertIntEQ(BIO_make_bio_pair(bio1, bio2), SSL_SUCCESS); + + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 10), 10); + XMEMCPY(bufPt, buffer, 10); + AssertIntEQ(BIO_write(bio1, buffer + 10, 10), 10); + /* write buffer full */ + AssertIntEQ(BIO_write(bio1, buffer, 10), WOLFSSL_BIO_ERROR); + AssertIntEQ(BIO_flush(bio1), SSL_SUCCESS); + AssertIntEQ((int)BIO_ctrl_pending(bio1), 0); + + /* write the other direction with pair */ + AssertIntEQ((int)BIO_nwrite(bio2, &bufPt, 10), 8); + XMEMCPY(bufPt, buffer, 8); + AssertIntEQ(BIO_write(bio2, buffer, 10), WOLFSSL_BIO_ERROR); + + /* try read */ + AssertIntEQ((int)BIO_ctrl_pending(bio1), 8); + AssertIntEQ((int)BIO_ctrl_pending(bio2), 20); + + AssertIntEQ(BIO_nread(bio2, &bufPt, (int)BIO_ctrl_pending(bio2)), 20); + for (i = 0; i < 20; i++) { + AssertIntEQ((int)bufPt[i], i); + } + AssertIntEQ(BIO_nread(bio2, &bufPt, 1), WOLFSSL_BIO_ERROR); + AssertIntEQ(BIO_nread(bio1, &bufPt, (int)BIO_ctrl_pending(bio1)), 8); + for (i = 0; i < 8; i++) { + AssertIntEQ((int)bufPt[i], i); + } + AssertIntEQ(BIO_nread(bio1, &bufPt, 1), WOLFSSL_BIO_ERROR); + AssertIntEQ(BIO_ctrl_reset_read_request(bio1), 1); + + /* new pair */ + AssertIntEQ(BIO_make_bio_pair(bio1, bio3), SSL_FAILURE); + BIO_free(bio2); /* free bio2 and automaticly remove from pair */ + AssertIntEQ(BIO_make_bio_pair(bio1, bio3), SSL_SUCCESS); + AssertIntEQ((int)BIO_ctrl_pending(bio3), 0); + AssertIntEQ(BIO_nread(bio3, &bufPt, 10), WOLFSSL_BIO_ERROR); + + /* test wrap around... */ + AssertIntEQ(BIO_reset(bio1), 0); + AssertIntEQ(BIO_reset(bio3), 0); + + /* fill write buffer, read only small amount then write again */ + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20); + XMEMCPY(bufPt, buffer, 20); + AssertIntEQ(BIO_nread(bio3, &bufPt, 4), 4); + for (i = 0; i < 4; i++) { + AssertIntEQ(bufPt[i], i); + } + + /* try writing over read index */ + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 5), 4); + XMEMSET(bufPt, 0, 4); + AssertIntEQ((int)BIO_ctrl_pending(bio3), 20); + + /* read and write 0 bytes */ + AssertIntEQ(BIO_nread(bio3, &bufPt, 0), 0); + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 0), 0); + + /* should read only to end of write buffer then need to read again */ + AssertIntEQ(BIO_nread(bio3, &bufPt, 20), 16); + for (i = 0; i < 16; i++) { + AssertIntEQ(bufPt[i], buffer[4 + i]); + } + + AssertIntEQ(BIO_nread(bio3, NULL, 0), SSL_FAILURE); + AssertIntEQ(BIO_nread0(bio3, &bufPt), 4); + for (i = 0; i < 4; i++) { + AssertIntEQ(bufPt[i], 0); + } + + /* read index should not have advanced with nread0 */ + AssertIntEQ(BIO_nread(bio3, &bufPt, 5), 4); + for (i = 0; i < 4; i++) { + AssertIntEQ(bufPt[i], 0); + } + + /* write and fill up buffer checking reset of index state */ + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20); + XMEMCPY(bufPt, buffer, 20); + + /* test reset on data in bio1 write buffer */ + AssertIntEQ(BIO_reset(bio1), 0); + AssertIntEQ((int)BIO_ctrl_pending(bio3), 0); + AssertIntEQ(BIO_nread(bio3, &bufPt, 3), WOLFSSL_BIO_ERROR); + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20); + XMEMCPY(bufPt, buffer, 20); + AssertIntEQ(BIO_nread(bio3, &bufPt, 6), 6); + for (i = 0; i < 6; i++) { + AssertIntEQ(bufPt[i], i); + } + + /* test case of writing twice with offset read index */ + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 3), 3); + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), 3); /* try overwriting */ + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR); + AssertIntEQ(BIO_nread(bio3, &bufPt, 0), 0); + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR); + AssertIntEQ(BIO_nread(bio3, &bufPt, 1), 1); + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), 1); + AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR); + + BIO_free(bio1); + BIO_free(bio3); + + /* BIOs with file pointers */ + #if !defined(NO_FILESYSTEM) + { + XFILE f1; + XFILE f2; + BIO* f_bio1; + BIO* f_bio2; + unsigned char cert[300]; + char testFile[] = "tests/bio_write_test.txt"; + char msg[] = "bio_write_test.txt contains the first 300 bytes of certs/server-cert.pem\ncreated by tests/unit.test\n\n"; + + AssertNotNull(f_bio1 = BIO_new(BIO_s_file())); + AssertNotNull(f_bio2 = BIO_new(BIO_s_file())); + + AssertIntEQ((int)BIO_set_mem_eof_return(f_bio1, -1), 0); + AssertIntEQ((int)BIO_set_mem_eof_return(NULL, -1), 0); + + f1 = XFOPEN(svrCert, "rwb"); + AssertIntEQ((int)BIO_set_fp(f_bio1, f1, BIO_CLOSE), SSL_SUCCESS); + AssertIntEQ(BIO_write_filename(f_bio2, testFile), + SSL_SUCCESS); + + AssertIntEQ(BIO_read(f_bio1, cert, sizeof(cert)), sizeof(cert)); + AssertIntEQ(BIO_write(f_bio2, msg, sizeof(msg)), sizeof(msg)); + AssertIntEQ(BIO_write(f_bio2, cert, sizeof(cert)), sizeof(cert)); + + AssertIntEQ((int)BIO_get_fp(f_bio2, &f2), SSL_SUCCESS); + AssertIntEQ(BIO_reset(f_bio2), 0); + AssertIntEQ(BIO_seek(f_bio2, 4), 0); + + BIO_free(f_bio1); + BIO_free(f_bio2); + } + #endif /* !defined(NO_FILESYSTEM) */ + + printf(resultFmt, passed); + #endif +} + + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -2304,6 +3066,18 @@ void ApiTest(void) /* compatibility tests */ test_wolfSSL_DES(); + test_wolfSSL_certs(); + test_wolfSSL_private_keys(); + test_wolfSSL_PEM_PrivateKey(); + test_wolfSSL_tmp_dh(); + test_wolfSSL_ctrl(); + test_wolfSSL_CTX_add_extra_chain_cert(); + test_wolfSSL_ERR_peek_last_error_line(); + test_wolfSSL_X509_STORE_set_flags(); + test_wolfSSL_BN(); + test_wolfSSL_set_options(); + test_wolfSSL_PEM_read_bio(); + test_wolfSSL_BIO(); AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS); printf(" End API Tests\n"); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index c1f1f74e80..cdd8d30fb5 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1959,6 +1959,9 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, checkAESNI = 1; } if (haveAESNI) { + #ifdef WOLFSSL_AES_COUNTER + aes->left = 0; + #endif /* WOLFSSL_AES_COUNTER */ aes->use_aesni = 1; if (iv) XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); @@ -2842,6 +2845,33 @@ int wc_InitAes_h(Aes* aes, void* h) #endif /* AES-CBC block */ #endif /* HAVE_AES_CBC */ +#ifdef HAVE_AES_ECB +int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + if ((in == NULL) || (out == NULL) || (aes == NULL)) + return BAD_FUNC_ARG; + while (sz>0) { + wc_AesEncryptDirect(aes, out, in); + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + sz -= AES_BLOCK_SIZE; + } + return 0; +} +int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + if ((in == NULL) || (out == NULL) || (aes == NULL)) + return BAD_FUNC_ARG; + while (sz>0) { + wc_AesDecryptDirect(aes, out, in); + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + sz -= AES_BLOCK_SIZE; + } + return 0; +} +#endif + /* AES-CTR */ #ifdef WOLFSSL_AES_COUNTER diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5d7b4b0ae6..8d86f8e78e 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2553,6 +2553,10 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) #ifdef OPENSSL_EXTRA XMEMSET(&cert->issuerName, 0, sizeof(DecodedName)); XMEMSET(&cert->subjectName, 0, sizeof(DecodedName)); + cert->extCRLdistSet = 0; + cert->extCRLdistCrit = 0; + cert->extAuthInfoSet = 0; + cert->extAuthInfoCrit = 0; cert->extBasicConstSet = 0; cert->extBasicConstCrit = 0; cert->extSubjAltNameSet = 0; @@ -5199,11 +5203,19 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case CRL_DIST_OID: + #ifdef OPENSSL_EXTRA + cert->extCRLdistSet = 1; + cert->extCRLdistCrit = critical; + #endif if (DecodeCrlDist(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; case AUTH_INFO_OID: + #ifdef OPENSSL_EXTRA + cert->extAuthInfoSet = 1; + cert->extAuthInfoCrit = critical; + #endif if (DecodeAuthInfo(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; @@ -5727,6 +5739,8 @@ const char* BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----"; const char* END_CERT_REQ = "-----END CERTIFICATE REQUEST-----"; const char* BEGIN_DH_PARAM = "-----BEGIN DH PARAMETERS-----"; const char* END_DH_PARAM = "-----END DH PARAMETERS-----"; +const char* BEGIN_DSA_PARAM = "-----BEGIN DSA PARAMETERS-----"; +const char* END_DSA_PARAM = "-----END DSA PARAMETERS-----"; const char* BEGIN_X509_CRL = "-----BEGIN X509 CRL-----"; const char* END_X509_CRL = "-----END X509 CRL-----"; const char* BEGIN_RSA_PRIV = "-----BEGIN RSA PRIVATE KEY-----"; @@ -5855,6 +5869,20 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, headerLen = (int)XSTRLEN(header); footerLen = (int)XSTRLEN(footer); + /* if null output and 0 size passed in then return size needed */ + if (!output && outSz == 0) { +#ifdef WOLFSSL_SMALL_STACK + XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + outLen = 0; + if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen)) + != LENGTH_ONLY_E) { + return err; + } + return headerLen + footerLen + outLen; + } + if (!der || !output) { #ifdef WOLFSSL_SMALL_STACK XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 4fc5101547..005b03f339 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -76,6 +76,10 @@ int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) return Des_EcbEncrypt(des, out, in, sz); } +int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz) +{ + return Des3_EcbEncrypt(des, out, in, sz); +} #endif /* WOLFSSL_DES_ECB */ @@ -1617,6 +1621,10 @@ int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) { word32 blocks = sz / DES_BLOCK_SIZE; + if (des == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + while (blocks--) { DesProcessBlock(des, in, out); @@ -1626,6 +1634,25 @@ int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) return 0; } +int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / DES_BLOCK_SIZE; + /* printf("wc_Des3_EcbEncrypt(%016x, %016x, %d)\n", + *(unsigned long *)in, *(unsigned long *)out, sz) ; */ + + if (des == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + while (blocks--) { + Des3ProcessBlock(des, in, out); + + out += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + } + return 0; +} + #endif /* WOLFSSL_DES_ECB */ #endif /* End wolfCrypt software implementation */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c new file mode 100644 index 0000000000..fb9e56edc0 --- /dev/null +++ b/wolfcrypt/src/evp.c @@ -0,0 +1,535 @@ +/* evp.c + * + * Copyright (C) 2006-2016 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 + */ + +static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher); + +WOLFSSL_API int wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + unsigned char* key, unsigned char* iv) +{ + return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 1); +} + +WOLFSSL_API int wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + unsigned char* key, unsigned char* iv) +{ + (void) impl; + return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 1); +} + +WOLFSSL_API int wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + unsigned char* key, unsigned char* iv) +{ + WOLFSSL_ENTER("wolfSSL_EVP_CipherInit"); + return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 0); +} + +WOLFSSL_API int wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + unsigned char* key, unsigned char* iv) +{ + (void) impl; + WOLFSSL_ENTER("wolfSSL_EVP_DecryptInit"); + return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 0); +} + +WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void) +{ + WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (ctx){ + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_new"); + wolfSSL_EVP_CIPHER_CTX_init(ctx); + } + return ctx; +} + +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx) +{ + if (ctx) { + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_free"); + wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); + XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +} + +WOLFSSL_API unsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx) +{ + if (ctx == NULL) return 0; + return ctx->flags & WOLFSSL_EVP_CIPH_MODE; +} + +WOLFSSL_API int wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl) +{ + if (ctx && ctx->enc){ + WOLFSSL_ENTER("wolfSSL_EVP_EncryptFinal"); + return wolfSSL_EVP_CipherFinal(ctx, out, outl); + } + else + return 0; +} + + +WOLFSSL_API int wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + unsigned char* key, unsigned char* iv, + int enc) +{ + (void)impl; + return wolfSSL_EVP_CipherInit(ctx, type, key, iv, enc); +} + +WOLFSSL_API int wolfSSL_EVP_EncryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl) +{ + if (ctx && ctx->enc){ + WOLFSSL_ENTER("wolfSSL_EVP_EncryptFinal_ex"); + return wolfSSL_EVP_CipherFinal(ctx, out, outl); + } + else + return 0; +} + +WOLFSSL_API int wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl) +{ + if (ctx && ctx->enc) + return 0; + else{ + WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal"); + return wolfSSL_EVP_CipherFinal(ctx, out, outl); + } +} + +WOLFSSL_API int wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl) +{ + if (ctx && ctx->enc) + return 0; + else{ + WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal_ex"); + return wolfSSL_EVP_CipherFinal(ctx, out, outl); + } +} + + +WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx, + const WOLFSSL_EVP_MD* type, + WOLFSSL_ENGINE *impl) +{ + (void) impl; + WOLFSSL_ENTER("wolfSSL_EVP_DigestInit_ex"); + return wolfSSL_EVP_DigestInit(ctx, type); +} + +#ifdef DEBUG_WOLFSSL_EVP +#define PRINT_BUF(b, sz) { int i; for(i=0; i<(sz); i++){printf("%02x(%c),", (b)[i], (b)[i]); if((i+1)%8==0)printf("\n");}} +#else +#define PRINT_BUF(b, sz) +#endif + +static int fillBuff(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int sz) +{ + int fill; + + if (sz > 0) { + if ((sz+ctx->bufUsed) > ctx->block_size) { + fill = ctx->block_size - ctx->bufUsed; + } else { + fill = sz; + } + XMEMCPY(&(ctx->buf[ctx->bufUsed]), in, fill); + ctx->bufUsed += fill; + return fill; + } else return 0; +} + +static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, int inl) +{ + switch (ctx->cipherType) { + #if !defined(NO_AES) && defined(HAVE_AES_CBC) + case AES_128_CBC_TYPE: + case AES_192_CBC_TYPE: + case AES_256_CBC_TYPE: + if (ctx->enc) + wc_AesCbcEncrypt(&ctx->cipher.aes, out, in, inl); + else + wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl); + break; + #endif + #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + case AES_128_CTR_TYPE: + case AES_192_CTR_TYPE: + case AES_256_CTR_TYPE: + if (ctx->enc) + wc_AesCtrEncrypt(&ctx->cipher.aes, out, in, inl); + else + wc_AesCtrEncrypt(&ctx->cipher.aes, out, in, inl); + break; + #endif + #if !defined(NO_AES) && defined(HAVE_AES_ECB) + case AES_128_ECB_TYPE: + case AES_192_ECB_TYPE: + case AES_256_ECB_TYPE: + if (ctx->enc) + wc_AesEcbEncrypt(&ctx->cipher.aes, out, in, inl); + else + wc_AesEcbDecrypt(&ctx->cipher.aes, out, in, inl); + break; + #endif + #ifndef NO_DES3 + case DES_CBC_TYPE: + if (ctx->enc) + wc_Des_CbcEncrypt(&ctx->cipher.des, out, in, inl); + else + wc_Des_CbcDecrypt(&ctx->cipher.des, out, in, inl); + break; + case DES_EDE3_CBC_TYPE: + if (ctx->enc) + wc_Des3_CbcEncrypt(&ctx->cipher.des3, out, in, inl); + else + wc_Des3_CbcDecrypt(&ctx->cipher.des3, out, in, inl); + break; + #if defined(WOLFSSL_DES_ECB) + case DES_ECB_TYPE: + wc_Des_EcbEncrypt(&ctx->cipher.des, out, in, inl); + break; + case DES_EDE3_ECB_TYPE: + if (ctx->enc) + wc_Des3_EcbEncrypt(&ctx->cipher.des3, out, in, inl); + else + wc_Des3_EcbEncrypt(&ctx->cipher.des3, out, in, inl); + break; + #endif + #endif + default: + return 0; + } + (void)in; + (void)inl; + (void)out; + return 1; +} + +WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int blocks; + int fill; + + if (ctx == NULL) return BAD_FUNC_ARG; + WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate"); + *outl = 0; + if (ctx->bufUsed > 0) { /* concatinate them if there is anything */ + fill = fillBuff(ctx, in, inl); + inl -= fill; + in += fill; + } + if((ctx->enc == 0)&& (ctx->lastUsed == 1)){ + PRINT_BUF(ctx->lastBlock, ctx->block_size); + XMEMCPY(out, ctx->lastBlock, ctx->block_size); + *outl+= ctx->block_size; + out += ctx->block_size; + } + if ((ctx->bufUsed == ctx->block_size) || (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING)){ + /* the buff is full, flash out */ + PRINT_BUF(ctx->buf, ctx->block_size); + if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) + return 0; + PRINT_BUF(out, ctx->block_size); + if(ctx->enc == 0){ + ctx->lastUsed = 1; + XMEMCPY(ctx->lastBlock, out, ctx->block_size); + } else { + *outl+= ctx->block_size; + out += ctx->block_size; + } + ctx->bufUsed = 0; + } + + blocks = inl / ctx->block_size; + if (blocks > 0) { + /* process blocks */ + if (evpCipherBlock(ctx, out, ctx->buf, blocks) == 0) + return 0; + PRINT_BUF(ctx->buf, ctx->block_size); + PRINT_BUF(out, ctx->block_size); + inl -= ctx->block_size * blocks; + in += ctx->block_size * blocks; + if(ctx->enc == 0){ + ctx->lastUsed = 1; + XMEMCPY(ctx->lastBlock, &out[ctx->block_size * (blocks-1)], ctx->block_size); + *outl+= ctx->block_size * (blocks-1); + } else { + *outl+= ctx->block_size * blocks; + } + } + if (inl > 0) { + /* put fraction into buff */ + fillBuff(ctx, in, inl); + /* no increase of outl */ + } + + (void)out; /* silence warning in case not read */ + + return 1; +} + +static void padBlock(WOLFSSL_EVP_CIPHER_CTX *ctx) +{ + int i; + for (i = ctx->bufUsed; i < ctx->block_size; i++) + ctx->buf[i] = (byte)(ctx->block_size - ctx->bufUsed); +} + +static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff) +{ + int i; + int n; + n = buff[ctx->block_size-1]; + + if (n > ctx->block_size) return FALSE; + for (i = 0; i < n; i++){ + if (buff[ctx->block_size-i-1] != n) + return FALSE; + } + return ctx->block_size - n; +} + +WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl) +{ + int fl ; + if (ctx == NULL) return BAD_FUNC_ARG; + WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal"); + if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) { + *outl = 0; + return 1; + } + if (ctx->enc) { + if (ctx->bufUsed > 0) { + padBlock(ctx); + PRINT_BUF(ctx->buf, ctx->block_size); + if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) + return 0; + PRINT_BUF(out, ctx->block_size); + *outl = ctx->block_size; + } + } else { + if (ctx->lastUsed){ + PRINT_BUF(ctx->lastBlock, ctx->block_size); + if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) { + XMEMCPY(out, ctx->lastBlock, fl); + *outl = fl; + } else return 0; + } + } + return 1; +} + +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx) +{ + if (ctx == NULL) return BAD_FUNC_ARG; + switch (ctx->cipherType) { + +#if !defined(NO_AES) && defined(HAVE_AES_CBC) + case AES_128_CBC_TYPE: + case AES_192_CBC_TYPE: + case AES_256_CBC_TYPE: +#endif +#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + case AES_128_CTR_TYPE: + case AES_192_CTR_TYPE: + case AES_256_CTR_TYPE: +#endif +#if !defined(NO_AES) + case AES_128_ECB_TYPE: + case AES_192_ECB_TYPE: + case AES_256_ECB_TYPE: +#endif +#ifndef NO_DES3 + case DES_CBC_TYPE: + case DES_ECB_TYPE: + case DES_EDE3_CBC_TYPE: + case DES_EDE3_ECB_TYPE: +#endif + return ctx->block_size; + default: + return 0; + } +} + +static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) +{ + if (cipher == NULL) return 0; /* dummy for #ifdef */ + #ifndef NO_DES3 + else if (XSTRNCMP(cipher, EVP_DES_CBC, EVP_DES_SIZE) == 0) + return DES_CBC_TYPE; + else if (XSTRNCMP(cipher, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) + return DES_EDE3_CBC_TYPE; + #if !defined(NO_DES3) + else if (XSTRNCMP(cipher, EVP_DES_ECB, EVP_DES_SIZE) == 0) + return DES_ECB_TYPE; + else if (XSTRNCMP(cipher, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0) + return DES_EDE3_ECB_TYPE; + #endif /* NO_DES3 && HAVE_AES_ECB */ + #endif + + #if !defined(NO_AES) && defined(HAVE_AES_CBC) + else if (XSTRNCMP(cipher, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) + return AES_128_CBC_TYPE; + else if (XSTRNCMP(cipher, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) + return AES_192_CBC_TYPE; + else if (XSTRNCMP(cipher, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) + return AES_256_CBC_TYPE; + #endif /* !NO_AES && HAVE_AES_CBC */ + #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + else if (XSTRNCMP(cipher, EVP_AES_128_CTR, EVP_AES_SIZE) == 0) + return AES_128_CTR_TYPE; + else if (XSTRNCMP(cipher, EVP_AES_192_CTR, EVP_AES_SIZE) == 0) + return AES_192_CTR_TYPE; + else if (XSTRNCMP(cipher, EVP_AES_256_CTR, EVP_AES_SIZE) == 0) + return AES_256_CTR_TYPE; + #endif /* !NO_AES && HAVE_AES_CBC */ + #if !defined(NO_AES) && defined(HAVE_AES_ECB) + else if (XSTRNCMP(cipher, EVP_AES_128_ECB, EVP_AES_SIZE) == 0) + return AES_128_ECB_TYPE; + else if (XSTRNCMP(cipher, EVP_AES_192_ECB, EVP_AES_SIZE) == 0) + return AES_192_ECB_TYPE; + else if (XSTRNCMP(cipher, EVP_AES_256_ECB, EVP_AES_SIZE) == 0) + return AES_256_ECB_TYPE; + #endif /* !NO_AES && HAVE_AES_CBC */ + else return 0; +} + +WOLFSSL_API int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) +{ + if (cipher == NULL) return BAD_FUNC_ARG; + switch (cipherType(cipher)) { + #if !defined(NO_AES) && defined(HAVE_AES_CBC) + case AES_128_CBC_TYPE: + case AES_192_CBC_TYPE: + case AES_256_CBC_TYPE: + return AES_BLOCK_SIZE; + #endif + #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + case AES_128_CTR_TYPE: + case AES_192_CTR_TYPE: + case AES_256_CTR_TYPE: + return AES_BLOCK_SIZE; + #endif + #if !defined(NO_AES) && defined(HAVE_AES_ECB) + case AES_128_ECB_TYPE: + case AES_192_ECB_TYPE: + case AES_256_ECB_TYPE: + return AES_BLOCK_SIZE; + #endif + #ifndef NO_DES3 + case DES_CBC_TYPE: return 8; + case DES_EDE3_CBC_TYPE: return 8; + case DES_ECB_TYPE: return 8; + case DES_EDE3_ECB_TYPE: return 8; + #endif + default: + return 0; + } +} + +unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) +{ + switch (cipherType(cipher)) { + #if !defined(NO_AES) && defined(HAVE_AES_CBC) + case AES_128_CBC_TYPE: + case AES_192_CBC_TYPE: + case AES_256_CBC_TYPE: + return WOLFSSL_EVP_CIPH_CBC_MODE ; + #endif + #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + case AES_128_CTR_TYPE: + case AES_192_CTR_TYPE: + case AES_256_CTR_TYPE: + return WOLFSSL_EVP_CIPH_CTR_MODE ; + #endif + #if !defined(NO_AES) + case AES_128_ECB_TYPE: + case AES_192_ECB_TYPE: + case AES_256_ECB_TYPE: + return WOLFSSL_EVP_CIPH_ECB_MODE ; + #endif + #ifndef NO_DES3 + case DES_CBC_TYPE: + case DES_EDE3_CBC_TYPE: + return WOLFSSL_EVP_CIPH_CBC_MODE ; + case DES_ECB_TYPE: + case DES_EDE3_ECB_TYPE: + return WOLFSSL_EVP_CIPH_ECB_MODE ; + #endif + default: + return 0; + } +} + +WOLFSSL_API unsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) +{ + if (cipher == NULL) return 0; + return WOLFSSL_CIPHER_mode(cipher); +} + +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags) +{ + if (ctx != NULL) { + ctx->flags = flags; + } +} + +WOLFSSL_API unsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher) +{ + if (cipher == NULL) return 0; + return WOLFSSL_CIPHER_mode(cipher); +} + +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *ctx, int padding) +{ + if (ctx == NULL) return BAD_FUNC_ARG; + if (padding) { + ctx->flags &= ~WOLFSSL_EVP_CIPH_NO_PADDING; + } + else { + ctx->flags |= WOLFSSL_EVP_CIPH_NO_PADDING; + } + return 1; +} + +WOLFSSL_API int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest) +{ + (void)digest; + /* nothing to do */ + return 0; +} diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 714d5d4343..81aa797db3 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -1,7 +1,9 @@ # vim:ft=automake # All paths should be given relative to the root +EXTRA_DIST += src/bio.c EXTRA_DIST += wolfcrypt/src/misc.c +EXTRA_DIST += wolfcrypt/src/evp.c EXTRA_DIST += wolfcrypt/src/asm.c EXTRA_DIST += wolfcrypt/src/aes_asm.asm diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 9a4fac5f43..9307413b51 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -43,6 +43,11 @@ #ifdef DEBUG_WOLFSSL + #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + volatile char wc_last_error_file[80]; + volatile unsigned long wc_last_error_line; + volatile unsigned long wc_last_error; + #endif /* Set these to default values initially. */ static wolfSSL_Logging_cb log_function = 0; @@ -198,11 +203,35 @@ void WOLFSSL_LEAVE(const char* msg, int ret) } +/* + * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is + * mapped to new funtion WOLFSSL_ERROR_LINE which gets the line # and function + * name where WOLFSSL_ERROR is called at. + */ +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) +void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line, + const char* file, void* usrCtx) +#else void WOLFSSL_ERROR(int error) +#endif { if (loggingEnabled) { char buffer[80]; - sprintf(buffer, "wolfSSL error occurred, error = %d", error); + #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + (void)usrCtx; /* a user ctx for future flexibility */ + (void)func; + if (error < 0) error = error - (2*error); /* get absolute value */ + wc_last_error = (unsigned long)error; + wc_last_error_line = (unsigned long)line; + XMEMSET((char*)wc_last_error_file, 0, sizeof(file)); + if (XSTRLEN(file) < sizeof(file)) { + XSTRNCPY((char*)wc_last_error_file, file, XSTRLEN(file)); + } + sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s", + error, line, file); + #else + sprintf(buffer, "wolfSSL error occurred, error = %d", error); + #endif wolfssl_log(ERROR_LOG , buffer); } } diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 669298cb6c..434248fd7a 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -43,6 +43,10 @@ #include #endif +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + #include +#endif + #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ #pragma warning(disable: 4996) @@ -89,6 +93,10 @@ int wolfCrypt_Init(void) WOLFSSL_MSG("Using ARM hardware acceleration"); #endif + #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + wolfSSL_EVP_init(); + #endif + initRefCount = 1; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 8f79648906..d7c6fb4ce5 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -111,6 +111,7 @@ #include #include #include + #include #include #endif @@ -2081,7 +2082,7 @@ int hc128_test(void) (word32)test_hc128[i].outLen) != 0) { return -110; } - if (wc_Hc128_Process(&dec, plain, cipher, + if (wc_Hc128_Process(&dec, plain, cipher, (word32)test_hc128[i].outLen) != 0) { return -115; } @@ -4860,7 +4861,7 @@ int rsa_test(void) !defined(HAVE_FIPS) #ifndef NO_SHA XMEMSET(plain, 0, sizeof(plain)); - + do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_RsaAsyncWait(ret, &key); @@ -6879,7 +6880,7 @@ int openssl_test(void) #ifndef NO_AES - { /* evp_cipher test */ + { /* evp_cipher test: EVP_aes_128_cbc */ EVP_CIPHER_CTX ctx; @@ -6922,13 +6923,437 @@ int openssl_test(void) return -86; + } /* end evp_cipher test: EVP_aes_128_cbc*/ + +#ifdef HAVE_AES_ECB + { /* evp_cipher test: EVP_aes_128_ecb*/ + EVP_CIPHER_CTX ctx; + const byte msg[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + const byte verify[] = + { + 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, + 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 + }; + + const byte key[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + + byte cipher[AES_BLOCK_SIZE * 4]; + byte plain [AES_BLOCK_SIZE * 4]; + + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 1) == 0) + return -181; + + if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) + return -182; + + if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) + return -183; + + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 0) == 0) + return -184; + + if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) + return -185; + + if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) + return -186; + } /* end evp_cipher test */ +#endif #endif /* NO_AES */ +#define OPENSSL_TEST_ERROR (-10000) + + +#ifndef NO_AES +#ifdef WOLFSSL_AES_DIRECT + /* enable HAVE_AES_DECRYPT for AES_encrypt/decrypt */ +{ + + /* Test: AES_encrypt/decrypt/set Key */ + AES_KEY enc; +#ifdef HAVE_AES_DECRYPT + AES_KEY dec; +#endif + + const byte msg[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + const byte verify[] = + { + 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, + 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 + }; + + const byte key[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + byte plain[sizeof(msg)]; + byte cipher[sizeof(msg)]; + + printf("openSSL extra test\n") ; + + + AES_set_encrypt_key(key, sizeof(key)*8, &enc); + AES_set_decrypt_key(key, sizeof(key)*8, &dec); + + AES_encrypt(msg, cipher, &enc); + +#ifdef HAVE_AES_DECRYPT + AES_decrypt(cipher, plain, &dec); + if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) + return OPENSSL_TEST_ERROR-60; +#endif /* HAVE_AES_DECRYPT */ + + if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) + return OPENSSL_TEST_ERROR-61; +} + +#endif + +/* EVP_Cipher with EVP_aes_xxx_ctr() */ +#ifdef WOLFSSL_AES_COUNTER +{ + const byte ctrKey[] = + { + 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c + }; + + const byte ctrIv[] = + { + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff + }; + + + const byte ctrPlain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 + }; + + const byte ctrCipher[] = + { + 0x87,0x4d,0x61,0x91,0xb6,0x20,0xe3,0x26, + 0x1b,0xef,0x68,0x64,0x99,0x0d,0xb6,0xce, + 0x98,0x06,0xf6,0x6b,0x79,0x70,0xfd,0xff, + 0x86,0x17,0x18,0x7b,0xb9,0xff,0xfd,0xff, + 0x5a,0xe4,0xdf,0x3e,0xdb,0xd5,0xd3,0x5e, + 0x5b,0x4f,0x09,0x02,0x0d,0xb0,0x3e,0xab, + 0x1e,0x03,0x1d,0xda,0x2f,0xbe,0x03,0xd1, + 0x79,0x21,0x70,0xa0,0xf3,0x00,0x9c,0xee + }; + + byte plainBuff [64]; + byte cipherBuff[64]; + + const byte oddCipher[] = + { + 0xb9,0xd7,0xcb,0x08,0xb0,0xe1,0x7b,0xa0, + 0xc2 + }; + + + /* test vector from "Recommendation for Block Cipher Modes of Operation" + * NIST Special Publication 800-38A */ + const byte ctr192Key[] = + { + 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, + 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, + 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b + }; + + const byte ctr192Iv[] = + { + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff + }; + + + const byte ctr192Plain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + const byte ctr192Cipher[] = + { + 0x1a,0xbc,0x93,0x24,0x17,0x52,0x1c,0xa2, + 0x4f,0x2b,0x04,0x59,0xfe,0x7e,0x6e,0x0b + }; + + /* test vector from "Recommendation for Block Cipher Modes of Operation" + * NIST Special Publication 800-38A */ + const byte ctr256Key[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + const byte ctr256Iv[] = + { + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff + }; + + + const byte ctr256Plain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + const byte ctr256Cipher[] = + { + 0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5, + 0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28 + }; + + EVP_CIPHER_CTX en; + EVP_CIPHER_CTX de; + EVP_CIPHER_CTX *p_en; + EVP_CIPHER_CTX *p_de; + + EVP_CIPHER_CTX_init(&en); + if (EVP_CipherInit(&en, EVP_aes_128_ctr(), + (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) + return -3300; + if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) + return -3301; + EVP_CIPHER_CTX_init(&de); + if (EVP_CipherInit(&de, EVP_aes_128_ctr(), + (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) + return -3302; + + if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) + return -3303; + + if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) + return -3304; + if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) + return -3305; + + p_en = wolfSSL_EVP_CIPHER_CTX_new(); + if(p_en == NULL)return -3390; + p_de = wolfSSL_EVP_CIPHER_CTX_new(); + if(p_de == NULL)return -3391; + + if (EVP_CipherInit(p_en, EVP_aes_128_ctr(), + (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) + return -3392; + if (EVP_Cipher(p_en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) + return -3393; + if (EVP_CipherInit(p_de, EVP_aes_128_ctr(), + (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) + return -3394; + + if (EVP_Cipher(p_de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) + return -3395; + + wolfSSL_EVP_CIPHER_CTX_free(p_en); + wolfSSL_EVP_CIPHER_CTX_free(p_de); + + if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) + return -3396; + if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) + return -3397; + + EVP_CIPHER_CTX_init(&en); + if (EVP_CipherInit(&en, EVP_aes_128_ctr(), + (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) + return -3306; + if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) + return -3307; + + EVP_CIPHER_CTX_init(&de); + if (EVP_CipherInit(&de, EVP_aes_128_ctr(), + (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) + return -3308; + + if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) + return -3309; + + if (XMEMCMP(plainBuff, ctrPlain, 9)) + return -3310; + if (XMEMCMP(cipherBuff, ctrCipher, 9)) + return -3311; + + if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) + return -3312; + if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) + return -3313; + + if (XMEMCMP(plainBuff, ctrPlain, 9)) + return -3314; + if (XMEMCMP(cipherBuff, oddCipher, 9)) + return -3315; + + EVP_CIPHER_CTX_init(&en); + if (EVP_CipherInit(&en, EVP_aes_192_ctr(), + (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) + return -3316; + if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr192Plain, AES_BLOCK_SIZE) == 0) + return -3317; + EVP_CIPHER_CTX_init(&de); + if (EVP_CipherInit(&de, EVP_aes_192_ctr(), + (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) + return -3318; + + XMEMSET(plainBuff, 0, sizeof(plainBuff)); + if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) + return -3319; + + if (XMEMCMP(plainBuff, ctr192Plain, sizeof(ctr192Plain))) + return -3320; + if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) + return -3321; + + EVP_CIPHER_CTX_init(&en); + if (EVP_CipherInit(&en, EVP_aes_256_ctr(), + (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) + return -3322; + if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr256Plain, AES_BLOCK_SIZE) == 0) + return -3323; + EVP_CIPHER_CTX_init(&de); + if (EVP_CipherInit(&de, EVP_aes_256_ctr(), + (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) + return -3324; + + XMEMSET(plainBuff, 0, sizeof(plainBuff)); + if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) + return -3325; + + if (XMEMCMP(plainBuff, ctr256Plain, sizeof(ctr256Plain))) + return -3326; + if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) + return -3327; +} +#endif /* HAVE_AES_COUNTER */ + +{ + /* EVP_CipherUpdate test */ + + + const byte cbcPlain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 + }; + + byte key[] = "0123456789abcdef "; /* align */ + byte iv[] = "1234567890abcdef "; /* align */ + + byte cipher[AES_BLOCK_SIZE * 4]; + byte plain [AES_BLOCK_SIZE * 4]; + EVP_CIPHER_CTX en; + EVP_CIPHER_CTX de; + int outlen ; + int total = 0; + + EVP_CIPHER_CTX_init(&en); + if (EVP_CipherInit(&en, EVP_aes_128_cbc(), + (unsigned char*)key, (unsigned char*)iv, 1) == 0) + return -3401; + if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) + return -3402; + if(outlen != 0) + return -3403; + total += outlen; + + if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) + return -3404; + if(outlen != 16) + return -3405; + total += outlen; + + if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) + return -3406; + if(outlen != 16) + return -3407; + total += outlen; + if(total != 32) + return 3408; + + total = 0; + EVP_CIPHER_CTX_init(&de); + if (EVP_CipherInit(&de, EVP_aes_128_cbc(), + (unsigned char*)key, (unsigned char*)iv, 0) == 0) + return -3420; + + if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) + return -3421; + if(outlen != 0) + return -3422; + total += outlen; + + if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) + return -3423; + if(outlen != 0) + total += outlen; + + if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) + return -3423; + if(outlen != 16) + return -3424; + total += outlen; + + if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) + return -3425; + if(outlen != 2) + return -3426; + total += outlen; + + if(total != 18) + return 3427; + + if (XMEMCMP(plain, cbcPlain, 18)) + return -3428; + + } +#endif /* ifndef NO_AES */ + return 0; } + #endif /* OPENSSL_EXTRA */ @@ -7094,6 +7519,7 @@ int pbkdf2_test(void) return -102; return 0; + } @@ -8838,7 +9264,7 @@ int ed25519_test(void) #if defined(WOLFSSL_CMAC) && !defined(NO_AES) - + typedef struct CMAC_Test_Case { int type; int partial; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 759abe174f..19195f6756 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1242,7 +1242,9 @@ enum BIO_TYPE { BIO_BUFFER = 1, BIO_SOCKET = 2, BIO_SSL = 3, - BIO_MEMORY = 4 + BIO_MEMORY = 4, + BIO_BIO = 5, + BIO_FILE = 6 }; @@ -1254,15 +1256,24 @@ struct WOLFSSL_BIO_METHOD { /* wolfSSL BIO type */ struct WOLFSSL_BIO { - byte type; /* method type */ - byte close; /* close flag */ - byte eof; /* eof flag */ WOLFSSL* ssl; /* possible associated ssl */ - byte* mem; /* memory buffer */ - int memLen; /* memory buffer length */ - int fd; /* possible file descriptor */ +#ifndef NO_FILESYSTEM + XFILE file; +#endif WOLFSSL_BIO* prev; /* previous in chain */ WOLFSSL_BIO* next; /* next in chain */ + WOLFSSL_BIO* pair; /* BIO paired with */ + void* heap; /* user heap hint */ + byte* mem; /* memory buffer */ + int wrSz; /* write buffer size (mem) */ + int wrIdx; /* current index for write buffer */ + int rdIdx; /* current read index */ + int readRq; /* read request */ + int memLen; /* memory buffer length */ + int fd; /* possible file descriptor */ + int eof; /* eof flag */ + byte type; /* method type */ + byte close; /* close flag */ }; @@ -1994,6 +2005,9 @@ struct WOLFSSL_CTX { #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) pem_password_cb passwd_cb; void* userdata; + WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */ + byte readAhead; + void* userPRFArg; /* passed to prf callback */ #endif /* OPENSSL_EXTRA */ #ifdef HAVE_STUNNEL void* ex_data[MAX_EX_DATA]; @@ -2371,6 +2385,9 @@ typedef struct Options { wc_psk_server_callback server_psk_cb; word16 havePSK:1; /* psk key set by user */ #endif /* NO_PSK */ +#ifdef OPENSSL_EXTRA + unsigned long mask; /* store SSL_OP_ flags */ +#endif /* on/off or small bit flags, optimize layout */ word16 sendVerify:2; /* false = 0, true = 1, sendBlank = 2 */ @@ -2495,6 +2512,7 @@ struct WOLFSSL_STACK { union { WOLFSSL_X509* x509; WOLFSSL_BIO* bio; + WOLFSSL_ASN1_OBJECT* obj; } data; WOLFSSL_STACK* next; }; @@ -2558,9 +2576,21 @@ struct WOLFSSL_X509 { void* heap; /* heap hint */ byte dynamicMemory; /* dynamic memory flag */ byte isCa; +#ifdef WOLFSSL_CERT_EXT + char certPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ]; + int certPoliciesNb; +#endif /* WOLFSSL_CERT_EXT */ #ifdef OPENSSL_EXTRA word32 pathLength; word16 keyUsage; + byte CRLdistSet; + byte CRLdistCrit; + byte* CRLInfo; + int CRLInfoSz; + byte authInfoSet; + byte authInfoCrit; + byte* authInfo; + int authInfoSz; byte basicConstSet; byte basicConstCrit; byte basicConstPlSet; @@ -2576,6 +2606,10 @@ struct WOLFSSL_X509 { word32 subjKeyIdSz; byte keyUsageSet; byte keyUsageCrit; + byte extKeyUsageCrit; + byte* extKeyUsageSrc; + word32 extKeyUsageSz; + word32 extKeyUsageCount; #endif /* OPENSSL_EXTRA */ }; @@ -2725,6 +2759,11 @@ struct WOLFSSL { #ifdef OPENSSL_EXTRA WOLFSSL_BIO* biord; /* socket bio read to free/close */ WOLFSSL_BIO* biowr; /* socket bio write to free/close */ + unsigned long peerVerifyRet; + byte readAhead; +#ifdef HAVE_PK_CALLBACKS + void* loggingCtx; /* logging callback argument */ +#endif #endif #ifndef NO_RSA RsaKey* peerRsaKey; diff --git a/wolfssl/openssl/aes.h b/wolfssl/openssl/aes.h new file mode 100644 index 0000000000..418914808a --- /dev/null +++ b/wolfssl/openssl/aes.h @@ -0,0 +1,73 @@ +/* aes.h + * + * Copyright (C) 2006-2016 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 + */ + + + +/* aes.h defines mini des openssl compatibility layer + * + */ + + +#ifndef WOLFSSL_AES_H_ +#define WOLFSSL_AES_H_ + +#include + +#ifndef NO_AES +#ifdef WOLFSSL_AES_DIRECT + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef Aes AES_KEY; + +WOLFSSL_API void wolfSSL_AES_set_encrypt_key + (const unsigned char *, const int bits, AES_KEY *); +WOLFSSL_API void wolfSSL_AES_set_decrypt_key + (const unsigned char *, const int bits, AES_KEY *); +WOLFSSL_API void wolfSSL_AES_encrypt + (const unsigned char* input, unsigned char* output, AES_KEY *); +WOLFSSL_API void wolfSSL_AES_decrypt + (const unsigned char* input, unsigned char* output, AES_KEY *); + +#define AES_set_encrypt_key wolfSSL_AES_set_encrypt_key +#define AES_set_decrypt_key wolfSSL_AES_set_decrypt_key +#define AES_encrypt wolfSSL_AES_encrypt +#define AES_decrypt wolfSSL_AES_decrypt + +#define wolfSSL_AES_set_encrypt_key(key, bits, aes) \ + wc_AesSetKey(aes, key, ((bits)/8), NULL, AES_ENCRYPTION) +#define wolfSSL_AES_set_decrypt_key(key, bits, aes) \ + wc_AesSetKey(aes, key, ((bits)/8), NULL, AES_DECRYPTION) + +#define wolfSSL_AES_encrypt(in, out, aes) wc_AesEncryptDirect(aes, out, in) +#define wolfSSL_AES_decrypt(in, out, aes) wc_AesDecryptDirect(aes, out, in) + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_AES_DIRECT */ +#endif /* NO_AES */ + +#endif /* WOLFSSL_DES_H_ */ diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index c56a3cfcad..ba5648a883 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -35,7 +35,8 @@ WOLFSSL_API int wolfSSL_BN_sub(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_mod(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, const WOLFSSL_BN_CTX*); - +WOLFSSL_API int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, + const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx); WOLFSSL_API const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void); @@ -109,6 +110,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_bin2bn wolfSSL_BN_bin2bn #define BN_mod wolfSSL_BN_mod +#define BN_mod_exp wolfSSL_BN_mod_exp #define BN_sub wolfSSL_BN_sub #define BN_value_one wolfSSL_BN_value_one @@ -148,4 +150,3 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #endif /* WOLFSSL__H_ */ - diff --git a/wolfssl/openssl/des.h b/wolfssl/openssl/des.h index 0425511963..d154b72be1 100644 --- a/wolfssl/openssl/des.h +++ b/wolfssl/openssl/des.h @@ -53,9 +53,9 @@ enum { }; -WOLFSSL_API void wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, +WOLFSSL_API int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, WOLFSSL_DES_key_schedule* key); -WOLFSSL_API void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, +WOLFSSL_API int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, WOLFSSL_DES_key_schedule* key); WOLFSSL_API void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock*, WOLFSSL_DES_key_schedule*); diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index e13d1fa4f7..086e82c4cb 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -21,7 +21,7 @@ -/* evp.h defines mini evp openssl compatibility layer +/* evp.h defines mini evp openssl compatibility layer * */ @@ -47,13 +47,14 @@ #include #include #include - +#ifdef HAVE_IDEA + #include +#endif #ifdef __cplusplus extern "C" { #endif -typedef char WOLFSSL_EVP_MD; typedef char WOLFSSL_EVP_CIPHER; #ifndef NO_MD5 @@ -66,12 +67,17 @@ WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ecb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void); @@ -128,39 +134,65 @@ enum { AES_128_CTR_TYPE = 4, AES_192_CTR_TYPE = 5, AES_256_CTR_TYPE = 6, - DES_CBC_TYPE = 7, - DES_EDE3_CBC_TYPE = 8, - ARC4_TYPE = 9, - NULL_CIPHER_TYPE = 10, - EVP_PKEY_RSA = 11, - EVP_PKEY_DSA = 12, - EVP_PKEY_EC = 13, - IDEA_CBC_TYPE = 14, + AES_128_ECB_TYPE = 7, + AES_192_ECB_TYPE = 8, + AES_256_ECB_TYPE = 9, + DES_CBC_TYPE = 10, + DES_ECB_TYPE = 11, + DES_EDE3_CBC_TYPE = 12, + DES_EDE3_ECB_TYPE = 13, + ARC4_TYPE = 14, + NULL_CIPHER_TYPE = 15, + EVP_PKEY_RSA = 16, + EVP_PKEY_DSA = 17, + EVP_PKEY_EC = 18, + IDEA_CBC_TYPE = 19, NID_sha1 = 64, NID_md2 = 3, NID_md5 = 4 }; - +#define WOLFSSL_EVP_BUF_SIZE 16 typedef struct WOLFSSL_EVP_CIPHER_CTX { int keyLen; /* user may set for variable */ + int block_size; + unsigned long flags; unsigned char enc; /* if encrypt side, then true */ unsigned char cipherType; #ifndef NO_AES - unsigned char iv[AES_BLOCK_SIZE]; /* working iv pointer into cipher */ + /* working iv pointer into cipher */ + ALIGN16 unsigned char iv[AES_BLOCK_SIZE]; #elif !defined(NO_DES3) - unsigned char iv[DES_BLOCK_SIZE]; /* working iv pointer into cipher */ + /* working iv pointer into cipher */ + ALIGN16 unsigned char iv[DES_BLOCK_SIZE]; #endif WOLFSSL_Cipher cipher; + ALIGN16 byte buf[WOLFSSL_EVP_BUF_SIZE]; + int bufUsed; + ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; + int lastUsed; } WOLFSSL_EVP_CIPHER_CTX; +typedef int WOLFSSL_ENGINE ; +typedef WOLFSSL_ENGINE ENGINE; +WOLFSSL_API void wolfSSL_EVP_init(void); WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* md); +WOLFSSL_API int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md); + +WOLFSSL_API WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new (void); +WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX* ctx); WOLFSSL_API void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx); WOLFSSL_API int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx); +WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx); +WOLFSSL_API const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name); +WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name); WOLFSSL_API int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, const WOLFSSL_EVP_MD* type); +WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx, + const WOLFSSL_EVP_MD* type, + WOLFSSL_ENGINE *impl); WOLFSSL_API int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data, unsigned long sz); WOLFSSL_API int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, @@ -184,6 +216,43 @@ WOLFSSL_API int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx, const WOLFSSL_EVP_CIPHER* type, unsigned char* key, unsigned char* iv, int enc); +WOLFSSL_API int wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + unsigned char* key, unsigned char* iv, + int enc); +WOLFSSL_API int wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + unsigned char* key, unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + unsigned char* key, unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + unsigned char* key, unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, + const WOLFSSL_EVP_CIPHER* type, + WOLFSSL_ENGINE *impl, + unsigned char* key, unsigned char* iv); +WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl); +WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_CipherFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, int enc); +WOLFSSL_API int wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_EncryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); +WOLFSSL_API int wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl); + +WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void); +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx, int keylen); @@ -209,6 +278,35 @@ WOLFSSL_API void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, WOLFSSL_API int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx); WOLFSSL_API int wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API unsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API unsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher); +WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags); +WOLFSSL_API unsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *c, int pad); +WOLFSSL_API int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest); + +#define EVP_CIPH_STREAM_CIPHER WOLFSSL_EVP_CIPH_STREAM_CIPHER +#define EVP_CIPH_ECB_MODE WOLFSSL_EVP_CIPH_ECB_MODE +#define EVP_CIPH_CBC_MODE WOLFSSL_EVP_CIPH_CBC_MODE +#define EVP_CIPH_CFB_MODE WOLFSSL_EVP_CIPH_CFB_MODE +#define EVP_CIPH_OFB_MODE WOLFSSL_EVP_CIPH_OFB_MODE +#define EVP_CIPH_CTR_MODE WOLFSSL_EVP_CIPH_CTR_MODE +#define EVP_CIPH_GCM_MODE WOLFSSL_EVP_CIPH_GCM_MODE +#define EVP_CIPH_CCM_MODE WOLFSSL_EVP_CIPH_CCM_MODE + +#define WOLFSSL_EVP_CIPH_MODE 0x0007 +#define WOLFSSL_EVP_CIPH_STREAM_CIPHER 0x0 +#define WOLFSSL_EVP_CIPH_ECB_MODE 0x1 +#define WOLFSSL_EVP_CIPH_CBC_MODE 0x2 +#define WOLFSSL_EVP_CIPH_CFB_MODE 0x3 +#define WOLFSSL_EVP_CIPH_OFB_MODE 0x4 +#define WOLFSSL_EVP_CIPH_CTR_MODE 0x5 +#define WOLFSSL_EVP_CIPH_GCM_MODE 0x6 +#define WOLFSSL_EVP_CIPH_CCM_MODE 0x7 +#define WOLFSSL_EVP_CIPH_NO_PADDING 0x100 /* end OpenSSH compat */ @@ -230,38 +328,84 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc #define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc #define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc +#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb +#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb +#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb #define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr #define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr #define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr #define EVP_des_cbc wolfSSL_EVP_des_cbc +#define EVP_des_ecb wolfSSL_EVP_des_ecb #define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc +#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb #define EVP_rc4 wolfSSL_EVP_rc4 #define EVP_idea_cbc wolfSSL_EVP_idea_cbc #define EVP_enc_null wolfSSL_EVP_enc_null #define EVP_MD_size wolfSSL_EVP_MD_size +#define EVP_MD_CTX_new wolfSSL_EVP_MD_CTX_new +#define EVP_MD_CTX_create wolfSSL_EVP_MD_CTX_new +#define EVP_MD_CTX_free wolfSSL_EVP_MD_CTX_free +#define EVP_MD_CTX_destroy wolfSSL_EVP_MD_CTX_free #define EVP_MD_CTX_init wolfSSL_EVP_MD_CTX_init #define EVP_MD_CTX_cleanup wolfSSL_EVP_MD_CTX_cleanup +#define EVP_MD_CTX_md wolfSSL_EVP_MD_CTX_md +#define EVP_MD_CTX_type wolfSSL_EVP_MD_type +#define EVP_MD_type wolfSSL_EVP_MD_type + #define EVP_DigestInit wolfSSL_EVP_DigestInit +#define EVP_DigestInit_ex wolfSSL_EVP_DigestInit_ex #define EVP_DigestUpdate wolfSSL_EVP_DigestUpdate #define EVP_DigestFinal wolfSSL_EVP_DigestFinal #define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex #define EVP_BytesToKey wolfSSL_EVP_BytesToKey +#define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname +#define EVP_get_digestbyname wolfSSL_EVP_get_digestbyname + #define EVP_CIPHER_CTX_init wolfSSL_EVP_CIPHER_CTX_init #define EVP_CIPHER_CTX_cleanup wolfSSL_EVP_CIPHER_CTX_cleanup #define EVP_CIPHER_CTX_iv_length wolfSSL_EVP_CIPHER_CTX_iv_length #define EVP_CIPHER_CTX_key_length wolfSSL_EVP_CIPHER_CTX_key_length #define EVP_CIPHER_CTX_set_key_length wolfSSL_EVP_CIPHER_CTX_set_key_length +#define EVP_CIPHER_CTX_mode wolfSSL_EVP_CIPHER_CTX_mode + #define EVP_CipherInit wolfSSL_EVP_CipherInit +#define EVP_CipherInit_ex wolfSSL_EVP_CipherInit_ex +#define EVP_EncryptInit wolfSSL_EVP_EncryptInit +#define EVP_EncryptInit_ex wolfSSL_EVP_EncryptInit_ex +#define EVP_DecryptInit wolfSSL_EVP_DecryptInit +#define EVP_DecryptInit_ex wolfSSL_EVP_DecryptInit_ex + #define EVP_Cipher wolfSSL_EVP_Cipher +#define EVP_CipherUpdate wolfSSL_EVP_CipherUpdate +#define EVP_EncryptUpdate wolfSSL_EVP_CipherUpdate +#define EVP_DecryptUpdate wolfSSL_EVP_CipherUpdate +#define EVP_CipherFinal wolfSSL_EVP_CipherFinal +#define EVP_CipherFinal_ex wolfSSL_EVP_CipherFinal +#define EVP_EncryptFinal wolfSSL_EVP_CipherFinal +#define EVP_EncryptFinal_ex wolfSSL_EVP_CipherFinal +#define EVP_DecryptFinal wolfSSL_EVP_CipherFinal +#define EVP_DecryptFinal_ex wolfSSL_EVP_CipherFinal + +#define EVP_CIPHER_CTX_free wolfSSL_EVP_CIPHER_CTX_free +#define EVP_CIPHER_CTX_new wolfSSL_EVP_CIPHER_CTX_new #define EVP_get_digestbynid wolfSSL_EVP_get_digestbynid +#define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname +#define EVP_get_digestbyname wolfSSL_EVP_get_digestbyname #define EVP_PKEY_get1_RSA wolfSSL_EVP_PKEY_get1_RSA #define EVP_PKEY_get1_DSA wolfSSL_EVP_PKEY_get1_DSA #define EVP_PKEY_get1_EC_KEY wolfSSL_EVP_PKEY_get1_EC_KEY +#define EVP_CIPHER_CTX_block_size wolfSSL_EVP_CIPHER_CTX_block_size +#define EVP_CIPHER_block_size wolfSSL_EVP_CIPHER_block_size +#define EVP_CIPHER_flags wolfSSL_EVP_CIPHER_flags +#define EVP_CIPHER_CTX_set_flags wolfSSL_EVP_CIPHER_CTX_set_flags +#define EVP_CIPHER_CTX_set_padding wolfSSL_EVP_CIPHER_CTX_set_padding +#define EVP_CIPHER_CTX_flags wolfSSL_EVP_CIPHER_CTX_flags +#define EVP_add_digest wolfSSL_EVP_add_digest #ifndef EVP_MAX_MD_SIZE #define EVP_MAX_MD_SIZE 64 /* sha512 */ diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 21d99ef00c..d6d7438356 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -3,6 +3,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/asn1.h \ + wolfssl/openssl/aes.h\ wolfssl/openssl/bio.h \ wolfssl/openssl/bn.h \ wolfssl/openssl/conf.h \ diff --git a/wolfssl/openssl/md5.h b/wolfssl/openssl/md5.h index bdcda5b98a..2e8620825b 100644 --- a/wolfssl/openssl/md5.h +++ b/wolfssl/openssl/md5.h @@ -32,11 +32,16 @@ typedef WOLFSSL_MD5_CTX MD5_CTX; #define MD5_Update wolfSSL_MD5_Update #define MD5_Final wolfSSL_MD5_Final +#ifdef OPENSSL_EXTRA_BSD + #define MD5Init wolfSSL_MD5_Init + #define MD5Update wolfSSL_MD5_Update + #define MD5Final wolfSSL_MD5_Final +#endif + #ifdef __cplusplus - } /* extern "C" */ + } /* extern "C" */ #endif #endif /* NO_MD5 */ #endif /* WOLFSSL_MD5_H_ */ - diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 76a391f542..60624aa5c3 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -13,13 +13,14 @@ extern "C" { #endif +#define PEM_write_bio_PrivateKey wolfSSL_PEM_write_bio_PrivateKey /* RSA */ WOLFSSL_API int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, - pem_password_cb cb, void* arg); + pem_password_cb* cb, void* arg); WOLFSSL_API int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, @@ -46,7 +47,7 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, - pem_password_cb cb, void* arg); + pem_password_cb* cb, void* arg); WOLFSSL_API int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, const EVP_CIPHER* cipher, @@ -67,7 +68,7 @@ WOLFSSL_API int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, const EVP_CIPHER* cipher, unsigned char* passwd, int len, - pem_password_cb cb, void* arg); + pem_password_cb* cb, void* arg); WOLFSSL_API int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* key, const EVP_CIPHER* cipher, @@ -87,9 +88,15 @@ int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *key); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY**, - pem_password_cb cb, + pem_password_cb* cb, void* arg); WOLFSSL_API +int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, + const WOLFSSL_EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb* cb, void* arg); + +WOLFSSL_API int wolfSSL_EVP_PKEY_type(int type); #if !defined(NO_FILESYSTEM) @@ -98,6 +105,7 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); #endif /* NO_FILESYSTEM */ +#define PEM_write_bio_PrivateKey wolfSSL_PEM_write_bio_PrivateKey /* RSA */ #define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey #define PEM_write_RSAPrivateKey wolfSSL_PEM_write_RSAPrivateKey diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 22592f7d7d..d0b114c109 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -21,7 +21,7 @@ -/* ssl.h defines wolfssl_openssl compatibility layer +/* ssl.h defines wolfssl_openssl compatibility layer * */ @@ -80,6 +80,12 @@ typedef WOLFSSL_ASN1_INTEGER ASN1_INTEGER; typedef WOLFSSL_ASN1_OBJECT ASN1_OBJECT; typedef WOLFSSL_ASN1_STRING ASN1_STRING; typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value; +typedef WOLFSSL_BUF_MEM BUF_MEM; + +/* GENERAL_NAME and BASIC_CONSTRAINTS structs may need implemented as + * compatibility layer expands. For now treating them as an ASN1_OBJECT */ +typedef WOLFSSL_ASN1_OBJECT GENERAL_NAME; +typedef WOLFSSL_ASN1_OBJECT BASIC_CONSTRAINTS; #define ASN1_UTCTIME WOLFSSL_ASN1_TIME @@ -101,16 +107,23 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; strncpy(buf, "Not Implemented, SSLv2 only", len) /* @TODO */ -#define ERR_print_errors_fp(file) +#define ERR_print_errors_fp(file) wolfSSL_ERR_print_errors_fp((file)) /* at the moment only returns ok */ -#define SSL_get_verify_result(ctx) X509_V_OK +#define SSL_get_verify_result wolfSSL_get_verify_result #define SSL_get_verify_mode wolfSSL_SSL_get_mode #define SSL_get_verify_depth wolfSSL_get_verify_depth #define SSL_CTX_get_verify_mode wolfSSL_CTX_get_verify_mode #define SSL_CTX_get_verify_depth wolfSSL_CTX_get_verify_depth #define SSL_get_certificate wolfSSL_get_certificate +#define SSL_use_certificate wolfSSL_use_certificate +#define SSL_use_certificate_ASN1 wolfSSL_use_certificate_ASN1 +#define SSL_use_PrivateKey wolfSSL_use_PrivateKey +#define SSL_use_PrivateKey_ASN1 wolfSSL_use_PrivateKey_ASN1 +#define SSL_use_RSAPrivateKey_ASN1 wolfSSL_use_RSAPrivateKey_ASN1 + +#define SSLv23_method wolfSSLv23_method #define SSLv3_server_method wolfSSLv3_server_method #define SSLv3_client_method wolfSSLv3_client_method #define TLSv1_server_method wolfTLSv1_server_method @@ -134,7 +147,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_CTX_load_verify_locations wolfSSL_CTX_load_verify_locations #define SSL_CTX_use_certificate_chain_file wolfSSL_CTX_use_certificate_chain_file #define SSL_CTX_use_RSAPrivateKey_file wolfSSL_CTX_use_RSAPrivateKey_file - + #define SSL_use_certificate_file wolfSSL_use_certificate_file #define SSL_use_PrivateKey_file wolfSSL_use_PrivateKey_file #define SSL_use_certificate_chain_file wolfSSL_use_certificate_chain_file @@ -147,6 +160,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_get_fd wolfSSL_get_fd #define SSL_connect wolfSSL_connect #define SSL_clear wolfSSL_clear +#define SSL_state wolfSSL_state #define SSL_write wolfSSL_write #define SSL_read wolfSSL_read @@ -201,7 +215,12 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_get_keyblock_size wolfSSL_get_keyblock_size #define SSL_get_keys wolfSSL_get_keys +#define SSL_SESSION_get_master_key wolfSSL_SESSION_get_master_key +#define SSL_SESSION_get_master_key_length wolfSSL_SESSION_get_master_key_length +#define SSL_X509_NAME_get_text_by_NID wolfSSL_X509_NAME_get_text_by_NID +#define X509_get_ext_d2i wolfSSL_X509_get_ext_d2i +#define X509_digest wolfSSL_X509_digest #define X509_free wolfSSL_X509_free #define OPENSSL_free wolfSSL_OPENSSL_free @@ -217,7 +236,11 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define BIO_new wolfSSL_BIO_new #define BIO_free wolfSSL_BIO_free #define BIO_free_all wolfSSL_BIO_free_all +#define BIO_nread0 wolfSSL_BIO_nread0 +#define BIO_nread wolfSSL_BIO_nread #define BIO_read wolfSSL_BIO_read +#define BIO_nwrite0 wolfSSL_BIO_nwrite0 +#define BIO_nwrite wolfSSL_BIO_nwrite #define BIO_write wolfSSL_BIO_write #define BIO_push wolfSSL_BIO_push #define BIO_pop wolfSSL_BIO_pop @@ -239,9 +262,10 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define BIO_f_base64 wolfSSL_BIO_f_base64 #define BIO_set_flags wolfSSL_BIO_set_flags +#define OpenSSL_add_all_digests() #define OpenSSL_add_all_algorithms wolfSSL_add_all_algorithms #define SSLeay_add_ssl_algorithms wolfSSL_add_all_algorithms -#define SSLeay_add_all_algorithms wolfSSL_add_all_algorithms +#define SSLeay_add_all_algorithms wolfSSL_add_all_algorithms #define RAND_screen wolfSSL_RAND_screen #define RAND_file_name wolfSSL_RAND_file_name @@ -271,6 +295,9 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; # define CRYPTO_WRITE 8 #define X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert +#define X509_STORE_add_cert wolfSSL_X509_STORE_add_cert +#define X509_STORE_set_flags wolfSSL_X509_STORE_set_flags +#define X509_STORE_CTX_get_chain wolfSSL_X509_STORE_CTX_get_chain #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 @@ -297,6 +324,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define X509_CRL_verify wolfSSL_X509_CRL_verify #define X509_STORE_CTX_set_error wolfSSL_X509_STORE_CTX_set_error #define X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents +#define EVP_PKEY_new wolfSSL_PKEY_new #define EVP_PKEY_free wolfSSL_EVP_PKEY_free #define X509_cmp_current_time wolfSSL_X509_cmp_current_time #define sk_X509_REVOKED_num wolfSSL_sk_X509_REVOKED_num @@ -312,10 +340,13 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define ASN1_INTEGER_cmp wolfSSL_ASN1_INTEGER_cmp #define ASN1_INTEGER_get wolfSSL_ASN1_INTEGER_get +#define ASN1_INTEGER_to_BN wolfSSL_ASN1_INTEGER_to_BN #define SSL_load_client_CA_file wolfSSL_load_client_CA_file #define SSL_CTX_set_client_CA_list wolfSSL_CTX_set_client_CA_list +#define SSL_CTX_set_cert_store wolfSSL_CTX_set_cert_store +#define SSL_CTX_get_cert_store wolfSSL_CTX_get_cert_store #define X509_STORE_CTX_get_ex_data wolfSSL_X509_STORE_CTX_get_ex_data #define SSL_get_ex_data_X509_STORE_CTX_idx wolfSSL_get_ex_data_X509_STORE_CTX_idx #define SSL_get_ex_data wolfSSL_get_ex_data @@ -327,6 +358,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_CTX_set_info_callback wolfSSL_CTX_set_info_callback #define ERR_peek_error wolfSSL_ERR_peek_error +#define ERR_peek_last_error_line wolfSSL_ERR_peek_last_error_line +#define ERR_peek_errors_fp wolfSSL_ERR_peek_errors_fp #define ERR_GET_REASON wolfSSL_ERR_GET_REASON #define SSL_alert_type_string wolfSSL_alert_type_string @@ -377,7 +410,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define RAND_status wolfSSL_RAND_status #define RAND_bytes wolfSSL_RAND_bytes #define SSLv23_server_method wolfSSLv23_server_method -#define SSL_CTX_set_options wolfSSL_CTX_set_options +#define SSL_CTX_set_options wolfSSL_CTX_set_options #define SSL_CTX_check_private_key wolfSSL_CTX_check_private_key #define ERR_free_strings wolfSSL_ERR_free_strings @@ -405,6 +438,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define sk_value wolfSSL_sk_value #define sk_X509_pop wolfSSL_sk_X509_pop #define sk_X509_free wolfSSL_sk_X509_free +#define d2i_X509_bio wolfSSL_d2i_X509_bio #define SSL_CTX_get_ex_data wolfSSL_CTX_get_ex_data #define SSL_CTX_set_ex_data wolfSSL_CTX_set_ex_data @@ -418,6 +452,21 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_SESSION_get_timeout wolfSSL_SESSION_get_timeout #define SSL_SESSION_get_time wolfSSL_SESSION_get_time #define SSL_CTX_get_ex_new_index wolfSSL_CTX_get_ex_new_index +#define PEM_read_bio_X509 wolfSSL_PEM_read_bio_X509 +#define PEM_read_bio_X509_AUX wolfSSL_PEM_read_bio_X509_AUX + +/*#if OPENSSL_API_COMPAT < 0x10100000L*/ +#define CONF_modules_free() +#define ENGINE_cleanup() +#define HMAC_CTX_cleanup wolfSSL_HMAC_cleanup +#define SSL_CTX_need_tmp_RSA(ctx) 0 +#define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 +#define SSL_need_tmp_RSA(ssl) 0 +#define SSL_set_tmp_rsa(ssl,rsa) 1 +/*#endif*/ +#define CONF_modules_unload(a) + +#define SSL_get_hit wolfSSL_session_reused /* yassl had set the default to be 500 */ #define SSL_get_default_timeout(ctx) 500 @@ -433,10 +482,9 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define SSL_CTX_use_PrivateKey wolfSSL_CTX_use_PrivateKey #define BIO_read_filename wolfSSL_BIO_read_filename #define BIO_s_file wolfSSL_BIO_s_file -#define OBJ_nid2sn wolf_OBJ_nid2sn -#define OBJ_obj2nid wolf_OBJ_obj2nid -#define OBJ_sn2nid wolf_OBJ_sn2nid -#define PEM_read_bio_X509 PEM_read_bio_WOLFSSL_X509 +#define OBJ_nid2sn wolfSSL_OBJ_nid2sn +#define OBJ_obj2nid wolfSSL_OBJ_obj2nid +#define OBJ_sn2nid wolfSSL_OBJ_sn2nid #define SSL_CTX_set_verify_depth wolfSSL_CTX_set_verify_depth #define SSL_get_app_data wolfSSL_get_app_data #define SSL_set_app_data wolfSSL_set_app_data @@ -458,21 +506,105 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) \ || defined(WOLFSSL_MYSQL_COMPATIBLE) -#define OBJ_nid2ln wolf_OBJ_nid2ln -#define OBJ_txt2nid wolf_OBJ_txt2nid +#define OBJ_nid2ln wolfSSL_OBJ_nid2ln +#define OBJ_txt2nid wolfSSL_OBJ_txt2nid #define PEM_read_bio_DHparams wolfSSL_PEM_read_bio_DHparams +#define PEM_read_bio_DSAparams wolfSSL_PEM_read_bio_DSAparams #define PEM_write_bio_X509 PEM_write_bio_WOLFSSL_X509 -#define SSL_CTX_set_tmp_dh wolfSSL_CTX_set_tmp_dh -#define BIO_new_file wolfSSL_BIO_new_file - #endif /* HAVE_STUNNEL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE */ +#define SSL_CTX_set_tmp_dh wolfSSL_CTX_set_tmp_dh + +#define BIO_new_file wolfSSL_BIO_new_file +#define BIO_ctrl wolfSSL_BIO_ctrl +#define BIO_ctrl_pending wolfSSL_BIO_ctrl_pending +#define BIO_get_mem_ptr wolfSSL_BIO_get_mem_ptr +#define BIO_int_ctrl wolfSSL_BIO_int_ctrl +#define BIO_reset wolfSSL_BIO_reset +#define BIO_s_file wolfSSL_BIO_s_file +#define BIO_s_bio wolfSSL_BIO_s_bio +#define BIO_s_socket wolfSSL_BIO_s_socket +#define BIO_set_fd wolfSSL_BIO_set_fd +#define BIO_ctrl_reset_read_request wolfSSL_BIO_ctrl_reset_read_request + +#define BIO_set_write_buf_size wolfSSL_BIO_set_write_buf_size +#define BIO_make_bio_pair wolfSSL_BIO_make_bio_pair + +#define BIO_set_fp wolfSSL_BIO_set_fp +#define BIO_get_fp wolfSSL_BIO_get_fp +#define BIO_seek wolfSSL_BIO_seek +#define BIO_write_filename wolfSSL_BIO_write_filename +#define BIO_set_mem_eof_return wolfSSL_BIO_set_mem_eof_return + +#define SSL_set_options wolfSSL_set_options +#define SSL_get_options wolfSSL_get_options +#define SSL_set_tmp_dh wolfSSL_set_tmp_dh +#define SSL_clear_num_renegotiations wolfSSL_clear_num_renegotiations +#define SSL_total_renegotiations wolfSSL_total_renegotiations +#define SSL_set_tlsext_debug_arg wolfSSL_set_tlsext_debug_arg +#define SSL_set_tlsext_status_type wolfSSL_set_tlsext_status_type +#define SSL_set_tlsext_status_exts wolfSSL_set_tlsext_status_exts +#define SSL_get_tlsext_status_ids wolfSSL_get_tlsext_status_ids +#define SSL_set_tlsext_status_ids wolfSSL_set_tlsext_status_ids +#define SSL_get_tlsext_status_ocsp_resp wolfSSL_get_tlsext_status_ocsp_resp +#define SSL_set_tlsext_status_ocsp_resp wolfSSL_set_tlsext_status_ocsp_resp + +#define SSL_CTX_add_extra_chain_cert wolfSSL_CTX_add_extra_chain_cert +#define SSL_CTX_get_read_ahead wolfSSL_CTX_get_read_ahead +#define SSL_CTX_set_read_ahead wolfSSL_CTX_set_read_ahead +#define SSL_CTX_set_tlsext_status_arg wolfSSL_CTX_set_tlsext_status_arg +#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg \ + wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg +#define SSL_get_server_random wolfSSL_get_server_random + +#define SSL_get_tlsext_status_exts wolfSSL_get_tlsext_status_exts + +#define BIO_C_SET_FILE_PTR 106 +#define BIO_C_GET_FILE_PTR 107 +#define BIO_C_SET_FILENAME 108 +#define BIO_C_FILE_SEEK 128 +#define BIO_C_SET_BUF_MEM_EOF_RETURN 130 +#define BIO_C_SET_WRITE_BUF_SIZE 136 +#define BIO_C_MAKE_BIO_PAIR 138 + +#define BIO_CTRL_RESET 1 +#define BIO_CTRL_INFO 3 +#define BIO_CTRL_FLUSH 11 +#define BIO_CLOSE 0x01 +#define BIO_FP_WRITE 0x04 + +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 + +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_EXTRA_CHAIN_CERT 14 + +#define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +#define SSL_CTRL_GET_READ_AHEAD 40 +#define SSL_CTRL_SET_READ_AHEAD 41 + +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 + +#define SSL_ctrl wolfSSL_ctrl +#define SSL_CTX_ctrl wolfSSL_CTX_ctrl + +#define X509_V_FLAG_CRL_CHECK WOLFSSL_CRL_CHECK +#define X509_V_FLAG_CRL_CHECK_ALL WOLFSSL_CRL_CHECKALL #ifdef HAVE_STUNNEL #include /* defined as: (SSL_ST_ACCEPT|SSL_CB_LOOP), which becomes 0x2001*/ -#define SSL_CB_ACCEPT_LOOP 0x2001 +#define SSL_CB_ACCEPT_LOOP 0x2001 #define SSL2_VERSION 0x0002 #define SSL3_VERSION 0x0300 #define TLS1_VERSION 0x0301 @@ -518,8 +650,8 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define SSL_get_servername wolfSSL_get_servername #define SSL_set_SSL_CTX wolfSSL_set_SSL_CTX #define SSL_CTX_get_verify_callback wolfSSL_CTX_get_verify_callback -#define SSL_CTX_set_tlsext_servername_callback wolfSSL_CTX_set_servername_callback -#define SSL_CTX_set_tlsext_servername_arg wolfSSL_CTX_set_servername_arg +#define SSL_CTX_set_tlsext_servername_callback wolfSSL_CTX_set_servername_callback +#define SSL_CTX_set_tlsext_servername_arg wolfSSL_CTX_set_servername_arg #define PSK_MAX_PSK_LEN 256 #define PSK_MAX_IDENTITY_LEN 128 @@ -528,6 +660,26 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #endif /* HAVE_STUNNEL */ +#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 + +/* certificate extension NIDs */ +#define NID_basic_constraints 133 +#define NID_key_usage 129 /* 2.5.29.15 */ +#define NID_ext_key_usage 151 /* 2.5.29.37 */ +#define NID_subject_key_identifier 128 +#define NID_authority_key_identifier 149 +#define NID_private_key_usage_period 130 /* 2.5.29.16 */ +#define NID_subject_alt_name 131 +#define NID_issuer_alt_name 132 +#define NID_info_access 69 +#define NID_sinfo_access 79 /* id-pe 11 */ +#define NID_name_constraints 144 /* 2.5.29.30 */ +#define NID_certificate_policies 146 +#define NID_policy_mappings 147 +#define NID_policy_constraints 150 +#define NID_inhibit_any_policy 168 /* 2.5.29.54 */ +#define NID_tlsfeature 92 /* id-pe 24 */ #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 24fee4e10e..5db4f8270e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -59,7 +59,9 @@ #undef OCSP_RESPONSE #endif - +#ifdef OPENSSL_EXTRA + #include +#endif #ifdef __cplusplus extern "C" { @@ -113,15 +115,24 @@ typedef struct WOLFSSL_ASN1_STRING WOLFSSL_ASN1_STRING; typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; typedef struct WOLFSSL_DH WOLFSSL_DH; typedef struct WOLFSSL_ASN1_BIT_STRING WOLFSSL_ASN1_BIT_STRING; +typedef unsigned char* WOLFSSL_BUF_MEM; #define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME +struct WOLFSSL_ASN1_INTEGER { + /* size can be increased set at 20 for tag, length then to hold at least 16 + * byte type */ + unsigned char data[20]; + /* ASN_INTEGER | LENGTH | hex of number */ +}; + +typedef char WOLFSSL_EVP_MD; typedef struct WOLFSSL_EVP_PKEY { int type; /* openssh dereference */ int save_type; /* openssh dereference */ int pkey_sz; union { - char* ptr; + char* ptr; /* der format of key / or raw for NTRU */ } pkey; #ifdef HAVE_ECC int pkey_curve; @@ -174,6 +185,7 @@ typedef struct WOLFSSL_BUFFER_INFO { typedef struct WOLFSSL_X509_STORE_CTX { WOLFSSL_X509_STORE* store; /* Store full of a CA cert chain */ WOLFSSL_X509* current_cert; /* stunnel dereference */ + WOLFSSL_STACK* chain; char* domain; /* subject CN domain name */ void* ex_data; /* external data, for fortress build */ void* userCtx; /* user ctx */ @@ -239,6 +251,7 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_client_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method_ex(void* heap); #endif +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_server_method(void); @@ -438,6 +451,13 @@ WOLFSSL_API int wolfSSL_sk_X509_push(STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509); WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(STACK_OF(WOLFSSL_X509_NAME)* sk); WOLFSSL_API void wolfSSL_sk_X509_free(STACK_OF(WOLFSSL_X509_NAME)* sk); +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void); +WOLFSSL_API void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj); +WOLFSSL_API int wolfSSL_sk_ASN1_OBJECT_push(STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk, + WOLFSSL_ASN1_OBJECT* obj); +WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJCET_pop( + STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); +WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_free(STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); WOLFSSL_API int wolfSSL_set_ex_data(WOLFSSL*, int, void*); WOLFSSL_API int wolfSSL_get_shutdown(const WOLFSSL*); @@ -501,11 +521,34 @@ WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,const unsigned char** WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len); -WOLFSSL_API long wolfSSL_BIO_set_ssl(WOLFSSL_BIO*, WOLFSSL*, int flag); -WOLFSSL_API void wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr); - +WOLFSSL_API long wolfSSL_BIO_set_ssl(WOLFSSL_BIO*, WOLFSSL*, int flag); +WOLFSSL_API long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int flag); +WOLFSSL_API void wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr); WOLFSSL_API int wolfSSL_add_all_algorithms(void); +#ifndef NO_FILESYSTEM +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_file(void); +#endif + +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void); +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void); + +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); + +WOLFSSL_API int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *b, long size); +WOLFSSL_API int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2); +WOLFSSL_API int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b); +WOLFSSL_API int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf); +WOLFSSL_API int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num); +WOLFSSL_API int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num); +WOLFSSL_API int wolfSSL_BIO_reset(WOLFSSL_BIO *bio); + +WOLFSSL_API int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs); +WOLFSSL_API int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name); +WOLFSSL_API long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v); +WOLFSSL_API long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **m); + WOLFSSL_API void wolfSSL_RAND_screen(void); WOLFSSL_API const char* wolfSSL_RAND_file_name(char*, unsigned long); WOLFSSL_API int wolfSSL_RAND_write_file(const char*); @@ -574,6 +617,10 @@ WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void); WOLFSSL_API void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE*); WOLFSSL_API int wolfSSL_X509_STORE_add_cert( WOLFSSL_X509_STORE*, WOLFSSL_X509*); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain( + 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*); WOLFSSL_API int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX*, int, WOLFSSL_X509_NAME*, WOLFSSL_X509_OBJECT*); @@ -591,6 +638,9 @@ WOLFSSL_API int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL*, WOLFSSL_EVP_PKE WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX*, int); WOLFSSL_API void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT*); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, + WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new(void); WOLFSSL_API void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY*); WOLFSSL_API int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME*); WOLFSSL_API int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED*); @@ -606,7 +656,11 @@ WOLFSSL_API int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER*, const WOLFSSL_ASN1_INTEGER*); WOLFSSL_API long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER*); +#ifdef OPENSSL_EXTRA +WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai, + WOLFSSL_BIGNUM *bn); WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char*); +#endif WOLFSSL_API void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX*, STACK_OF(WOLFSSL_X509_NAME)*); @@ -648,11 +702,73 @@ WOLFSSL_API long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX*); WOLFSSL_API long wolfSSL_CTX_sess_misses(WOLFSSL_CTX*); WOLFSSL_API long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX*); WOLFSSL_API long wolfSSL_CTX_sess_number(WOLFSSL_CTX*); + +WOLFSSL_API long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX*, WOLFSSL_X509*); +WOLFSSL_API long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX*, long); WOLFSSL_API long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX*); +WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX*, int v); +WOLFSSL_API long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX*, void* arg); +WOLFSSL_API long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg( + WOLFSSL_CTX*, void* arg); + +WOLFSSL_API unsigned long wolfSSL_set_options(WOLFSSL *s, unsigned long op); +WOLFSSL_API unsigned long wolfSSL_get_options(const WOLFSSL *s); +WOLFSSL_API long wolfSSL_clear_num_renegotiations(WOLFSSL *s); +WOLFSSL_API long wolfSSL_total_renegotiations(WOLFSSL *s); +WOLFSSL_API long wolfSSL_set_tmp_dh(WOLFSSL *s, WOLFSSL_DH *dh); +WOLFSSL_API long wolfSSL_set_tlsext_debug_arg(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type); +WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp); +WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len); + +WOLFSSL_API void wolfSSL_CONF_modules_unload(int all); +WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg); +WOLFSSL_API long wolfSSL_get_verify_result(const WOLFSSL *ssl); + #define WOLFSSL_DEFAULT_CIPHER_LIST "" /* default all */ #define WOLFSSL_RSA_F4 0x10001L +/* seperated out from other enums because of size */ +enum { + /* bit flags (ie 0001 vs 0010) : each is 2 times previous value */ + SSL_OP_MICROSOFT_SESS_ID_BUG = 1, + SSL_OP_NETSCAPE_CHALLENGE_BUG = 2, + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 4, + SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 8, + SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 16, + SSL_OP_MSIE_SSLV2_RSA_PADDING = 32, + SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 64, + SSL_OP_TLS_D5_BUG = 128, + SSL_OP_TLS_BLOCK_PADDING_BUG = 256, + SSL_OP_TLS_ROLLBACK_BUG = 512, + SSL_OP_ALL = 1024, + SSL_OP_EPHEMERAL_RSA = 2048, + SSL_OP_NO_SSLv3 = 4096, + SSL_OP_NO_TLSv1 = 8192, + SSL_OP_PKCS1_CHECK_1 = 16384, + SSL_OP_PKCS1_CHECK_2 = 32768, + SSL_OP_NETSCAPE_CA_DN_BUG = 65536, + SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 131072, + SSL_OP_SINGLE_DH_USE = 262144, + SSL_OP_NO_TICKET = 524288, + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 1048576, + SSL_OP_NO_QUERY_MTU = 2097152, + SSL_OP_COOKIE_EXCHANGE = 4194304, + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 8388608, + SSL_OP_SINGLE_ECDH_USE = 16777216, + SSL_OP_CIPHER_SERVER_PREFERENCE = 33554432, + SSL_OP_NO_TLSv1_1 = 67108864, + SSL_OP_NO_TLSv1_2 = 134217728, + SSL_OP_NO_COMPRESSION = 268435456, +}; + + enum { OCSP_NOCERTS = 1, OCSP_NOINTERN = 2, @@ -677,36 +793,9 @@ enum { WOLFSSL_OCSP_CHECKALL = 4, WOLFSSL_CRL_CHECKALL = 1, + WOLFSSL_CRL_CHECK = 27, ASN1_GENERALIZEDTIME = 4, - - SSL_OP_MICROSOFT_SESS_ID_BUG = 1, - SSL_OP_NETSCAPE_CHALLENGE_BUG = 2, - SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 3, - SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 4, - SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 5, - SSL_OP_MSIE_SSLV2_RSA_PADDING = 6, - SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 7, - SSL_OP_TLS_D5_BUG = 8, - SSL_OP_TLS_BLOCK_PADDING_BUG = 9, - SSL_OP_TLS_ROLLBACK_BUG = 10, - SSL_OP_ALL = 11, - SSL_OP_EPHEMERAL_RSA = 12, - SSL_OP_NO_SSLv3 = 13, - SSL_OP_NO_TLSv1 = 14, - SSL_OP_PKCS1_CHECK_1 = 15, - SSL_OP_PKCS1_CHECK_2 = 16, - SSL_OP_NETSCAPE_CA_DN_BUG = 17, - SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 18, - SSL_OP_SINGLE_DH_USE = 19, - SSL_OP_NO_TICKET = 20, - SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 21, - SSL_OP_NO_QUERY_MTU = 22, - SSL_OP_COOKIE_EXCHANGE = 23, - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 24, - SSL_OP_SINGLE_ECDH_USE = 25, - SSL_OP_CIPHER_SERVER_PREFERENCE = 26, - SSL_MAX_SSL_SESSION_ID_LENGTH = 32, EVP_R_BAD_DECRYPT = 2, @@ -854,6 +943,14 @@ enum { /* ERR Constants */ ERR_TXT_STRING = 1 }; +/* bio misc */ +enum { + WOLFSSL_BIO_ERROR = -1, + WOLFSSL_BIO_UNSET = -2, + WOLFSSL_BIO_SIZE = 17000 /* default BIO write size if not set */ +}; + + WOLFSSL_API unsigned long wolfSSL_ERR_get_error_line_data(const char**, int*, const char**, int *); @@ -873,6 +970,7 @@ WOLFSSL_API void wolfSSL_ERR_free_strings(void); WOLFSSL_API void wolfSSL_ERR_remove_state(unsigned long); WOLFSSL_API void wolfSSL_EVP_cleanup(void); WOLFSSL_API int wolfSSL_clear(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_state(WOLFSSL* ssl); WOLFSSL_API void wolfSSL_cleanup_all_ex_data(void); WOLFSSL_API long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode); @@ -880,7 +978,6 @@ WOLFSSL_API long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx); WOLFSSL_API void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m); WOLFSSL_API long wolfSSL_SSL_get_mode(WOLFSSL* ssl); -WOLFSSL_API long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX*, long); WOLFSSL_API int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX*); WOLFSSL_API int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX*, @@ -1290,6 +1387,7 @@ WOLFSSL_API int wolfSSL_SetTlsHmacInner(WOLFSSL*, unsigned char enum { WOLFSSL_SERVER_END = 0, WOLFSSL_CLIENT_END = 1, + WOLFSSL_NEITHER_END = 3, WOLFSSL_BLOCK_TYPE = 2, WOLFSSL_STREAM_TYPE = 3, WOLFSSL_AEAD_TYPE = 4, @@ -1748,7 +1846,8 @@ WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name); then will not send keys in the hello extension */ WOLFSSL_API int wolfSSL_UseClientQSHKeys(WOLFSSL* ssl, unsigned char flag); #endif -#endif + +#endif /* QSH */ /* TLS Extended Master Secret Extension */ WOLFSSL_API int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl); @@ -1821,9 +1920,55 @@ WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time, #ifdef OPENSSL_EXTRA -WOLFSSL_API int wolfSSL_get_client_random(WOLFSSL* ssl, unsigned char* out, - int outSz); +#ifndef NO_FILESYSTEM +WOLFSSL_API long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c); +WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp); +#endif +WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line); +WOLFSSL_API long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt); +WOLFSSL_API long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt,void* pt); + +#ifndef NO_CERTS +WOLFSSL_API int wolfSSL_check_private_key(const WOLFSSL* ssl); +WOLFSSL_API void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, + int nid, int* c, int* idx); +WOLFSSL_API int wolfSSL_X509_digest(const WOLFSSL_X509* x509, + const WOLFSSL_EVP_MD* digest, unsigned char* buf, unsigned int* len); +WOLFSSL_API int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509); +WOLFSSL_API int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, unsigned char* der, + int derSz); +WOLFSSL_API int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey); +WOLFSSL_API int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, + unsigned char* der, long derSz); +#ifndef NO_RSA +WOLFSSL_API int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, + long derSz); +#endif +#endif /* NO_CERTS */ + +WOLFSSL_API WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *r); + +WOLFSSL_API int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, + unsigned char* out, int outSz); +WOLFSSL_API int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses); + +WOLFSSL_API void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, + WOLFSSL_X509_STORE* str); +WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509); +WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx); + +WOLFSSL_API size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *b); +WOLFSSL_API size_t wolfSSL_get_server_random(const WOLFSSL *ssl, + unsigned char *out, size_t outlen); +WOLFSSL_API size_t wolfSSL_get_client_random(const WOLFSSL* ssl, + unsigned char* out, size_t outSz); +WOLFSSL_API pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx); +WOLFSSL_API void *wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx); +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); +WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX + (WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); /*lighttp compatibility */ @@ -1839,14 +1984,11 @@ struct WOLFSSL_X509_NAME_ENTRY { #if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name); WOLFSSL_API char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x); -WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name); -WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void); /* These are to be merged shortly */ -WOLFSSL_API const char * wolf_OBJ_nid2sn(int n); -WOLFSSL_API int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o); -WOLFSSL_API int wolf_OBJ_sn2nid(const char *sn); -WOLFSSL_API WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +WOLFSSL_API const char * wolfSSL_OBJ_nid2sn(int n); +WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o); +WOLFSSL_API int wolfSSL_OBJ_sn2nid(const char *sn); WOLFSSL_API void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth); WOLFSSL_API void* wolfSSL_get_app_data( const WOLFSSL *ssl); WOLFSSL_API void wolfSSL_set_app_data(WOLFSSL *ssl, void *arg); @@ -1857,20 +1999,25 @@ WOLFSSL_API unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsign WOLFSSL_API int wolfSSL_X509_check_private_key(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*); WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( STACK_OF(WOLFSSL_X509_NAME) *sk ); -/* end lighttpd, mysql, have_stunnel*/ +/* end lighttpd*/ #endif #endif #if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) \ - || defined(WOLFSSL_MYSQL_COMPATIBLE) + || defined(WOLFSSL_MYSQL_COMPATIBLE) \ + || defined(OPENSSL_EXTRA) -WOLFSSL_API char * wolf_OBJ_nid2ln(int n); -WOLFSSL_API int wolf_OBJ_txt2nid(const char *sn); +WOLFSSL_API char* wolfSSL_OBJ_nid2ln(int n); +WOLFSSL_API int wolfSSL_OBJ_txt2nid(const char *sn); 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*); WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u); -WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x); +WOLFSSL_API WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, + WOLFSSL_DSA **x, pem_password_cb *cb, void *u); +WOLFSSL_API int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x); +WOLFSSL_API long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx); + #endif /* HAVE_STUNNEL || HAVE_LIGHTY */ @@ -1928,8 +2075,6 @@ WOLFSSL_API void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)*, int); WOLFSSL_API STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL*); -WOLFSSL_API long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx); - WOLFSSL_API void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION*, int); WOLFSSL_API int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION*, int, void*); @@ -1958,6 +2103,10 @@ WOLFSSL_API void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX *, void*); WOLFSSL_API void WOLFSSL_ERR_remove_thread_state(void*); +#ifndef NO_FILESYSTEM +WOLFSSL_API void wolfSSL_print_all_errors_fp(XFILE *fp); +#endif + WOLFSSL_API long wolfSSL_CTX_clear_options(WOLFSSL_CTX*, long); WOLFSSL_API void wolfSSL_THREADID_set_callback(void (*threadid_func)(void*)); diff --git a/wolfssl/test.h b/wolfssl/test.h index b0b7517854..3e278161cd 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -524,6 +524,7 @@ static INLINE void showPeer(WOLFSSL* ssl) #endif #if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT) ShowX509(wolfSSL_get_certificate(ssl), "our cert info:"); + printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl)); #endif /* SHOW_CERTS */ printf("SSL version is %s\n", wolfSSL_get_version(ssl)); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index b7fb2c776e..2b3c4e576e 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -124,6 +124,13 @@ WOLFSSL_API int wc_AesCbcEncrypt(Aes* aes, byte* out, WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); +#ifdef HAVE_AES_ECB +WOLFSSL_API int wc_AesEcbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif + /* AES-CTR */ #ifdef WOLFSSL_AES_COUNTER WOLFSSL_API void wc_AesCtrEncrypt(Aes* aes, byte* out, @@ -192,4 +199,3 @@ WOLFSSL_API int wc_AesGetKeySize(Aes* aes, word32* keySize); #endif /* NO_AES */ #endif /* WOLF_CRYPT_AES_H */ - diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index fdb8dc7dc9..1eb4b6d90f 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -303,14 +303,20 @@ enum Extensions_Sum { BASIC_CA_OID = 133, ALT_NAMES_OID = 131, CRL_DIST_OID = 145, - AUTH_INFO_OID = 69, + AUTH_INFO_OID = 69, /* id-pe 1 */ AUTH_KEY_OID = 149, SUBJ_KEY_OID = 128, CERT_POLICY_OID = 146, KEY_USAGE_OID = 129, /* 2.5.29.15 */ INHIBIT_ANY_OID = 168, /* 2.5.29.54 */ - EXT_KEY_USAGE_OID = 151, /* 2.5.29.37 */ - NAME_CONS_OID = 144 /* 2.5.29.30 */ + EXT_KEY_USAGE_OID = 151, /* 2.5.29.37 */ + NAME_CONS_OID = 144, /* 2.5.29.30 */ + PRIV_KEY_USAGE_PERIOD_OID = 130, /* 2.5.29.16 */ + SUBJECT_INFO_ACCESS = 79, /* id-pe 11 */ + POLICY_MAP_OID = 147, + POLICY_CONST_OID = 150, + ISSUE_ALT_NAMES_OID = 132, + TLS_FEATURE_OID = 92 /* id-pe 24 */ }; enum CertificatePolicy_Sum { @@ -475,6 +481,10 @@ struct DecodedCert { byte extExtKeyUsageSet; /* Extended Key Usage */ byte extExtKeyUsage; /* Extended Key usage bitfield */ #ifdef OPENSSL_EXTRA + byte extCRLdistSet; + byte extCRLdistCrit; + byte extAuthInfoSet; + byte extAuthInfoCrit; byte extBasicConstSet; byte extBasicConstCrit; byte extSubjAltNameSet; @@ -554,10 +564,22 @@ struct DecodedCert { #endif /* WOLFSSL_CERT_EXT */ }; + +struct WOLFSSL_ASN1_OBJECT { + void* heap; + byte* obj; + int type; /* oid */ + word32 objSz; + byte dynamic; /* if 1 then obj was dynamiclly created, 0 otherwise */ +}; + + extern const char* BEGIN_CERT; extern const char* END_CERT; extern const char* BEGIN_CERT_REQ; extern const char* END_CERT_REQ; +extern const char* BEGIN_DSA_PARAM; +extern const char* END_DSA_PARAM; extern const char* BEGIN_DH_PARAM; extern const char* END_DH_PARAM; extern const char* BEGIN_X509_CRL; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index c9d95459d6..576d2d28f0 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -41,6 +41,7 @@ enum CertType { CERT_TYPE = 0, PRIVATEKEY_TYPE, DH_PARAM_TYPE, + DSA_PARAM_TYPE, CRL_TYPE, CA_TYPE, ECC_PRIVATEKEY_TYPE, @@ -157,11 +158,6 @@ typedef struct Cert { #endif void* heap; /* heap hint */ } Cert; -#endif /* WOLFSSL_CERT_GEN */ - - -#ifdef WOLFSSL_CERT_GEN - /* Initialize and Set Certificate defaults: diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index db12cc9002..409aa81f75 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -94,6 +94,12 @@ WOLFSSL_API int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz); WOLFSSL_API int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz); +WOLFSSL_API int wc_Des3_EcbEncrypt(Des3* des, byte* out, + const byte* in, word32 sz); + +/* ECB decrypt same process as encrypt but with decrypt key */ +#define wc_Des_EcbDecrypt wc_Des_EcbEncrypt +#define wc_Des3_EcbDecrypt wc_Des3_EcbEncrypt WOLFSSL_API int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir); diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index 29bf0abea8..a69bde5c73 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -55,7 +55,18 @@ WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); #define WOLFSSL_STUB(m) \ WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented)) +#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) + /* make these variables global and declare them in logging.c */ + extern volatile char wc_last_error_file[80]; + extern volatile unsigned long wc_last_error_line; + extern volatile unsigned long wc_last_error; + + void WOLFSSL_ERROR_LINE(int err, const char* func, unsigned int line, + const char* file, void* ctx); + #define WOLFSSL_ERROR(x) WOLFSSL_ERROR_LINE((x), __func__, __LINE__, __FILE__,NULL) +#else void WOLFSSL_ERROR(int); +#endif void WOLFSSL_MSG(const char* msg); void WOLFSSL_BUFFER(byte* buffer, word32 length); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 6d9cd060ce..d409165484 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -339,7 +339,8 @@ DYNAMIC_TYPE_SESSION_TICK = 57, DYNAMIC_TYPE_PKCS = 58, DYNAMIC_TYPE_MUTEX = 59, - DYNAMIC_TYPE_PKCS7 = 60 + DYNAMIC_TYPE_PKCS7 = 60, + DYNAMIC_TYPE_ASN1 = 61 }; /* max error buffer string size */