diff --git a/configure.ac b/configure.ac
index dcb57b474..336b3ba27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -190,6 +190,7 @@ then
enable_jni=yes
enable_lighty=yes
enable_stunnel=yes
+ enable_nginx=yes
enable_pwdbased=yes
fi
AM_CONDITIONAL([BUILD_DISTRO], [test "x$ENABLED_DISTRO" = "xyes"])
@@ -268,6 +269,12 @@ AC_ARG_ENABLE([openssh],
[ENABLED_OPENSSH=$enableval],
[ENABLED_OPENSSH=no])
+# nginx compatibility build
+AC_ARG_ENABLE([nginx],
+ [ --enable-nginx Enable nginx (default: disabled)],
+ [ ENABLED_NGINX=$enableval ],
+ [ ENABLED_NGINX=no ]
+ )
# OPENSSL Extra Compatibility
AC_ARG_ENABLE([opensslextra],
@@ -275,7 +282,7 @@ AC_ARG_ENABLE([opensslextra],
[ ENABLED_OPENSSLEXTRA=$enableval ],
[ ENABLED_OPENSSLEXTRA=no ]
)
-if test "$ENABLED_OPENSSH" = "yes"
+if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes"
then
ENABLED_OPENSSLEXTRA="yes"
fi
@@ -761,6 +768,11 @@ AC_ARG_ENABLE([sessioncerts],
[ ENABLED_SESSIONCERTS=no ]
)
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_SESSIONCERTS=yes
+fi
+
if test "$ENABLED_SESSIONCERTS" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS"
@@ -870,7 +882,7 @@ AC_ARG_ENABLE([dsa],
[ ENABLED_DSA=no ]
)
-if test "$ENABLED_OPENSSH" = "yes"
+if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes"
then
ENABLED_DSA="yes"
fi
@@ -912,7 +924,7 @@ then
ENABLED_ECC=no
fi
-if test "$ENABLED_OPENSSH" = "yes"
+if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes"
then
ENABLED_ECC="yes"
fi
@@ -1689,6 +1701,11 @@ AC_ARG_ENABLE([ocsp],
[ ENABLED_OCSP=no ],
)
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_OCSP=yes
+fi
+
if test "$ENABLED_OCSP" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_OCSP"
@@ -1718,6 +1735,11 @@ AC_ARG_ENABLE([ocspstapling],
[ ENABLED_CERTIFICATE_STATUS_REQUEST=no ]
)
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_CERTIFICATE_STATUS_REQUEST=yes
+fi
+
if test "x$ENABLED_CERTIFICATE_STATUS_REQUEST" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_CERTIFICATE_STATUS_REQUEST"
@@ -1740,6 +1762,11 @@ AC_ARG_ENABLE([ocspstapling2],
[ ENABLED_CERTIFICATE_STATUS_REQUEST_V2=no ]
)
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_CERTIFICATE_STATUS_REQUEST_V2=yes
+fi
+
if test "x$ENABLED_CERTIFICATE_STATUS_REQUEST_V2" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_CERTIFICATE_STATUS_REQUEST_V2"
@@ -1762,6 +1789,12 @@ AC_ARG_ENABLE([crl],
[ ENABLED_CRL=no ],
)
+
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_CRL=yes
+fi
+
if test "$ENABLED_CRL" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL"
@@ -2034,6 +2067,11 @@ AC_ARG_ENABLE([session-ticket],
[ ENABLED_SESSION_TICKET=no ]
)
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_SESSION_TICKET=yes
+fi
+
if test "x$ENABLED_SESSION_TICKET" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SESSION_TICKET"
@@ -2058,6 +2096,11 @@ AC_ARG_ENABLE([tlsx],
[ ENABLED_TLSX=no ]
)
+if test "x$ENABLED_NGINX" = "xyes"
+then
+ ENABLED_TLSX=yes
+fi
+
if test "x$ENABLED_TLSX" = "xyes"
then
ENABLED_SNI=yes
@@ -2302,6 +2345,16 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE_LIGHTY -DHAVE_WOLFSSL_SSL_H=1"
fi
+if test "$ENABLED_NGINX" = "yes"
+then
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NGINX"
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_VERIFY_CB"
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_KEEP_SNI"
+ AM_CFLAGS="$AM_CFLAGS -DKEEP_OUR_CERT -DKEEP_PEER_CERT"
+ AM_CFLAGS="$AM_CFLAGS -DHAVE_EXT_CACHE -DOPENSSL_ERR_ONE -DHAVE_EX_DATA"
+fi
+
+
# stunnel Support
AC_ARG_ENABLE([stunnel],
[ --enable-stunnel Enable stunnel (default: disabled)],
@@ -2374,7 +2427,7 @@ then
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_STUNNEL -DWOLFSSL_ALWAYS_VERIFY_CB"
- AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_KEEP_SNI"
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_KEEP_SNI -DHAVE_EX_DATA"
fi
if test "$ENABLED_PSK" = "no" && test "$ENABLED_LEANPSK" = "no" \
@@ -3352,6 +3405,7 @@ echo " * MEMORY: $ENABLED_MEMORY"
echo " * I/O POOL: $ENABLED_IOPOOL"
echo " * LIGHTY: $ENABLED_LIGHTY"
echo " * STUNNEL: $ENABLED_STUNNEL"
+echo " * NGINX: $ENABLED_NGINX"
echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS"
echo " * DTLS: $ENABLED_DTLS"
echo " * SCTP: $ENABLED_SCTP"
diff --git a/examples/server/server.c b/examples/server/server.c
index 13bf57918..0769207df 100644
--- a/examples/server/server.c
+++ b/examples/server/server.c
@@ -74,7 +74,19 @@
int myHsDoneCb(WOLFSSL* ssl, void* user_ctx);
#endif
-
+static const char webServerMsg[] =
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: text/html\n"
+ "Connection: close\n"
+ "\n"
+ "\n"
+ "
\n"
+ "Welcome to wolfSSL!\n"
+ "\n"
+ "\n"
+ "wolfSSL has successfully performed handshake!
\n"
+ "\n"
+ "\n";
static int NonBlockingSSL_Accept(SSL* ssl)
{
@@ -253,6 +265,8 @@ static void Usage(void)
#ifdef HAVE_WNR
printf("-q Whitewood config file, default %s\n", wnrConfig);
#endif
+ printf("-g Return basic HTML web page\n");
+ printf("-C The number of connections to accept, default: 1\n");
}
THREAD_RETURN CYASSL_THREAD server_test(void* args)
@@ -269,6 +283,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#else
const char msg[] = "I hear you fa shizzle!\n";
#endif
+ int useWebServerMsg = 0;
char input[80];
int ch;
int version = SERVER_DEFAULT_VERSION;
@@ -290,7 +305,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
int wc_shutdown = 0;
int resume = 0;
int resumeCount = 0;
- int loopIndefinitely = 0;
+ int loops = 1;
int echoData = 0;
int throughput = 0;
int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
@@ -376,7 +391,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
useAnyAddr = 1;
#else
while ((ch = mygetopt(argc, argv,
- "?jdbstnNuGfrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) {
+ "?jdbstnNuGfrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:gC:")) != -1) {
switch (ch) {
case '?' :
Usage();
@@ -541,7 +556,15 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
break;
case 'i' :
- loopIndefinitely = 1;
+ loops = -1;
+ break;
+
+ case 'C' :
+ loops = atoi(myoptarg);
+ if (loops <= 0) {
+ Usage();
+ exit(MY_EX_USAGE);
+ }
break;
case 'e' :
@@ -568,6 +591,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#endif
break;
+ case 'g' :
+ useWebServerMsg = 1;
+ break;
+
default:
Usage();
exit(MY_EX_USAGE);
@@ -1096,8 +1123,15 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
err_sys("SSL_read failed");
}
- if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
- err_sys("SSL_write failed");
+ if (!useWebServerMsg) {
+ if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
+ err_sys("SSL_write failed");
+ }
+ else {
+ if (SSL_write(ssl, webServerMsg, sizeof(webServerMsg))
+ != sizeof(webServerMsg))
+ err_sys("SSL_write failed");
+ }
}
else {
ServerEchoData(ssl, clientfd, echoData, throughput);
@@ -1139,7 +1173,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
}
resumeCount = 0;
- if(!loopIndefinitely) {
+ if (loops > 0 && --loops == 0) {
break; /* out of while loop, done with normal and resume option */
}
} /* while(1) */
diff --git a/src/internal.c b/src/internal.c
index 3c5f39c7f..10971d58b 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -105,7 +105,7 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
#if !defined(NO_RSA) || defined(HAVE_ECC)
static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32);
#endif
- #ifdef HAVE_STUNNEL
+ #if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
static int SNI_Callback(WOLFSSL* ssl);
#endif
#ifdef WOLFSSL_DTLS
@@ -1452,13 +1452,30 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
FreeDer(&ctx->privateKey);
FreeDer(&ctx->certificate);
#ifdef KEEP_OUR_CERT
- FreeX509(ctx->ourCert);
- if (ctx->ourCert) {
+ if (ctx->ourCert && ctx->ownOurCert) {
+ FreeX509(ctx->ourCert);
XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
}
#endif /* KEEP_OUR_CERT */
FreeDer(&ctx->certChain);
wolfSSL_CertManagerFree(ctx->cm);
+ #ifdef OPENSSL_EXTRA
+ while (ctx->ca_names != NULL) {
+ WOLFSSL_STACK *next = ctx->ca_names->next;
+ wolfSSL_X509_NAME_free(ctx->ca_names->data.name);
+ XFREE(ctx->ca_names->data.name, NULL, DYNAMIC_TYPE_OPENSSL);
+ XFREE(ctx->ca_names, NULL, DYNAMIC_TYPE_OPENSSL);
+ ctx->ca_names = next;
+ }
+ #endif
+ #ifdef WOLFSSL_NGINX
+ while (ctx->x509Chain != NULL) {
+ WOLFSSL_STACK *next = ctx->x509Chain->next;
+ wolfSSL_X509_free(ctx->x509Chain->data.x509);
+ XFREE(ctx->x509Chain, NULL, DYNAMIC_TYPE_OPENSSL);
+ ctx->x509Chain = next;
+ }
+ #endif
#endif /* !NO_CERTS */
#ifdef HAVE_TLS_EXTENSIONS
@@ -3079,8 +3096,15 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer)
keySz = peer->dp->size;
}
- /* TODO: Implement _ex version here */
- ret = wc_ecc_make_key(ssl->rng, keySz, key);
+ if (ssl->ecdhCurveOID > 0) {
+ ret = wc_ecc_make_key_ex(ssl->rng, keySz, key,
+ wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL));
+ }
+ else {
+ ret = wc_ecc_make_key(ssl->rng, keySz, key);
+ if (ret == 0)
+ ssl->ecdhCurveOID = key->dp->oidSum;
+ }
/* Handle async pending response */
#if defined(WOLFSSL_ASYNC_CRYPT)
@@ -3212,17 +3236,19 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#ifdef HAVE_ECC
ssl->eccTempKeySz = ctx->eccTempKeySz;
ssl->pkCurveOID = ctx->pkCurveOID;
+ ssl->ecdhCurveOID = ctx->ecdhCurveOID;
#endif
+#ifdef OPENSSL_EXTRA
+ ssl->options.mask = ctx->mask;
+#endif
ssl->timeout = ctx->timeout;
ssl->verifyCallback = ctx->verifyCallback;
ssl->options.side = ctx->method->side;
ssl->options.downgrade = ctx->method->downgrade;
ssl->options.minDowngrade = ctx->minDowngrade;
- if (ssl->options.side == WOLFSSL_SERVER_END)
- ssl->options.haveDH = ctx->haveDH;
-
+ ssl->options.haveDH = ctx->haveDH;
ssl->options.haveNTRU = ctx->haveNTRU;
ssl->options.haveECDSAsig = ctx->haveECDSAsig;
ssl->options.haveECC = ctx->haveECC;
@@ -3249,6 +3275,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
+#ifdef HAVE_EXT_CACHE
+ ssl->options.internalCacheOff = ctx->internalCacheOff;
+#endif
ssl->options.verifyPeer = ctx->verifyPeer;
ssl->options.verifyNone = ctx->verifyNone;
@@ -3261,10 +3290,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
ssl->options.groupMessages = ctx->groupMessages;
#ifndef NO_DH
- if (ssl->options.side == WOLFSSL_SERVER_END) {
- ssl->buffers.serverDH_P = ctx->serverDH_P;
- ssl->buffers.serverDH_G = ctx->serverDH_G;
- }
+ ssl->buffers.serverDH_P = ctx->serverDH_P;
+ ssl->buffers.serverDH_G = ctx->serverDH_G;
#endif
#ifndef NO_CERTS
@@ -3491,6 +3518,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#endif
#ifdef HAVE_ALPN
ssl->alpn_client_list = NULL;
+ #ifdef WOLFSSL_NGINX
+ ssl->alpnSelect = ctx->alpnSelect;
+ ssl->alpnSelectArg = ctx->alpnSelectArg;
+ #endif
#endif
#ifdef HAVE_SUPPORTED_CURVES
ssl->options.userCurves = ctx->userCurves;
@@ -3805,6 +3836,9 @@ void SSL_ResourceFree(WOLFSSL* ssl)
ssl->session.ticketLen = 0;
}
#endif
+#ifdef HAVE_EXT_CACHE
+ wolfSSL_SESSION_free(ssl->extSession);
+#endif
#ifdef WOLFSSL_STATIC_MEMORY
/* check if using fixed io buffers and free them */
@@ -6234,6 +6268,78 @@ static int CheckAltNames(DecodedCert* dCert, char* domain)
}
+#ifdef OPENSSL_EXTRA
+/* Check that alternative names, if they exists, match the domain.
+ * Fail if there are wild patterns and they didn't match.
+ * Check the common name if no alternative names matched.
+ *
+ * dCert Decoded cert to get the alternative names from.
+ * domain Domain name to compare against.
+ * checkCN Whether to check the common name.
+ * returns whether there was a problem in matching.
+ */
+static int CheckForAltNames(DecodedCert* dCert, char* domain, int* checkCN)
+{
+ int match;
+ DNS_entry* altName = NULL;
+
+ WOLFSSL_MSG("Checking AltNames");
+
+ if (dCert)
+ altName = dCert->altNames;
+
+ *checkCN = altName == NULL;
+ match = 0;
+ while (altName) {
+ WOLFSSL_MSG("\tindividual AltName check");
+
+ if (MatchDomainName(altName->name, (int)XSTRLEN(altName->name),
+ domain)) {
+ match = 1;
+ *checkCN = 0;
+ break;
+ }
+ /* No matches and wild pattern match failed. */
+ else if (altName->name[0] == '*' && match == 0)
+ match = -1;
+
+ altName = altName->next;
+ }
+
+ return match != -1;
+}
+
+/* Check the domain name matches the subject alternative name or the subject
+ * name.
+ *
+ * dcert Decoded certificate.
+ * domainName The domain name.
+ * domainNameLen The length of the domain name.
+ * returns DOMAIN_NAME_MISMATCH when no match found and 0 on success.
+ */
+int CheckHostName(DecodedCert* dCert, char *domainName, size_t domainNameLen)
+{
+ int checkCN;
+
+ /* Assume name is NUL terminated. */
+ (void)domainNameLen;
+
+ if (CheckForAltNames(dCert, domainName, &checkCN) == 0) {
+ WOLFSSL_MSG("DomainName match on alt names failed too");
+ return DOMAIN_NAME_MISMATCH;
+ }
+ if (checkCN == 1) {
+ if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
+ domainName) == 0) {
+ WOLFSSL_MSG("DomainName match on common name failed");
+ return DOMAIN_NAME_MISMATCH;
+ }
+ }
+
+ return 0;
+}
+#endif
+
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
/* Copy parts X509 needs from Decoded cert, 0 on success */
@@ -6662,6 +6768,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
}
else if (ret != 0) {
WOLFSSL_MSG("Failed to verify CA from chain");
+ #ifdef OPENSSL_EXTRA
+ ssl->peerVerifyRet = X509_V_ERR_INVALID_CA;
+ #endif
}
else {
WOLFSSL_MSG("Verified CA from chain and already had it");
@@ -6746,6 +6855,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
}
else {
WOLFSSL_MSG("Failed to verify Peer's cert");
+ #ifdef OPENSSL_EXTRA
+ ssl->peerVerifyRet = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
+ #endif
if (ssl->verifyCallback) {
WOLFSSL_MSG("\tCallback override available, will continue");
fatal = 0;
@@ -6808,6 +6920,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (ret != 0) {
WOLFSSL_MSG("\tOCSP Lookup not ok");
fatal = 0;
+ #ifdef OPENSSL_EXTRA
+ ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
+ #endif
}
}
#endif /* HAVE_OCSP */
@@ -6819,6 +6934,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (ret != 0) {
WOLFSSL_MSG("\tCRL check not ok");
fatal = 0;
+ #ifdef OPENSSL_EXTRA
+ ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
+ #endif
}
}
#endif /* HAVE_CRL */
@@ -7086,7 +7204,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#else
store->current_cert = NULL;
#endif
-#if defined(HAVE_FORTRESS) || defined(HAVE_STUNNEL)
+#if defined(HAVE_EX_DATA) || defined(HAVE_FORTRESS)
store->ex_data = ssl;
#endif
ok = ssl->verifyCallback(0, store);
@@ -7242,10 +7360,15 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
InitOcspResponse(response, status, input +*inOutIdx, status_length);
- if ((OcspResponseDecode(response, ssl->ctx->cm, ssl->heap) != 0)
- || (response->responseStatus != OCSP_SUCCESSFUL)
- || (response->status->status != CERT_GOOD)
- || (CompareOcspReqResp(request, response) != 0))
+ if (OcspResponseDecode(response, ssl->ctx->cm, ssl->heap) != 0)
+ ret = BAD_CERTIFICATE_STATUS_ERROR;
+ else if (CompareOcspReqResp(request, response) != 0)
+ ret = BAD_CERTIFICATE_STATUS_ERROR;
+ else if (response->responseStatus != OCSP_SUCCESSFUL)
+ ret = BAD_CERTIFICATE_STATUS_ERROR;
+ else if (response->status->status == CERT_REVOKED)
+ ret = OCSP_CERT_REVOKED;
+ else if (response->status->status != CERT_GOOD)
ret = BAD_CERTIFICATE_STATUS_ERROR;
*inOutIdx += status_length;
@@ -10990,6 +11113,9 @@ int SendCertificateStatus(WOLFSSL* ssl)
}
if (ret == 0) {
+ #ifdef WOLFSSL_NGINX
+ request->ssl = ssl;
+ #endif
ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request,
&response);
@@ -11088,6 +11214,9 @@ int SendCertificateStatus(WOLFSSL* ssl)
}
if (ret == 0) {
+ #ifdef WOLFSSL_NGINX
+ request->ssl = ssl;
+ #endif
ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request,
&responses[0]);
@@ -11160,6 +11289,9 @@ int SendCertificateStatus(WOLFSSL* ssl)
&ssl->ctx->cm->ocsp_stapling->ocspLock);
}
+ #ifdef WOLFSSL_NGINX
+ request->ssl = ssl;
+ #endif
ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
request, &responses[i + 1]);
@@ -11185,6 +11317,9 @@ int SendCertificateStatus(WOLFSSL* ssl)
else {
while (ret == 0 &&
NULL != (request = ssl->ctx->chainOcspRequest[i])) {
+ #ifdef WOLFSSL_NGINX
+ request->ssl = ssl;
+ #endif
ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
request, &responses[++i]);
@@ -13276,7 +13411,8 @@ int SetCipherList(Suites* suites, const char* list)
return 0;
}
- if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0)
+ if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0 ||
+ XSTRNCMP(next, "DEFAULT", 7) == 0)
return 1; /* wolfSSL defualt */
do {
@@ -14458,6 +14594,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
if ((curveOid = CheckCurveId(b)) < 0) {
ERROR_OUT(ECC_CURVE_ERROR, exit_dske);
}
+ ssl->ecdhCurveOID = curveOid;
length = input[idx++];
if ((idx - begin) + length > size) {
@@ -17029,6 +17166,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
idx += RAN_LEN;
output[idx++] = sessIdSz;
XMEMCPY(ssl->arrays->sessionID, output + idx, sessIdSz);
+ ssl->arrays->sessionIDSz = sessIdSz;
}
else {
/* If resuming, use info from SSL */
@@ -17344,6 +17482,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
}
+ ssl->options.dhKeySz =
+ (word16)ssl->buffers.serverDH_P.length;
+
ret = DhGenKeyPair(ssl,
ssl->buffers.serverDH_P.buffer,
ssl->buffers.serverDH_P.length,
@@ -18844,6 +18985,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_MSG("Session lookup for resume failed");
ssl->options.resuming = 0;
} else {
+ #ifdef HAVE_EXT_CACHE
+ wolfSSL_SESSION_free(session);
+ #endif
if (MatchSuite(ssl, &clSuites) < 0) {
WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
return UNSUPPORTED_SUITE;
@@ -19207,9 +19351,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if ((ret = TLSX_Parse(ssl, (byte *) input + i,
totalExtSz, 1, &clSuites)))
return ret;
-#ifdef HAVE_STUNNEL
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
if((ret=SNI_Callback(ssl)))
return ret;
+ ssl->options.side = WOLFSSL_SERVER_END;
#endif /*HAVE_STUNNEL*/
i += totalExtSz;
@@ -19294,8 +19439,14 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
"using EMS");
return EXT_MASTER_SECRET_NEEDED_E;
}
+#ifdef HAVE_EXT_CACHE
+ wolfSSL_SESSION_free(session);
+#endif
}
else {
+#ifdef HAVE_EXT_CACHE
+ wolfSSL_SESSION_free(session);
+#endif
if (MatchSuite(ssl, &clSuites) < 0) {
WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
return UNSUPPORTED_SUITE;
@@ -20893,7 +21044,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
-#ifdef HAVE_STUNNEL
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
static int SNI_Callback(WOLFSSL* ssl)
{
/* Stunnel supports a custom sni callback to switch an SSL's ctx
diff --git a/src/ocsp.c b/src/ocsp.c
index 7b69ab466..4eff1582c 100644
--- a/src/ocsp.c
+++ b/src/ocsp.c
@@ -244,6 +244,135 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
return ret;
}
+/* Check that the response for validity. Store result in status.
+ *
+ * ocsp Context object for OCSP status.
+ * response OCSP response message data.
+ * responseSz Length of OCSP response message data.
+ * reponseBuffer Buffer object to return the response with.
+ * status The certificate status object.
+ * entry The OCSP entry for this certificate.
+ * returns OCSP_LOOKUP_FAIL when the response is bad and 0 otherwise.
+ */
+static int CheckResponse(WOLFSSL_OCSP* ocsp, byte* response, int responseSz,
+ buffer* responseBuffer, CertStatus* status,
+ OcspEntry* entry, OcspRequest* ocspRequest)
+{
+#ifdef WOLFSSL_SMALL_STACK
+ CertStatus* newStatus;
+ OcspResponse* ocspResponse;
+#else
+ CertStatus newStatus[1];
+ OcspResponse ocspResponse[1];
+#endif
+ int ret;
+ int validated = 0; /* ocsp validation flag */
+
+#ifdef WOLFSSL_SMALL_STACK
+ newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+
+ if (newStatus == NULL || ocspResponse == NULL) {
+ if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ XFREE(request, NULL, DYNAMIC_TYPE_OCSP);
+
+ WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
+ return MEMORY_E;
+ }
+#endif
+ XMEMSET(newStatus, 0, sizeof(CertStatus));
+
+ InitOcspResponse(ocspResponse, newStatus, response, responseSz);
+ ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap);
+ if (ret != 0) {
+ WOLFSSL_MSG("OcspResponseDecode failed");
+ goto end;
+ }
+
+ if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
+ WOLFSSL_MSG("OcspResponse status bad");
+ goto end;
+ }
+ if (ocspRequest != NULL) {
+ ret = CompareOcspReqResp(ocspRequest, ocspResponse);
+ if (ret != 0) {
+ goto end;
+ }
+ }
+
+ if (responseBuffer) {
+ responseBuffer->buffer = (byte*)XMALLOC(responseSz, ocsp->cm->heap,
+ DYNAMIC_TYPE_TMP_BUFFER);
+
+ if (responseBuffer->buffer) {
+ responseBuffer->length = responseSz;
+ XMEMCPY(responseBuffer->buffer, response, responseSz);
+ }
+ }
+
+ ret = xstat2err(ocspResponse->status->status);
+ if (ret == 0) {
+ validated = 1;
+ }
+
+ if (wc_LockMutex(&ocsp->ocspLock) != 0) {
+ ret = BAD_MUTEX_E;
+ goto end;
+ }
+
+ if (status != NULL) {
+ if (status->rawOcspResponse) {
+ XFREE(status->rawOcspResponse, ocsp->cm->heap,
+ DYNAMIC_TYPE_OCSP_STATUS);
+ }
+
+ /* Replace existing certificate entry with updated */
+ XMEMCPY(status, newStatus, sizeof(CertStatus));
+ }
+ else {
+ /* Save new certificate entry */
+ status = (CertStatus*)XMALLOC(sizeof(CertStatus),
+ ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
+ if (status != NULL) {
+ XMEMCPY(status, newStatus, sizeof(CertStatus));
+ status->next = entry->status;
+ entry->status = status;
+ entry->totalStatus++;
+ }
+ }
+
+ if (status && responseBuffer && responseBuffer->buffer) {
+ status->rawOcspResponse = (byte*)XMALLOC(responseBuffer->length,
+ ocsp->cm->heap,
+ DYNAMIC_TYPE_OCSP_STATUS);
+
+ if (status->rawOcspResponse) {
+ status->rawOcspResponseSz = responseBuffer->length;
+ XMEMCPY(status->rawOcspResponse, responseBuffer->buffer,
+ responseBuffer->length);
+ }
+ }
+
+ wc_UnLockMutex(&ocsp->ocspLock);
+
+end:
+ if (ret == 0 && validated == 1) {
+ WOLFSSL_MSG("New OcspResponse validated");
+ } else if (ret != OCSP_CERT_REVOKED) {
+ ret = OCSP_LOOKUP_FAIL;
+ }
+
+#ifdef WOLFSSL_SMALL_STACK
+ XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+ return ret;
+}
+
/* 0 on success */
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
buffer* responseBuffer)
@@ -257,15 +386,6 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
const char* url = NULL;
int urlSz = 0;
int ret = -1;
- int validated = 0; /* ocsp validation flag */
-
-#ifdef WOLFSSL_SMALL_STACK
- CertStatus* newStatus;
- OcspResponse* ocspResponse;
-#else
- CertStatus newStatus[1];
- OcspResponse ocspResponse[1];
-#endif
WOLFSSL_ENTER("CheckOcspRequest");
@@ -282,6 +402,22 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
if (ret != OCSP_INVALID_STATUS)
return ret;
+#ifdef WOLFSSL_NGINX
+ if (ocsp->statusCb != NULL && ocspRequest->ssl != NULL) {
+ ret = ocsp->statusCb((WOLFSSL*)ocspRequest->ssl, NULL);
+ if (ret == 0) {
+ ret = wolfSSL_get_ocsp_response((WOLFSSL*)ocspRequest->ssl,
+ &response);
+ ret = CheckResponse(ocsp, response, ret, responseBuffer, status,
+ entry, NULL);
+ if (response != NULL)
+ XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
+ return ret;
+ }
+ return OCSP_LOOKUP_FAIL;
+ }
+#endif
+
if (ocsp->cm->ocspUseOverrideURL) {
url = ocsp->cm->ocspOverrideURL;
if (url != NULL && url[0] != '\0')
@@ -304,120 +440,373 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
return MEMORY_ERROR;
}
-#ifdef WOLFSSL_SMALL_STACK
- newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
- DYNAMIC_TYPE_TMP_BUFFER);
- ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
- DYNAMIC_TYPE_TMP_BUFFER);
-
- if (newStatus == NULL || ocspResponse == NULL) {
- if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-
- XFREE(request, NULL, DYNAMIC_TYPE_OCSP);
-
- WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
- return MEMORY_E;
- }
-#endif
-
requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);
if (requestSz > 0 && ocsp->cm->ocspIOCb) {
responseSz = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
request, requestSz, &response);
}
+ XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
+
if (responseSz >= 0 && response) {
- XMEMSET(newStatus, 0, sizeof(CertStatus));
-
- InitOcspResponse(ocspResponse, newStatus, response, responseSz);
- if (OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap) != 0) {
- WOLFSSL_MSG("OcspResponseDecode failed");
- }
- else if (ocspResponse->responseStatus != OCSP_SUCCESSFUL) {
- WOLFSSL_MSG("OcspResponse status bad");
- }
- else {
- if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
- if (responseBuffer) {
- responseBuffer->buffer = (byte*)XMALLOC(responseSz,
- ocsp->cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
-
- if (responseBuffer->buffer) {
- responseBuffer->length = responseSz;
- XMEMCPY(responseBuffer->buffer, response, responseSz);
- }
- }
-
- /* only way to get to good state */
- ret = xstat2err(ocspResponse->status->status);
- if (ret == 0) {
- validated = 1;
- }
-
- if (wc_LockMutex(&ocsp->ocspLock) != 0)
- ret = BAD_MUTEX_E;
- else {
- if (status != NULL) {
- if (status->rawOcspResponse)
- XFREE(status->rawOcspResponse, ocsp->cm->heap,
- DYNAMIC_TYPE_OCSP_STATUS);
-
- /* Replace existing certificate entry with updated */
- XMEMCPY(status, newStatus, sizeof(CertStatus));
- }
- else {
- /* Save new certificate entry */
- status = (CertStatus*)XMALLOC(sizeof(CertStatus),
- ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);
- if (status != NULL) {
- XMEMCPY(status, newStatus, sizeof(CertStatus));
- status->next = entry->status;
- entry->status = status;
- entry->totalStatus++;
- }
- }
-
- if (status && responseBuffer && responseBuffer->buffer) {
- status->rawOcspResponse = (byte*)XMALLOC(
- responseBuffer->length,
- ocsp->cm->heap,
- DYNAMIC_TYPE_OCSP_STATUS);
-
- if (status->rawOcspResponse) {
- status->rawOcspResponseSz = responseBuffer->length;
- XMEMCPY(status->rawOcspResponse,
- responseBuffer->buffer,
- responseBuffer->length);
- }
- }
-
- wc_UnLockMutex(&ocsp->ocspLock);
- }
- }
- }
+ ret = CheckResponse(ocsp, response, responseSz, responseBuffer, status,
+ entry, ocspRequest);
}
-#ifdef WOLFSSL_SMALL_STACK
- XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-#endif
-
- XFREE(request, NULL, DYNAMIC_TYPE_OCSP);
-
if (response != NULL && ocsp->cm->ocspRespFreeCb)
ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, response);
- if (ret == 0 && validated == 1) {
- WOLFSSL_MSG("New OcspResponse validated");
- } else {
- ret = OCSP_LOOKUP_FAIL;
- }
-
WOLFSSL_LEAVE("CheckOcspRequest", ret);
return ret;
}
+#ifdef WOLFSSL_NGINX
+
+int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
+ WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
+ WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
+ WOLFSSL_ASN1_TIME** nextupd)
+{
+ if (bs == NULL || id == NULL)
+ return SSL_FAILURE;
+
+ /* Only supporting one certificate status in asn.c. */
+ if (CompareOcspReqResp(id, bs) != 0)
+ return SSL_FAILURE;
+
+ if (status != NULL)
+ *status = bs->status->status;
+ if (thisupd != NULL)
+ *thisupd = (WOLFSSL_ASN1_TIME*)bs->status->thisDateAsn;
+ if (nextupd != NULL)
+ *nextupd = (WOLFSSL_ASN1_TIME*)bs->status->nextDateAsn;
+
+ /* TODO: Not needed for Nginx. */
+ if (reason != NULL)
+ *reason = 0;
+ if (revtime != NULL)
+ *revtime = NULL;
+
+ return SSL_SUCCESS;
+}
+
+const char *wolfSSL_OCSP_cert_status_str(long s)
+{
+ switch (s) {
+ case CERT_GOOD:
+ return "good";
+ case CERT_REVOKED:
+ return "revoked";
+ case CERT_UNKNOWN:
+ return "unknown";
+ default:
+ return "(UNKNOWN)";
+ }
+}
+
+int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
+ WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
+{
+ (void)thisupd;
+ (void)nextupd;
+ (void)sec;
+ (void)maxsec;
+ /* Dates validated in DecodeSingleResponse. */
+ return SSL_SUCCESS;
+}
+
+void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
+{
+ FreeOcspRequest(certId);
+ XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
+ const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
+ const WOLFSSL_X509 *issuer)
+{
+ WOLFSSL_OCSP_CERTID* certId;
+ DecodedCert cert;
+ WOLFSSL_CERT_MANAGER* cm;
+ int ret;
+ DerBuffer* derCert = NULL;
+
+ (void)dgst;
+
+ cm = wolfSSL_CertManagerNew();
+ if (cm == NULL)
+ return NULL;
+
+
+ ret = AllocDer(&derCert, issuer->derCert->length,
+ issuer->derCert->type, NULL);
+ if (ret == 0) {
+ /* AddCA() frees the buffer. */
+ XMEMCPY(derCert->buffer, issuer->derCert->buffer,
+ issuer->derCert->length);
+ AddCA(cm, &derCert, WOLFSSL_USER_CA, 1);
+ }
+
+ certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (certId != NULL) {
+ InitDecodedCert(&cert, subject->derCert->buffer,
+ subject->derCert->length, NULL);
+ if (ParseCertRelative(&cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) {
+ XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
+ certId = NULL;
+ }
+ else
+ InitOcspRequest(certId, &cert, 0, NULL);
+ FreeDecodedCert(&cert);
+ }
+
+ wolfSSL_CertManagerFree(cm);
+
+ return certId;
+}
+
+void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
+{
+ wolfSSL_OCSP_RESPONSE_free(basicResponse);
+}
+
+/* Signature verified in DecodeBasicOcspResponse.
+ * But no store available to verify certificate. */
+int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
+ STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
+{
+ DecodedCert cert;
+ int ret = SSL_SUCCESS;
+
+ (void)certs;
+
+ if (flags & OCSP_NOVERIFY)
+ return SSL_SUCCESS;
+
+ InitDecodedCert(&cert, bs->cert, bs->certSz, NULL);
+ if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0)
+ ret = SSL_FAILURE;
+ FreeDecodedCert(&cert);
+
+ return ret;
+}
+
+void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
+{
+ if (response->status != NULL)
+ XFREE(response->status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (response->source != NULL)
+ XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL);
+}
+
+OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
+ OcspResponse** response)
+{
+ byte* data;
+ byte* p;
+ int len;
+ int dataAlloced = 0;
+ OcspResponse* ret;
+
+ if (bio == NULL)
+ return NULL;
+
+ if (bio->type == BIO_MEMORY) {
+ len = wolfSSL_BIO_get_mem_data(bio, &data);
+ if (len <= 0 || data == NULL) {
+ return NULL;
+ }
+ }
+ else if (bio->type == BIO_FILE) {
+ long i;
+ long l;
+
+ i = XFTELL(bio->file);
+ XFSEEK(bio->file, 0, SEEK_END);
+ l = XFTELL(bio->file);
+ XFSEEK(bio->file, i, SEEK_SET);
+ data = (byte*)XMALLOC(l - i, 0, DYNAMIC_TYPE_TMP_BUFFER);
+ if (data == NULL)
+ return NULL;
+ dataAlloced = 1;
+
+ len = wolfSSL_BIO_read(bio, (char *)data, (int)l);
+ }
+ else
+ return NULL;
+
+ p = data;
+ ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p, len);
+
+ if (dataAlloced)
+ XFREE(data, 0, DYNAMIC_TYPE_TMP_BUFFER);
+
+ return ret;
+}
+
+OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
+ const unsigned char** data, int len)
+{
+ OcspResponse *resp = NULL;
+ word32 idx = 0;
+ int length = 0;
+
+ if (data == NULL)
+ return NULL;
+
+ if (response != NULL)
+ resp = *response;
+ if (resp == NULL) {
+ resp = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (resp == NULL)
+ return NULL;
+ XMEMSET(resp, 0, sizeof(OcspResponse));
+ }
+
+ resp->source = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (resp->source == NULL) {
+ XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL);
+ return NULL;
+ }
+ resp->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (resp->status == NULL) {
+ XFREE(resp->source, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(resp, NULL, DYNAMIC_TYPE_OPENSSL);
+ return NULL;
+ }
+
+ XMEMCPY(resp->source, *data, len);
+ resp->maxIdx = len;
+
+ if (OcspResponseDecode(resp, NULL, NULL) != 0) {
+ wolfSSL_OCSP_RESPONSE_free(resp);
+ return NULL;
+ }
+
+ GetSequence(*data, &idx, &length, len);
+ (*data) += idx + length;
+
+ return resp;
+}
+
+int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
+ unsigned char** data)
+{
+ if (data == NULL)
+ return response->maxIdx;
+
+ XMEMCPY(*data, response->source, response->maxIdx);
+ return response->maxIdx;
+}
+
+int wolfSSL_OCSP_response_status(OcspResponse *response)
+{
+ return response->responseStatus;
+}
+
+const char *wolfSSL_OCSP_response_status_str(long s)
+{
+ switch (s) {
+ case OCSP_SUCCESSFUL:
+ return "successful";
+ case OCSP_MALFORMED_REQUEST:
+ return "malformedrequest";
+ case OCSP_INTERNAL_ERROR:
+ return "internalerror";
+ case OCSP_TRY_LATER:
+ return "trylater";
+ case OCSP_SIG_REQUIRED:
+ return "sigrequired";
+ case OCSP_UNAUTHROIZED:
+ return "unauthorized";
+ default:
+ return "(UNKNOWN)";
+ }
+}
+
+WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
+{
+ WOLFSSL_OCSP_BASICRESP* bs;
+
+ bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (bs == NULL)
+ return NULL;
+
+ XMEMCPY(bs, response, sizeof(OcspResponse));
+ bs->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (bs->status == NULL || bs->source == NULL) {
+ wolfSSL_OCSP_RESPONSE_free(bs);
+ bs = NULL;
+ }
+ XMEMCPY(bs->status, response->status, sizeof(CertStatus));
+ XMEMCPY(bs->source, response->source, response->maxIdx);
+ return bs;
+}
+
+OcspRequest* wolfSSL_OCSP_REQUEST_new(void)
+{
+ OcspRequest* request;
+
+ request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (request != NULL)
+ XMEMSET(request, 0, sizeof(OcspRequest));
+
+ return request;
+}
+
+void wolfSSL_OCSP_REQUEST_free(OcspRequest* request)
+{
+ FreeOcspRequest(request);
+ XFREE(request, 0, DYNAMIC_TYPE_OPENSSL);
+}
+
+int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data)
+{
+ word32 size;
+
+ size = EncodeOcspRequest(request, NULL, 0);
+ if (size <= 0 || data == NULL)
+ return size;
+
+ return EncodeOcspRequest(request, *data, size);
+}
+
+WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
+ WOLFSSL_OCSP_CERTID *cid)
+{
+ if (req == NULL || cid == NULL)
+ return NULL;
+
+ FreeOcspRequest(req);
+ XMEMCPY(req, cid, sizeof(OcspRequest));
+
+ if (cid->serial != NULL) {
+ req->serial = (byte*)XMALLOC(cid->serialSz, NULL,
+ DYNAMIC_TYPE_OCSP_REQUEST);
+ req->url = (byte*)XMALLOC(cid->urlSz, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
+ if (req->serial == NULL || req->url == NULL) {
+ FreeOcspRequest(req);
+ return NULL;
+ }
+
+ XMEMCPY(req->serial, cid->serial, cid->serialSz);
+ XMEMCPY(req->url, cid->url, cid->urlSz);
+ }
+
+ wolfSSL_OCSP_REQUEST_free(cid);
+
+ return req;
+}
+
+#endif
#else /* HAVE_OCSP */
diff --git a/src/ssl.c b/src/ssl.c
index 7b9b3a75d..c32c9be6c 100644
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -529,6 +529,19 @@ int wolfSSL_get_ciphers(char* buf, int len)
return SSL_SUCCESS;
}
+const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
+{
+ const char* cipher;
+
+ if (ssl == NULL)
+ return NULL;
+
+ cipher = wolfSSL_get_cipher_name_from_suite(ssl->options.cipherSuite0,
+ ssl->options.cipherSuite);
+ len = min(len, (int)(XSTRLEN(cipher) + 1));
+ XMEMCPY(buf, cipher, len);
+ return buf;
+}
int wolfSSL_get_fd(const WOLFSSL* ssl)
{
@@ -2250,7 +2263,6 @@ int wolfSSL_GetHmacSize(WOLFSSL* ssl)
#endif /* ATOMIC_USER */
#ifndef NO_CERTS
-
int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
{
int ret = BAD_FUNC_ARG;
@@ -4211,9 +4223,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
else if (ctx) {
FreeDer(&ctx->certificate); /* Make sure previous is free'd */
#ifdef KEEP_OUR_CERT
- FreeX509(ctx->ourCert);
if (ctx->ourCert) {
- XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
+ if (ctx->ownOurCert) {
+ FreeX509(ctx->ourCert);
+ XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
+ }
ctx->ourCert = NULL;
}
#endif
@@ -6644,6 +6658,9 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
session = GetSessionClient(ssl, id, len);
if (session) {
if (SetSession(ssl, session) != SSL_SUCCESS) {
+ #ifdef HAVE_EXT_CACHE
+ wolfSSL_SESSION_free(session);
+ #endif
WOLFSSL_MSG("SetSession failed");
session = NULL;
}
@@ -6656,6 +6673,10 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
}
+ #ifdef HAVE_EXT_CACHE
+ else
+ wolfSSL_SESSION_free(session);
+ #endif
return SSL_SUCCESS;
}
@@ -6983,9 +7004,14 @@ long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
if (mode == SSL_SESS_CACHE_OFF)
ctx->sessionCacheOff = 1;
- if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
+ if ((mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
ctx->sessionCacheFlushOff = 1;
+#ifdef HAVE_EXT_CACHE
+ if ((mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
+ ctx->internalCacheOff = 1;
+#endif
+
return SSL_SUCCESS;
}
@@ -8279,7 +8305,6 @@ int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
#endif /* NO_HANDSHAKE_DONE_CB */
-
int wolfSSL_Cleanup(void)
{
int ret = SSL_SUCCESS;
@@ -8365,6 +8390,8 @@ int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
if (ssl == NULL)
return BAD_FUNC_ARG;
+ if (to == 0)
+ to = WOLFSSL_SESSION_TIMEOUT;
ssl->timeout = to;
return SSL_SUCCESS;
@@ -8377,6 +8404,8 @@ int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
if (ctx == NULL)
return BAD_FUNC_ARG;
+ if (to == 0)
+ to = WOLFSSL_SESSION_TIMEOUT;
ctx->timeout = to;
return SSL_SUCCESS;
@@ -8396,10 +8425,26 @@ WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
WOLFSSL_ENTER("GetSessionClient");
+ if (ssl->ctx->sessionCacheOff)
+ return NULL;
+
if (ssl->options.side == WOLFSSL_SERVER_END)
return NULL;
len = min(SERVER_ID_LEN, (word32)len);
+
+#ifdef HAVE_EXT_CACHE
+ if (ssl->ctx->get_sess_cb != NULL) {
+ int copy = 0;
+ ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, ©);
+ if (ret != NULL)
+ return ret;
+ }
+
+ if (ssl->ctx->internalCacheOff)
+ return NULL;
+#endif
+
row = HashSession(id, len, &error) % SESSION_ROWS;
if (error != 0) {
WOLFSSL_MSG("Hash session failed");
@@ -8450,6 +8495,32 @@ WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
#endif /* NO_CLIENT_CACHE */
+/* Restore the master secret and session information for certificates.
+ *
+ * ssl The SSL/TLS object.
+ * session The cached session to restore.
+ * masterSecret The master secret from the cached session.
+ * restoreSessionCerts Restoring session certificates is required.
+ */
+static INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session,
+ byte* masterSecret, byte restoreSessionCerts)
+{
+ (void)ssl;
+ (void)restoreSessionCerts;
+
+ if (masterSecret)
+ XMEMCPY(masterSecret, session->masterSecret, SECRET_LEN);
+#ifdef SESSION_CERTS
+ /* If set, we should copy the session certs into the ssl object
+ * from the session we are returning so we can resume */
+ if (restoreSessionCerts) {
+ ssl->session.chain = session->chain;
+ ssl->session.version = session->version;
+ ssl->session.cipherSuite0 = session->cipherSuite0;
+ ssl->session.cipherSuite = session->cipherSuite;
+ }
+#endif /* SESSION_CERTS */
+}
WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
byte restoreSessionCerts)
@@ -8479,6 +8550,21 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
else
id = ssl->session.sessionID;
+#ifdef HAVE_EXT_CACHE
+ if (ssl->ctx->get_sess_cb != NULL) {
+ int copy = 0;
+ /* Attempt to retrieve the session from the external cache. */
+ ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, ©);
+ if (ret != NULL) {
+ RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
+ return ret;
+ }
+ }
+
+ if (ssl->ctx->internalCacheOff)
+ return NULL;
+#endif
+
row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
if (error != 0) {
WOLFSSL_MSG("Hash session failed");
@@ -8508,19 +8594,7 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
if (LowResTimer() < (current->bornOn + current->timeout)) {
WOLFSSL_MSG("Session valid");
ret = current;
- if (masterSecret)
- XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
-#ifdef SESSION_CERTS
- /* If set, we should copy the session certs into the ssl object
- * from the session we are returning so we can resume */
- if (restoreSessionCerts) {
- ssl->session.chain = ret->chain;
- ssl->session.version = ret->version;
- ssl->session.cipherSuite0 = ret->cipherSuite0;
- ssl->session.cipherSuite = ret->cipherSuite;
- }
-#endif /* SESSION_CERTS */
-
+ RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
} else {
WOLFSSL_MSG("Session timed out");
}
@@ -8659,12 +8733,14 @@ static int get_locked_session_stats(word32* active, word32* total,
int AddSession(WOLFSSL* ssl)
{
- word32 row, idx;
+ word32 row = 0;
+ word32 idx = 0;
int error = 0;
#ifdef HAVE_SESSION_TICKET
byte* tmpBuff = NULL;
int ticLen = 0;
#endif
+ WOLFSSL_SESSION* session;
if (ssl->options.sessionCacheOff)
return 0;
@@ -8677,12 +8753,6 @@ int AddSession(WOLFSSL* ssl)
return 0;
#endif
- row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS;
- if (error != 0) {
- WOLFSSL_MSG("Hash session failed");
- return error;
- }
-
#ifdef HAVE_SESSION_TICKET
ticLen = ssl->session.ticketLen;
/* Alloc Memory here so if Malloc fails can exit outside of lock */
@@ -8694,27 +8764,56 @@ int AddSession(WOLFSSL* ssl)
}
#endif
- if (wc_LockMutex(&session_mutex) != 0) {
+#ifdef HAVE_EXT_CACHE
+ if (ssl->options.internalCacheOff) {
+ /* Create a new session object to be stored. */
+ session = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (session == NULL) {
#ifdef HAVE_SESSION_TICKET
- XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+ XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
#endif
- return BAD_MUTEX_E;
+ return MEMORY_E;
+ }
+ XMEMSET(session, 0, sizeof(WOLFSSL_SESSION));
+ session->isAlloced = 1;
+ }
+ else
+#endif
+ {
+ /* Use the session object in the cache for external cache if required.
+ */
+ row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) %
+ SESSION_ROWS;
+ if (error != 0) {
+ WOLFSSL_MSG("Hash session failed");
+#ifdef HAVE_SESSION_TICKET
+ XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+#endif
+ return error;
+ }
+
+ if (wc_LockMutex(&session_mutex) != 0) {
+#ifdef HAVE_SESSION_TICKET
+ XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+#endif
+ return BAD_MUTEX_E;
+ }
+
+ idx = SessionCache[row].nextIdx++;
+#ifdef SESSION_INDEX
+ ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
+#endif
+ session = &SessionCache[row].Sessions[idx];
}
- idx = SessionCache[row].nextIdx++;
-#ifdef SESSION_INDEX
- ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
-#endif
+ XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
+ session->haveEMS = ssl->options.haveEMS;
+ XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
+ session->sessionIDSz = ssl->arrays->sessionIDSz;
- XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
- ssl->arrays->masterSecret, SECRET_LEN);
- SessionCache[row].Sessions[idx].haveEMS = ssl->options.haveEMS;
- XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID,
- ID_LEN);
- SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz;
-
- SessionCache[row].Sessions[idx].timeout = ssl->timeout;
- SessionCache[row].Sessions[idx].bornOn = LowResTimer();
+ session->timeout = ssl->timeout;
+ session->bornOn = LowResTimer();
#ifdef HAVE_SESSION_TICKET
/* Check if another thread modified ticket since alloc */
@@ -8724,32 +8823,28 @@ int AddSession(WOLFSSL* ssl)
if (error == 0) {
/* Cleanup cache row's old Dynamic buff if exists */
- if(SessionCache[row].Sessions[idx].isDynamic) {
- XFREE(SessionCache[row].Sessions[idx].ticket,
- ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
- SessionCache[row].Sessions[idx].ticket = NULL;
+ if(session->isDynamic) {
+ XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
+ session->ticket = NULL;
}
/* If too large to store in static buffer, use dyn buffer */
if (ticLen > SESSION_TICKET_LEN) {
- SessionCache[row].Sessions[idx].ticket = tmpBuff;
- SessionCache[row].Sessions[idx].isDynamic = 1;
+ session->ticket = tmpBuff;
+ session->isDynamic = 1;
} else {
- SessionCache[row].Sessions[idx].ticket =
- SessionCache[row].Sessions[idx].staticTicket;
- SessionCache[row].Sessions[idx].isDynamic = 0;
+ session->ticket = session->staticTicket;
+ session->isDynamic = 0;
}
}
if (error == 0) {
- SessionCache[row].Sessions[idx].ticketLen = ticLen;
- XMEMCPY(SessionCache[row].Sessions[idx].ticket,
- ssl->session.ticket, ticLen);
+ session->ticketLen = ticLen;
+ XMEMCPY(session->ticket, ssl->session.ticket, ticLen);
} else { /* cleanup, reset state */
- SessionCache[row].Sessions[idx].ticket =
- SessionCache[row].Sessions[idx].staticTicket;
- SessionCache[row].Sessions[idx].isDynamic = 0;
- SessionCache[row].Sessions[idx].ticketLen = 0;
+ session->ticket = session->staticTicket;
+ session->isDynamic = 0;
+ session->ticketLen = 0;
if (tmpBuff) {
XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
tmpBuff = NULL;
@@ -8759,19 +8854,24 @@ int AddSession(WOLFSSL* ssl)
#ifdef SESSION_CERTS
if (error == 0) {
- SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
- XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
- ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
+ session->chain.count = ssl->session.chain.count;
+ XMEMCPY(session->chain.certs, ssl->session.chain.certs,
+ sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
- SessionCache[row].Sessions[idx].version = ssl->version;
- SessionCache[row].Sessions[idx].cipherSuite0 = ssl->options.cipherSuite0;
- SessionCache[row].Sessions[idx].cipherSuite = ssl->options.cipherSuite;
+ session->version = ssl->version;
+ session->cipherSuite0 = ssl->options.cipherSuite0;
+ session->cipherSuite = ssl->options.cipherSuite;
}
#endif /* SESSION_CERTS */
- if (error == 0) {
- SessionCache[row].totalCount++;
- if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
- SessionCache[row].nextIdx = 0;
+#ifdef HAVE_EXT_CACHE
+ if (!ssl->options.internalCacheOff)
+#endif
+ {
+ if (error == 0) {
+ SessionCache[row].totalCount++;
+ if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
+ SessionCache[row].nextIdx = 0;
+ }
}
#ifndef NO_CLIENT_CACHE
if (error == 0) {
@@ -8780,48 +8880,70 @@ int AddSession(WOLFSSL* ssl)
WOLFSSL_MSG("Adding client cache entry");
- SessionCache[row].Sessions[idx].idLen = ssl->session.idLen;
- XMEMCPY(SessionCache[row].Sessions[idx].serverID,
- ssl->session.serverID, ssl->session.idLen);
+ session->idLen = ssl->session.idLen;
+ XMEMCPY(session->serverID, ssl->session.serverID,
+ ssl->session.idLen);
- clientRow = HashSession(ssl->session.serverID, ssl->session.idLen,
- &error) % SESSION_ROWS;
- if (error != 0) {
- WOLFSSL_MSG("Hash session failed");
- } else {
- clientIdx = ClientCache[clientRow].nextIdx++;
+#ifdef HAVE_EXT_CACHE
+ if (!ssl->options.internalCacheOff)
+#endif
+ {
+ clientRow = HashSession(ssl->session.serverID,
+ ssl->session.idLen, &error) % SESSION_ROWS;
+ if (error != 0) {
+ WOLFSSL_MSG("Hash session failed");
+ } else {
+ clientIdx = ClientCache[clientRow].nextIdx++;
- ClientCache[clientRow].Clients[clientIdx].serverRow =
+ ClientCache[clientRow].Clients[clientIdx].serverRow =
(word16)row;
- ClientCache[clientRow].Clients[clientIdx].serverIdx =
+ ClientCache[clientRow].Clients[clientIdx].serverIdx =
(word16)idx;
- ClientCache[clientRow].totalCount++;
- if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
- ClientCache[clientRow].nextIdx = 0;
+ ClientCache[clientRow].totalCount++;
+ if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW)
+ ClientCache[clientRow].nextIdx = 0;
+ }
}
}
else
- SessionCache[row].Sessions[idx].idLen = 0;
+ session->idLen = 0;
}
#endif /* NO_CLIENT_CACHE */
#if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
- if (error == 0) {
- word32 active = 0;
+#ifdef HAVE_EXT_CACHE
+ if (!ssl->options.internalCacheOff)
+#endif
+ {
+ if (error == 0) {
+ word32 active = 0;
- error = get_locked_session_stats(&active, NULL, NULL);
- if (error == SSL_SUCCESS) {
- error = 0; /* back to this function ok */
+ error = get_locked_session_stats(&active, NULL, NULL);
+ if (error == SSL_SUCCESS) {
+ error = 0; /* back to this function ok */
- if (active > PeakSessions)
- PeakSessions = active;
+ if (active > PeakSessions)
+ PeakSessions = active;
+ }
}
}
#endif /* defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) */
- if (wc_UnLockMutex(&session_mutex) != 0)
- return BAD_MUTEX_E;
+#ifdef HAVE_EXT_CACHE
+ if (!ssl->options.internalCacheOff)
+#endif
+ {
+ if (wc_UnLockMutex(&session_mutex) != 0)
+ return BAD_MUTEX_E;
+ }
+
+#ifdef HAVE_EXT_CACHE
+ if (error == 0 && ssl->ctx->new_sess_cb != NULL)
+ ssl->ctx->new_sess_cb(ssl, session);
+ if (ssl->options.internalCacheOff)
+ wolfSSL_SESSION_free(session);
+#endif
return error;
}
@@ -9758,15 +9880,71 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
STACK_OF(WOLFSSL_X509_NAME)* names)
{
- (void)ctx;
- (void)names;
+ WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_client_CA_list");
+
+ if (ctx != NULL)
+ ctx->ca_names = names;
}
+ STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_SSL_CTX_get_client_CA_list(
+ const WOLFSSL_CTX *s)
+ {
+ WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_client_CA_list");
+
+ if (s == NULL)
+ return NULL;
+
+ return s->ca_names;
+ }
STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
{
- (void)fname;
- return 0;
+ WOLFSSL_STACK *list = NULL;
+ WOLFSSL_STACK *node;
+ WOLFSSL_BIO* bio;
+ WOLFSSL_X509 *cert = NULL;
+ WOLFSSL_X509_NAME *subjectName = NULL;
+
+ WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
+
+ bio = wolfSSL_BIO_new_file(fname, "r");
+ if (bio == NULL)
+ return NULL;
+
+ /* Read each certificate in the chain out of the file. */
+ while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
+ subjectName = wolfSSL_X509_get_subject_name(cert);
+ if (subjectName == NULL)
+ break;
+
+ node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (node == NULL)
+ break;
+
+ /* Need a persistent copy of the subject name. */
+ node->data.name = (WOLFSSL_X509_NAME*)XMALLOC(
+ sizeof(WOLFSSL_X509_NAME), NULL, DYNAMIC_TYPE_OPENSSL);
+ if (node->data.name == NULL) {
+ XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
+ break;
+ }
+ XMEMCPY(node->data.name, subjectName, sizeof(WOLFSSL_X509_NAME));
+ /* Clear pointers so freeing certificate doesn't free memory. */
+ XMEMSET(subjectName, 0, sizeof(WOLFSSL_X509_NAME));
+
+ /* Put nod on the front of the list. */
+ node->num = (list == NULL) ? 1 : list->num + 1;
+ node->next = list;
+ list = node;
+
+ wolfSSL_X509_free(cert);
+ cert = NULL;
+ }
+
+ wolfSSL_X509_free(cert);
+ wolfSSL_BIO_free(bio);
+ return list;
}
@@ -9878,9 +10056,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
{
- /* goahead calls with 0, do nothing */
WOLFSSL_ENTER("SSL_CTX_set_options");
- (void)ctx;
+ ctx->mask |= opt;
return opt;
}
@@ -10112,12 +10289,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
- int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, const byte** p)
+ int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
{
+ WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
+
if (bio == NULL || p == NULL)
return SSL_FATAL_ERROR;
- *p = bio->mem;
+ *(byte **)p = bio->mem;
return bio->memLen;
}
@@ -10232,6 +10411,11 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
return (int)XFREAD(buf, 1, len, bio->file);
}
#endif
+ if (bio && bio->type == BIO_MEMORY) {
+ len = min(len, bio->memLen);
+ XMEMCPY(buf, bio->mem, len);
+ return len;
+ }
/* already got eof, again is error */
if (bio && front->eof)
@@ -10280,6 +10464,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
int ret;
WOLFSSL* ssl = 0;
WOLFSSL_BIO* front = bio;
+ byte* p;
WOLFSSL_ENTER("wolfSSL_BIO_write");
@@ -10293,6 +10478,32 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
#endif
+ if (bio && bio->type == BIO_MEMORY) {
+ /* Make buffer big enough to hold new data. */
+ if (bio->mem == NULL) {
+ bio->mem = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
+ if (bio->mem == NULL)
+ return -1;
+ p = bio->mem;
+ }
+ else {
+ p = (byte*)XMALLOC(len + bio->memLen, bio->heap,
+ DYNAMIC_TYPE_OPENSSL);
+ if (p == NULL)
+ return -1;
+ XMEMCPY(p, bio->mem, bio->memLen);
+ XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+ bio->mem = p;
+ p += bio->memLen;
+ }
+
+ /* Put data on the end of the buffer. */
+ XMEMCPY(p, data, len);
+ bio->memLen += len;
+
+ return len;
+ }
+
/* already got eof, again is error */
if (bio && front->eof)
return SSL_FATAL_ERROR;
@@ -10372,8 +10583,15 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
unsigned long wolfSSL_ERR_get_error(void)
{
- /* TODO: */
- return 0;
+ WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
+
+#if defined(OPENSSL_ERR_ONE)
+ unsigned long ret = wc_last_error;
+ wc_last_error = 0;
+ return ret;
+#else
+ return (unsigned long)(0 - NOT_COMPILED_IN);
+#endif
}
#ifndef NO_MD5
@@ -11918,7 +12136,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
void wolfSSL_ERR_clear_error(void)
{
- /* TODO: */
+ WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
+
+#if defined(OPENSSL_ERR_ONE)
+ wc_last_error = 0;
+#endif
}
@@ -12164,14 +12386,61 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
#if defined(KEEP_PEER_CERT)
+ #ifdef SESSION_CERTS
+ /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
+ *
+ * x509 WOLFSSL_X509 object to decode into.
+ * in X509 DER data.
+ * len Length of the X509 DER data.
+ * returns the new certificate on success, otherwise NULL.
+ */
+ static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
+ {
+ int ret;
+ #ifdef WOLFSSL_SMALL_STACK
+ DecodedCert* cert = NULL;
+ #else
+ DecodedCert cert[1];
+ #endif
+
+ #ifdef WOLFSSL_SMALL_STACK
+ cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (cert == NULL)
+ return NULL;
+ #endif
+
+ /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
+ */
+ InitDecodedCert(cert, (byte*)in, len, NULL);
+ if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
+ InitX509(x509, 0, NULL);
+ ret = CopyDecodedToX509(x509, cert);
+ FreeDecodedCert(cert);
+ }
+ #ifdef WOLFSSL_SMALL_STACK
+ XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ #endif
+
+ return ret;
+ }
+ #endif
+
WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
{
WOLFSSL_ENTER("SSL_get_peer_certificate");
if (ssl->peerCert.issuer.sz)
return &ssl->peerCert;
- else
- return 0;
+#ifdef SESSION_CERTS
+ else if (ssl->session.chain.count > 0) {
+ if (DecodeToX509(&ssl->peerCert, ssl->session.chain.certs[0].buffer,
+ ssl->session.chain.certs[0].length) == 0) {
+ return &ssl->peerCert;
+ }
+ }
+#endif
+ return 0;
}
#endif /* KEEP_PEER_CERT */
@@ -12229,7 +12498,7 @@ static void ExternalFreeX509(WOLFSSL_X509* x509)
WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
{
WOLFSSL_ENTER("X509_get_issuer_name");
- if(cert)
+ if (cert && cert->issuer.sz != 0)
return &cert->issuer;
return NULL;
}
@@ -12238,7 +12507,7 @@ static void ExternalFreeX509(WOLFSSL_X509* x509)
WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
{
WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
- if(cert)
+ if (cert && cert->subject.sz != 0)
return &cert->subject;
return NULL;
}
@@ -12853,7 +13122,6 @@ void wolfSSL_sk_X509_free(STACK_OF(WOLFSSL_X509_NAME)* sk) {
}
#endif /* NO_CERTS && OPENSSL_EXTRA */
-
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
{
WOLFSSL_X509 *newX509 = NULL;
@@ -13119,6 +13387,7 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
ssl->ctx->certificate->buffer,
ssl->ctx->certificate->length);
+ ssl->ctx->ownOurCert = 1;
}
return ssl->ctx->ourCert;
}
@@ -13295,8 +13564,21 @@ int wolfSSL_session_reused(WOLFSSL* ssl)
#ifdef OPENSSL_EXTRA
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
{
+ if (session == NULL)
+ return;
+
+#ifdef HAVE_EXT_CACHE
+ if (session->isAlloced) {
+ #ifdef HAVE_SESSION_TICKET
+ if (session->isDynamic)
+ XFREE(session->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
+ #endif
+ XFREE(session, NULL, DYNAMIC_TYPE_OPENSSL);
+ }
+#else
/* No need to free since cache is static */
(void)session;
+#endif
}
#endif
@@ -13402,15 +13684,264 @@ const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
return wolfSSL_get_cipher_name_internal(ssl);
}
+#ifdef HAVE_ECC
+/* Return the name of the curve used for key exchange as a printable string.
+ *
+ * ssl The SSL/TLS object.
+ * returns NULL if ECDH was not used, otherwise the name as a string.
+ */
+const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
+{
+ if (ssl == NULL)
+ return NULL;
+ if (ssl->specs.kea != ecdhe_psk_kea &&
+ ssl->specs.kea != ecc_diffie_hellman_kea)
+ return NULL;
+ if (ssl->ecdhCurveOID == 0)
+ return NULL;
+ return wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL));
+}
+#endif
#ifdef OPENSSL_EXTRA
-char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len)
+char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
+ int len)
{
- (void)cipher;
- (void)in;
- (void)len;
- return 0;
+ char *ret = in;
+ const char *keaStr, *authStr, *encStr, *macStr;
+ size_t strLen;
+
+ if (cipher == NULL || in == NULL)
+ return NULL;
+
+ switch (cipher->ssl->specs.kea) {
+ case no_kea:
+ keaStr = "None";
+ break;
+#ifndef NO_RSA
+ case rsa_kea:
+ keaStr = "RSA";
+ break;
+#endif
+#ifndef NO_DH
+ case diffie_hellman_kea:
+ keaStr = "DHE";
+ break;
+#endif
+ case fortezza_kea:
+ keaStr = "FZ";
+ break;
+#ifndef NO_PSK
+ case psk_kea:
+ keaStr = "PSK";
+ break;
+ #ifndef NO_DH
+ case dhe_psk_kea:
+ keaStr = "DHEPSK";
+ break;
+ #endif
+ #ifdef HAVE_ECC
+ case ecdhe_psk_kea:
+ keaStr = "ECDHEPSK";
+ break;
+ #endif
+#endif
+#ifdef HAVE_NTRU
+ case ntru_kea:
+ keaStr = "NTRU";
+ break;
+#endif
+#ifdef HAVE_ECC
+ case ecc_diffie_hellman_kea:
+ keaStr = "ECDHE";
+ break;
+ case ecc_static_diffie_hellman_kea:
+ keaStr = "ECDH";
+ break;
+#endif
+ default:
+ keaStr = "unknown";
+ break;
+ }
+
+ switch (cipher->ssl->specs.sig_algo) {
+ case anonymous_sa_algo:
+ authStr = "None";
+ break;
+#ifndef NO_RSA
+ case rsa_sa_algo:
+ authStr = "RSA";
+ break;
+#endif
+#ifndef NO_DSA
+ case dsa_sa_algo:
+ authStr = "DSA";
+ break;
+#endif
+#ifdef HAVE_ECC
+ case ecc_dsa_sa_algo:
+ authStr = "ECDSA";
+ break;
+#endif
+ default:
+ authStr = "unknown";
+ break;
+ }
+
+ switch (cipher->ssl->specs.bulk_cipher_algorithm) {
+ case wolfssl_cipher_null:
+ encStr = "None";
+ break;
+#ifndef NO_RC4
+ case wolfssl_rc4:
+ encStr = "RC4(128)";
+ break;
+#endif
+#ifndef NO_DES3
+ case wolfssl_triple_des:
+ encStr = "3DES(168)";
+ break;
+#endif
+#ifdef HAVE_IDEA
+ case wolfssl_idea:
+ encStr = "IDEA(128)";
+ break;
+#endif
+#ifndef NO_AES
+ case wolfssl_aes:
+ if (cipher->ssl->specs.key_size == 128)
+ encStr = "AES(128)";
+ else if (cipher->ssl->specs.key_size == 256)
+ encStr = "AES(256)";
+ else
+ encStr = "AES(?)";
+ break;
+ #ifdef HAVE_AESGCM
+ case wolfssl_aes_gcm:
+ if (cipher->ssl->specs.key_size == 128)
+ encStr = "AESGCM(128)";
+ else if (cipher->ssl->specs.key_size == 256)
+ encStr = "AESGCM(256)";
+ else
+ encStr = "AESGCM(?)";
+ break;
+ #endif
+ #ifdef HAVE_AESCCM
+ case wolfssl_aes_ccm:
+ if (cipher->ssl->specs.key_size == 128)
+ encStr = "AESCCM(128)";
+ else if (cipher->ssl->specs.key_size == 256)
+ encStr = "AESCCM(256)";
+ else
+ encStr = "AESCCM(?)";
+ break;
+ #endif
+#endif
+#ifdef HAVE_CHACHA
+ case wolfssl_chacha:
+ encStr = "CHACHA20/POLY1305(256)";
+ break;
+#endif
+#ifdef HAVE_CAMELLIA
+ case wolfssl_camellia:
+ if (cipher->ssl->specs.key_size == 128)
+ encStr = "Camellia(128)";
+ else if (cipher->ssl->specs.key_size == 256)
+ encStr = "Camellia(256)";
+ else
+ encStr = "Camellia(?)";
+ break;
+#endif
+#if defined(HAVE_HC128) && !defined(NO_HC128)
+ case wolfssl_hc128:
+ encStr = "HC128(128)";
+ break;
+#endif
+#if defined(HAVE_RABBIT) && !defined(NO_RABBIT)
+ case wolfssl_rabbit:
+ encStr = "RABBIT(128)";
+ break;
+#endif
+ default:
+ encStr = "unknown";
+ break;
+ }
+
+ switch (cipher->ssl->specs.mac_algorithm) {
+ case no_mac:
+ macStr = "None";
+ break;
+#ifndef NO_MD5
+ case md5_mac:
+ macStr = "MD5";
+ break;
+#endif
+#ifndef NO_SHA
+ case sha_mac:
+ macStr = "SHA1";
+ break;
+#endif
+#ifdef HAVE_SHA224
+ case sha224_mac:
+ macStr = "SHA224";
+ break;
+#endif
+#ifndef NO_SHA256
+ case sha256_mac:
+ macStr = "SHA256";
+ break;
+#endif
+#ifdef HAVE_SHA384
+ case sha384_mac:
+ macStr = "SHA384";
+ break;
+#endif
+#ifdef HAVE_SHA512
+ case sha512_mac:
+ macStr = "SHA512";
+ break;
+#endif
+#ifdef HAVE_BLAKE2
+ case blake2b_mac:
+ macStr = "BLAKE2b";
+ break;
+#endif
+ default:
+ macStr = "unknown";
+ break;
+ }
+
+ /* Build up the string by copying onto the end. */
+ XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+ XSTRNCPY(in, " ", len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+ XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+ XSTRNCPY(in, " Kx=", len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+ XSTRNCPY(in, keaStr, len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+ XSTRNCPY(in, " Au=", len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+ XSTRNCPY(in, authStr, len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+ XSTRNCPY(in, " Enc=", len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+ XSTRNCPY(in, encStr, len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+
+ XSTRNCPY(in, " Mac=", len);
+ in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
+ XSTRNCPY(in, macStr, len);
+ in[len-1] = '\0';
+
+ return ret;
}
@@ -13437,15 +13968,6 @@ void wolfSSL_X509_free(WOLFSSL_X509* x509)
#endif /* NO_CERTS */
-/* was do nothing */
-/*
-void OPENSSL_free(void* buf)
-{
- (void)buf;
-}
-*/
-
-
int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
int* ssl)
{
@@ -13509,7 +14031,8 @@ WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* top)
int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
{
- (void)bio;
+ if (bio && bio->type == BIO_MEMORY)
+ return bio->memLen;
return 0;
}
@@ -13640,34 +14163,90 @@ int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
- const char* file, long len)
+ const char* file, long type)
{
+#ifndef NO_FILESYSTEM
+ int ret = SSL_FAILURE;
+ XFILE fp;
+ long sz;
+ byte* pem = NULL;
+ WOLFSSL_X509* x509;
+
+ if (type != X509_FILETYPE_PEM)
+ return BAD_FUNC_ARG;
+
+ fp = XFOPEN(file, "r");
+ if (fp == NULL)
+ return BAD_FUNC_ARG;
+
+ XFSEEK(fp, 0, XSEEK_END);
+ sz = XFTELL(fp);
+ XREWIND(fp);
+
+ if (sz <= 0)
+ goto end;
+
+ pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_TMP_BUFFER);
+ if (pem == NULL) {
+ ret = MEMORY_ERROR;
+ goto end;
+ }
+
+ /* Read in file which may be a CRL or certificate. */
+ if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
+ goto end;
+
+ if (XSTRNSTR((char*)pem, BEGIN_X509_CRL, (unsigned int)sz) != NULL) {
+#ifdef HAVE_CRL
+ ret = wolfSSL_CertManagerLoadCRLBuffer(lookup->store->cm, pem, sz,
+ SSL_FILETYPE_PEM);
+#endif
+ }
+ else {
+ x509 = wolfSSL_X509_load_certificate_buffer(pem, (int)sz,
+ SSL_FILETYPE_PEM);
+ if (x509 == NULL)
+ goto end;
+ ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
+ }
+
+end:
+ if (pem != NULL)
+ XFREE(pem, 0, DYNAMIC_TYPE_TMP_BUFFER);
+ XFCLOSE(fp);
+ return ret;
+#else
(void)lookup;
(void)file;
- (void)len;
- return 0;
+ (void)type;
+ return SSL_FAILURE;
+#endif
}
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
{
- return 0;
+ /* Method implementation in functions. */
+ static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
+ return &meth;
}
-
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
{
- return 0;
+ /* Method implementation in functions. */
+ static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
+ return &meth;
}
-
WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
WOLFSSL_X509_LOOKUP_METHOD* m)
{
- (void)store;
+ /* Method is a dummy value and is not needed. */
(void)m;
- return 0;
+ /* Make sure the lookup has a back reference to the store. */
+ store->lookup.store = store;
+ return &store->lookup;
}
@@ -13675,7 +14254,7 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
{
WOLFSSL_X509* localX509 = NULL;
- const unsigned char* mem = NULL;
+ unsigned char* mem = NULL;
int ret;
word32 size;
@@ -13710,7 +14289,7 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
{
WC_PKCS12* localPkcs12 = NULL;
- const unsigned char* mem = NULL;
+ unsigned char* mem = NULL;
int ret;
word32 size;
@@ -14074,6 +14653,8 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
store = NULL;
}
+ else
+ store->isDynamic = 1;
}
return store;
@@ -14082,7 +14663,7 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
{
- if (store != NULL) {
+ if (store != NULL && store->isDynamic) {
if (store->cm != NULL)
wolfSSL_CertManagerFree(store->cm);
XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
@@ -14147,7 +14728,9 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
ctx->current_cert = x509;
ctx->chain = sk;
ctx->domain = NULL;
+#ifdef HAVE_EX_DATA
ctx->ex_data = NULL;
+#endif
ctx->userCtx = NULL;
ctx->error = 0;
ctx->error_depth = 0;
@@ -14315,20 +14898,49 @@ WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
{
- (void)x509;
- return 0;
+ WOLFSSL_ASN1_INTEGER* a;
+ int i = 0;
+
+ WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
+
+ a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (a == NULL)
+ return NULL;
+
+ /* Make sure there is space for the data, ASN.1 type and length. */
+ if (x509->serialSz > (int)(sizeof(WOLFSSL_ASN1_INTEGER) - 2)) {
+ XFREE(a, NULL, DYNAMIC_TYPE_OPENSSL);
+ return NULL;
+ }
+
+ a->data[i++] = ASN_INTEGER;
+ a->data[i++] = (unsigned char)x509->serialSz;
+ XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
+
+ return a;
}
+#if defined(WOLFSSL_NGINX)
int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
{
- (void)bio;
- (void)asnTime;
+ char buf[MAX_TIME_STRING_SZ];
+
+ WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
+
+ if (bio == NULL || asnTime == NULL)
+ return BAD_FUNC_ARG;
+
+ wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf, sizeof(buf));
+ wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
+
return 0;
}
+#endif
-#if defined(WOLFSSL_MYSQL_COMPATIBLE)
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time, char* buf, int len)
{
int format;
@@ -14377,7 +14989,7 @@ 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");
-#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
if (ctx != NULL && idx == 0)
return ctx->ex_data;
#else
@@ -14405,12 +15017,23 @@ void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
unsigned long wolfSSL_ERR_peek_error(void)
{
+ WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
+
+#if defined(OPENSSL_ERR_ONE)
+ return wc_last_error;
+#else
return 0;
+#endif
}
int wolfSSL_ERR_GET_REASON(unsigned long err)
{
+#ifdef WOLFSSL_NGINX
+ /* Nginx looks for this error to know to stop parsing certificates. */
+ if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
+ return PEM_R_NO_START_LINE;
+#endif
(void)err;
return 0;
}
@@ -14630,21 +15253,25 @@ WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *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;
+ if (s == NULL || resp == NULL)
+ return 0;
+
+ *resp = s->ocspResp;
+ return s->ocspRespSz;
}
-/*** TBD ***/
-WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len)
+WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s,
+ unsigned char *resp, int len)
{
- (void)s;
- (void)resp;
- (void)len;
- return 0;
+ if (s == NULL)
+ return SSL_FAILURE;
+
+ s->ocspResp = resp;
+ s->ocspRespSz = len;
+
+ return SSL_SUCCESS;
}
@@ -14744,11 +15371,13 @@ long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
#ifndef NO_CERTS
long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
{
- byte* chain;
+ byte* chain = NULL;
long chainSz = 0;
- int derSz;
+ int derSz;
const byte* der;
- int ret;
+ int ret;
+ int idx = 0;
+ DerBuffer *derBuffer = NULL;
WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
@@ -14763,37 +15392,53 @@ long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
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);
+ if (ctx->certificate == NULL) {
+ /* Process buffer makes first certificate the leaf. */
+ ret = ProcessBuffer(ctx, der, derSz, SSL_FILETYPE_ASN1, CERT_TYPE,
+ NULL, NULL, 1);
+ if (ret != SSL_SUCCESS) {
+ WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
+ return SSL_FAILURE;
+ }
}
else {
- XMEMCPY(chain, der, derSz);
- }
+ /* TODO: Do this elsewhere. */
+ AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
+ XMEMCPY(derBuffer->buffer, der, derSz);
+ AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA, !ctx->verifyNone);
- 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;
+ /* adding cert to existing chain */
+ if (ctx->certChain != NULL && ctx->certChain->length > 0) {
+ chainSz += ctx->certChain->length;
+ }
+ chainSz += OPAQUE24_LEN + 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);
+ idx = ctx->certChain->length;
+ }
+ c32to24(derSz, chain + idx);
+ idx += OPAQUE24_LEN,
+ XMEMCPY(chain + idx, der, derSz);
+ idx += derSz;
+
+ FreeDer(&ctx->certChain);
+ ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
+ if (ret == 0) {
+ XMEMCPY(ctx->certChain->buffer, chain, idx);
+ }
}
/* on success WOLFSSL_X509 memory is responsibility of ctx */
wolfSSL_X509_free(x509);
- XFREE(chain, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
+ if (chain != NULL)
+ XFREE(chain, ctx->heap, CERT_TYPE);
return SSL_SUCCESS;
}
@@ -15031,6 +15676,47 @@ int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
return 0;
}
+/* Return the month as a string.
+ *
+ * n The number of the month as a two characters (1 based).
+ * returns the month as a string.
+ */
+static INLINE const char* MonthStr(const char* n)
+{
+ static const char monthStr[12][4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+ return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
+}
+
+int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
+ const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
+{
+ const char* p = (const char *)(asnTime->data + 2);
+ WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
+
+ if (bio == NULL || asnTime == NULL)
+ return BAD_FUNC_ARG;
+
+ /* GetTimeString not always available. */
+ wolfSSL_BIO_write(bio, MonthStr(p + 4), 3);
+ wolfSSL_BIO_write(bio, " ", 1);
+ /* Day */
+ wolfSSL_BIO_write(bio, p + 6, 2);
+ wolfSSL_BIO_write(bio, " ", 1);
+ /* Hour */
+ wolfSSL_BIO_write(bio, p + 8, 2);
+ wolfSSL_BIO_write(bio, ":", 1);
+ /* Min */
+ wolfSSL_BIO_write(bio, p + 10, 2);
+ wolfSSL_BIO_write(bio, ":", 1);
+ /* Secs */
+ wolfSSL_BIO_write(bio, p + 12, 2);
+ wolfSSL_BIO_write(bio, " ", 1);
+ wolfSSL_BIO_write(bio, p, 4);
+
+ return 0;
+}
int wolfSSL_sk_num(WOLFSSL_X509_REVOKED* rev)
{
@@ -15051,43 +15737,295 @@ void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED* rev, int i)
void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*))
{
+#ifdef HAVE_EXT_CACHE
+ ctx->get_sess_cb = f;
+#else
(void)ctx;
(void)f;
+#endif
}
void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
{
+#ifdef HAVE_EXT_CACHE
+ ctx->new_sess_cb = f;
+#else
(void)ctx;
(void)f;
+#endif
}
void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
WOLFSSL_SESSION*))
{
+#ifdef HAVE_EXT_CACHE
+ ctx->rem_sess_cb = f;
+#else
(void)ctx;
(void)f;
+#endif
}
+#ifdef HAVE_EXT_CACHE
+/* convert 32 bit integer to opaque */
+static INLINE void c32toa(word32 u32, byte* c)
+{
+ c[0] = (u32 >> 24) & 0xff;
+ c[1] = (u32 >> 16) & 0xff;
+ c[2] = (u32 >> 8) & 0xff;
+ c[3] = u32 & 0xff;
+}
+
+static INLINE void c16toa(word16 u16, byte* c)
+{
+ c[0] = (u16 >> 8) & 0xff;
+ c[1] = u16 & 0xff;
+}
+#endif
int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
{
+ int size = 0;
+#ifdef HAVE_EXT_CACHE
+ int idx = 0;
+#ifdef SESSION_CERTS
+ int i;
+#endif
+ unsigned char *data;
+
+ /* bornOn | timeout | sessionID len | sessionID | masterSecret | haveEMS */
+ size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz +
+ SECRET_LEN + OPAQUE8_LEN;
+#ifdef SESSION_CERTS
+ /* Peer chain */
+ size += OPAQUE8_LEN;
+ for (i = 0; i < sess->chain.count; i++)
+ size += OPAQUE16_LEN + sess->chain.certs[i].length;
+ /* Protocol version + cipher suite */
+ size += OPAQUE16_LEN + OPAQUE16_LEN;
+#endif
+#ifndef NO_CLIENT_CACHE
+ /* ServerID len | ServerID */
+ size += OPAQUE16_LEN + sess->idLen;
+#endif
+#ifdef HAVE_SESSION_TICKET
+ /* ticket len | ticket */
+ size += OPAQUE16_LEN + sess->ticketLen;
+#endif
+
+ if (p != NULL) {
+ if (*p == NULL)
+ *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
+ if (*p == NULL)
+ return 0;
+ data = *p;
+
+ c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
+ c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
+ data[idx++] = sess->sessionIDSz;
+ XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
+ idx += sess->sessionIDSz;
+ XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
+ data[idx++] = sess->haveEMS;
+#ifdef SESSION_CERTS
+ data[idx++] = sess->chain.count;
+ for (i = 0; i < sess->chain.count; i++) {
+ c16toa(sess->chain.certs[i].length, data + idx);
+ idx += OPAQUE16_LEN;
+ XMEMCPY(data + idx, sess->chain.certs[i].buffer,
+ sess->chain.certs[i].length);
+ idx += sess->chain.certs[i].length;
+ }
+ data[idx++] = sess->version.major;
+ data[idx++] = sess->version.minor;
+ data[idx++] = sess->cipherSuite0;
+ data[idx++] = sess->cipherSuite;
+#endif
+#ifndef NO_CLIENT_CACHE
+ c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
+ XMEMCPY(data + idx, sess->serverID, sess->idLen);
+ idx += sess->idLen;
+#endif
+#ifdef HAVE_SESSION_TICKET
+ c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
+ XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
+ idx += sess->ticketLen;
+#endif
+ }
+#endif
+
(void)sess;
(void)p;
- return sizeof(WOLFSSL_SESSION);
+#ifdef HAVE_EXT_CACHE
+ (void)idx;
+#endif
+
+ return size;
}
+#ifdef HAVE_EXT_CACHE
+/* convert opaque to 16 bit integer */
+static INLINE void ato16(const byte* c, word16* u16)
+{
+ *u16 = (word16) ((c[0] << 8) | (c[1]));
+}
+/* convert opaque to 32 bit integer */
+static INLINE void ato32(const byte* c, word32* u32)
+{
+ *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
+}
+#endif
+
+/* TODO: no function to free new session. */
WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
const unsigned char** p, long i)
{
+ WOLFSSL_SESSION* s = NULL;
+ int ret = 0;
+#if defined(HAVE_EXT_CACHE)
+ int idx;
+ byte* data;
+#ifdef SESSION_CERTS
+ int j;
+ word16 length;
+#endif
+#endif
+
(void)p;
(void)i;
- if (sess)
- return *sess;
- return NULL;
+ (void)ret;
+
+ if (sess != NULL)
+ s = *sess;
+
+#ifdef HAVE_EXT_CACHE
+ if (p == NULL || *p == NULL)
+ return NULL;
+
+ if (s == NULL) {
+ s = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (s == NULL)
+ return NULL;
+ s->isAlloced = 1;
+ s->isDynamic = 0;
+ }
+
+ idx = 0;
+ data = (byte*)*p;
+
+ /* bornOn | timeout | sessionID len */
+ if (i < OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
+ ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
+ s->sessionIDSz = data[idx++];
+
+ /* sessionID | secret | haveEMS */
+ if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
+ idx += s->sessionIDSz;
+ XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
+ s->haveEMS = data[idx++];
+
+#ifdef SESSION_CERTS
+ /* Certificate chain */
+ if (i - idx == 0) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ s->chain.count = data[idx++];
+ for (j = 0; j < s->chain.count; j++) {
+ if (i - idx < OPAQUE16_LEN) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ ato16(data + idx, &length); idx += OPAQUE16_LEN;
+ s->chain.certs[j].length = length;
+ if (i - idx < length) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
+ idx += length;
+ }
+
+ /* Protocol Version | Cipher suite */
+ if (i - idx < OPAQUE16_LEN + OPAQUE16_LEN) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ s->version.major = data[idx++];
+ s->version.minor = data[idx++];
+ s->cipherSuite0 = data[idx++];
+ s->cipherSuite = data[idx++];
+#endif
+#ifndef NO_CLIENT_CACHE
+ /* ServerID len */
+ if (i - idx < OPAQUE16_LEN) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
+
+ /* ServerID */
+ if (i - idx < s->idLen) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
+#endif
+#ifdef HAVE_SESSION_TICKET
+ /* ticket len */
+ if (i - idx < OPAQUE16_LEN) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
+
+ /* Dispose of ol dynamic ticket and ensure space for new ticket. */
+ if (s->isDynamic)
+ XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
+ if (s->ticketLen <= SESSION_TICKET_LEN)
+ s->ticket = s->staticTicket;
+ else {
+ s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
+ DYNAMIC_TYPE_SESSION_TICK);
+ if (s->ticket == NULL) {
+ ret = MEMORY_ERROR;
+ goto end;
+ }
+ s->isDynamic = 1;
+ }
+
+ /* ticket */
+ if (i - idx < s->ticketLen) {
+ ret = BUFFER_ERROR;
+ goto end;
+ }
+ XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
+#endif
+ (void)idx;
+
+ if (sess != NULL)
+ *sess = s;
+
+ *p += idx;
+
+end:
+ if (ret != 0 && (sess == NULL || *sess != s))
+ wolfSSL_SESSION_free(s);
+#endif
+ return s;
}
@@ -17534,6 +18472,14 @@ void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
}
}
+int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, int len,
+ const EVP_MD* md, void* impl)
+{
+ (void)impl;
+ wolfSSL_HMAC_Init(ctx, key, len, md);
+ return 1;
+}
+
void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
int len)
@@ -17821,7 +18767,47 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
return 0;
}
+int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
+{
+ const char *name = (const char *)cipher;
+ WOLFSSL_MSG("wolfSSL_EVP_CIPHER_iv_length");
+#ifndef NO_AES
+ if ((XSTRNCMP(name, EVP_AES_128_CBC, XSTRLEN(EVP_AES_128_CBC)) == 0) ||
+ (XSTRNCMP(name, EVP_AES_192_CBC, XSTRLEN(EVP_AES_192_CBC)) == 0) ||
+ (XSTRNCMP(name, EVP_AES_256_CBC, XSTRLEN(EVP_AES_256_CBC)) == 0)) {
+ return AES_BLOCK_SIZE;
+ }
+#ifdef WOLFSSL_AES_COUNTER
+ if ((XSTRNCMP(name, EVP_AES_128_CTR, XSTRLEN(EVP_AES_128_CTR)) == 0) ||
+ (XSTRNCMP(name, EVP_AES_192_CTR, XSTRLEN(EVP_AES_192_CTR)) == 0) ||
+ (XSTRNCMP(name, EVP_AES_256_CTR, XSTRLEN(EVP_AES_256_CTR)) == 0)) {
+ return AES_BLOCK_SIZE;
+ }
+#endif
+#endif
+
+#ifndef NO_DES3
+ if ((XSTRNCMP(name, EVP_DES_CBC, XSTRLEN(EVP_DES_CBC)) == 0) ||
+ (XSTRNCMP(name, EVP_DES_EDE3_CBC, XSTRLEN(EVP_DES_EDE3_CBC)) == 0)) {
+ return DES_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef HAVE_IDEA
+ if (XSTRNCMP(name, EVP_IDEA_CBC, XSTRLEN(EVP_IDEA_CBC)) == 0)
+ return IDEA_BLOCK_SIZE;
+#endif
+
+ (void)name;
+
+ return 0;
+}
+
+/* Free the dynamically allocated data.
+ *
+ * p Pointer to dynamically allocated memory.
+ */
void wolfSSL_OPENSSL_free(void* p)
{
WOLFSSL_MSG("wolfSSL_OPENSSL_free");
@@ -18251,7 +19237,8 @@ static int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
key = (ecc_key*)eckey->internal;
- /* set group (nid and idx) */
+ /* set group (OID, nid and idx) */
+ eckey->group->curve_oid = ecc_sets[key->idx].oidSum;
eckey->group->curve_nid = ecc_sets[key->idx].id;
eckey->group->curve_idx = key->idx;
@@ -18425,6 +19412,7 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
for (x = 0; ecc_sets[x].size != 0; x++)
if (ecc_sets[x].id == key->group->curve_nid) {
key->group->curve_idx = x;
+ key->group->curve_oid = ecc_sets[x].oidSum;
break;
}
@@ -18758,6 +19746,7 @@ WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
for (x = 0; ecc_sets[x].size != 0; x++)
if (ecc_sets[x].id == g->curve_nid) {
g->curve_idx = x;
+ g->curve_oid = ecc_sets[x].oidSum;
break;
}
@@ -20293,10 +21282,13 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
#ifndef NO_CERTS
WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
- pem_password_cb *cb, void *u) {
+ pem_password_cb *cb, void *u)
+ {
+#ifndef NO_FILESYSTEM
WOLFSSL_X509* x509 = NULL;
- const unsigned char* pem = NULL;
+ unsigned char* pem = NULL;
int pemSz;
+ int pemAlloced = 0;
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
@@ -20305,12 +21297,45 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
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;
+ if (bp->type == BIO_MEMORY) {
+ 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;
+ }
}
+ else if (bp->type == BIO_FILE) {
+ long i;
+ long l;
+
+ /* Read in next certificate from file but no more. */
+ i = XFTELL(bp->file);
+ XFSEEK(bp->file, 0, SEEK_END);
+ l = XFTELL(bp->file);
+ XFSEEK(bp->file, i, SEEK_SET);
+ pem = (unsigned char*)XMALLOC(l - i, 0, DYNAMIC_TYPE_TMP_BUFFER);
+ if (pem == NULL)
+ return NULL;
+ pemAlloced = 1;
+
+ i = 0;
+ /* TODO: Inefficient
+ * reading in one byte at a time until see END_CERT
+ */
+ while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
+ i++;
+ if (i > 26 && XMEMCMP((char *)&pem[i-26], END_CERT, 25) == 0)
+ break;
+ }
+ #ifdef WOLFSSL_NGINX
+ if (l == 0)
+ wc_last_error = ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE);
+ #endif
+ pemSz = (int)i;
+ }
+ else
+ return NULL;
x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
SSL_FILETYPE_PEM);
@@ -20319,10 +21344,20 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
*x = x509;
}
+ if (pemAlloced)
+ XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
(void)cb;
(void)u;
return x509;
+#else
+ (void)bp;
+ (void)x;
+ (void)cb;
+ (void)u;
+ return NULL;
+#endif
}
@@ -20346,7 +21381,16 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
}
#endif /* ifndef NO_CERTS */
-#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL)
+#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(OPENSSL_EXTRA)
+ #ifndef NO_CERTS
+ void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){
+ FreeX509Name(name, NULL);
+ WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
+ }
+ #endif /* NO_CERTS */
+#endif
+
+#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md)
{
@@ -20357,13 +21401,41 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
return NULL;
}
- char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x) {
- (void)ctx;
- (void)x;
- WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
- WOLFSSL_STUB("wolfSSL_CTX_use_certificate");
+ char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
+ {
+ int ret;
- return 0;
+ WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
+
+ FreeDer(&ctx->certificate); /* Make sure previous is free'd */
+ ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
+ ctx->heap);
+ if (ret != 0)
+ return 0;
+
+ XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
+ x->derCert->length);
+#ifdef KEEP_OUR_CERT
+ if (ctx->ourCert != NULL && ctx->ownOurCert) {
+ FreeX509(ctx->ourCert);
+ XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
+ }
+ ctx->ourCert = x;
+ ctx->ownOurCert = 0;
+#endif
+
+ /* Update the available options with public keys. */
+ switch (x->pubKeyOID) {
+ case RSAk:
+ ctx->haveRSA = 1;
+ break;
+ case ECDSAk:
+ ctx->haveECC = 1;
+ ctx->pkCurveOID = x->pkCurveOID;
+ break;
+ }
+
+ return SSL_SUCCESS;
}
int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
@@ -20401,6 +21473,11 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
int i;
WOLFSSL_ENTER("wolfSSL_OBJ_osn2nid");
+ /* Nginx uses this OpenSSL string. */
+ if (XSTRNCMP(sn, "prime256v1", 10) == 0)
+ sn = "SECP256R1";
+ if (XSTRNCMP(sn, "secp384r1", 10) == 0)
+ sn = "SECP384R1";
/* find based on name and return NID */
for (i = 0; i < ecc_sets[i].size; i++) {
if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
@@ -20420,6 +21497,14 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
}
+ void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth) {
+ (void)ssl;
+ (void)depth;
+ WOLFSSL_ENTER("wolfSSL_set_verify_depth");
+ WOLFSSL_STUB("wolfSSL_set_verify_depth");
+
+ }
+
void* wolfSSL_get_app_data( const WOLFSSL *ssl)
{
/* checkout exdata stuff... */
@@ -20476,14 +21561,6 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
return NULL;
}
-#ifndef NO_CERTS
- void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){
- FreeX509Name(name, NULL);
- WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
- WOLFSSL_STUB("wolfSSL_X509_NAME_free");
- }
-#endif /* NO_CERTS */
-
void wolfSSL_sk_X509_NAME_pop_free(STACK_OF(WOLFSSL_X509_NAME)* sk, void f (WOLFSSL_X509_NAME*)){
(void) sk;
(void) f;
@@ -20523,7 +21600,7 @@ unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
(void)line;
(void)file;
-#if defined(DEBUG_WOLFSSL)
+#if defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL)
{
int ret;
@@ -20558,7 +21635,7 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
{
WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
- #ifdef HAVE_STUNNEL
+ #ifdef HAVE_EX_DATA
if(ctx != NULL && idx < MAX_EX_DATA && idx >= 0) {
return ctx->ex_data[idx];
}
@@ -20569,24 +21646,26 @@ void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
return NULL;
}
-
int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
void* c)
{
+ static int ctx_idx = 0;
+
WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
(void)idx;
(void)arg;
(void)a;
(void)b;
(void)c;
- return 0;
+
+ return ctx_idx++;
}
int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
{
WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
- #ifdef HAVE_STUNNEL
+ #ifdef HAVE_EX_DATA
if (ctx != NULL && idx < MAX_EX_DATA)
{
ctx->ex_data[idx] = data;
@@ -20604,7 +21683,7 @@ int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
{
WOLFSSL_ENTER("wolfSSL_set_ex_data");
-#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
if (ssl != NULL && idx < MAX_EX_DATA)
{
ssl->ex_data[idx] = data;
@@ -20622,20 +21701,23 @@ int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
int wolfSSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
void* cb3)
{
+ static int ssl_idx = 0;
+
WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
(void)idx;
(void)data;
(void)cb1;
(void)cb2;
(void)cb3;
- return 0;
+
+ return ssl_idx++;
}
void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
{
WOLFSSL_ENTER("wolfSSL_get_ex_data");
-#if defined(FORTRESS) || defined(HAVE_STUNNEL)
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
if (ssl != NULL && idx < MAX_EX_DATA && idx >= 0)
return ssl->ex_data[idx];
#else
@@ -20652,7 +21734,7 @@ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
WOLFSSL_DSA* dsa;
DsaKey* key;
int length;
- const unsigned char* buf;
+ unsigned char* buf;
word32 bufSz;
int ret;
word32 idx = 0;
@@ -20766,38 +21848,202 @@ int wolfSSL_OBJ_txt2nid(const char* s) {
}
-WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode) {
+WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode)
+{
+#ifndef NO_FILESYSTEM
+ WOLFSSL_BIO* bio;
+ XFILE fp;
+
+ WOLFSSL_ENTER("wolfSSL_BIO_new_file");
+
+ fp = XFOPEN(filename, mode);
+ if (fp == NULL)
+ return NULL;
+
+ bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+ if (bio == NULL)
+ return bio;
+
+ if (wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE) != SSL_SUCCESS) {
+ wolfSSL_BIO_free(bio);
+ bio = NULL;
+ }
+
+ return bio;
+#else
(void)filename;
(void)mode;
- WOLFSSL_ENTER("wolfSSL_BIO_new_file");
- WOLFSSL_STUB("wolfSSL_BIO_new_file");
-
return NULL;
+#endif
}
-WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x,
+#ifndef NO_DH
+WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x,
pem_password_cb *cb, void *u)
{
- (void) bp;
- (void) x;
- (void) cb;
- (void) u;
+#ifndef NO_FILESYSTEM
+ WOLFSSL_DH* localDh = NULL;
+ unsigned char* mem = NULL;
+ word32 size;
+ long sz;
+ int ret;
+ DerBuffer *der = NULL;
+ byte* p = NULL;
+ byte* g = NULL;
+ word32 pSz = MAX_DH_SIZE;
+ word32 gSz = MAX_DH_SIZE;
+ int memAlloced = 0;
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
- WOLFSSL_STUB("wolfSSL_PEM_read_bio_DHparams");
+ (void)cb;
+ (void)u;
- return NULL;
-}
+ if (bio == NULL) {
+ WOLFSSL_MSG("Bad Function Argument bio is NULL");
+ return NULL;
+ }
+ if (bio->type == BIO_MEMORY) {
+ /* Use the buffer directly. */
+ ret = wolfSSL_BIO_get_mem_data(bio, &mem);
+ if (mem == NULL || ret <= 0) {
+ WOLFSSL_MSG("Failed to get data from bio struct");
+ goto end;
+ }
+ size = ret;
+ }
+ else if (bio->type == BIO_FILE) {
+ /* Read whole file into a new buffer. */
+ XFSEEK(bio->file, 0, SEEK_END);
+ sz = XFTELL(bio->file);
+ XFSEEK(bio->file, 0, SEEK_SET);
+ if (sz <= 0L)
+ goto end;
+ mem = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (mem == NULL)
+ goto end;
+ memAlloced = 1;
-int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) {
- (void)bp;
+ if (wolfSSL_BIO_read(bio, (char *)mem, (int)sz) <= 0)
+ goto end;
+ size = (word32)sz;
+ }
+ else {
+ WOLFSSL_MSG("BIO type not supported for reading DH parameters");
+ goto end;
+ }
+
+ ret = PemToDer(mem, size, DH_PARAM_TYPE, &der, NULL, NULL, NULL);
+ if (ret != 0)
+ goto end;
+
+ /* Use the object passed in, otherwise allocate a new object */
+ if (x != NULL)
+ localDh = *x;
+ if (localDh == NULL) {
+ localDh = (WOLFSSL_DH*)XMALLOC(sizeof(WOLFSSL_DH), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (localDh == NULL)
+ goto end;
+ XMEMSET(localDh, 0, sizeof(WOLFSSL_DH));
+ }
+
+ /* Load data in manually */
+ p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (p == NULL || g == NULL)
+ goto end;
+
+ /* Extract the p and g as data from the DER encoded DH parameters. */
+ ret = wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz);
+ if (ret != 0) {
+ if (x != NULL && localDh != *x)
+ XFREE(localDh, NULL, DYNAMIC_TYPE_OPENSSL);
+ localDh = NULL;
+ goto end;
+ }
+
+ if (x != NULL)
+ *x = localDh;
+
+ /* Put p and g in as big numbers. */
+ if (localDh->p != NULL) {
+ wolfSSL_BN_free(localDh->p);
+ localDh->p = NULL;
+ }
+ if (localDh->g != NULL) {
+ wolfSSL_BN_free(localDh->g);
+ localDh->g = NULL;
+ }
+ localDh->p = wolfSSL_BN_bin2bn(p, pSz, NULL);
+ localDh->g = wolfSSL_BN_bin2bn(g, gSz, NULL);
+ if (localDh->p == NULL || localDh->g == NULL) {
+ if (x != NULL && localDh != *x)
+ wolfSSL_DH_free(localDh);
+ localDh = NULL;
+ }
+
+end:
+ if (memAlloced) XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (der != NULL) FreeDer(&der);
+ XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(g, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return localDh;
+#else
+ (void)bio;
(void)x;
- WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
- WOLFSSL_STUB("wolfSSL_PEM_write_bio_X509");
+ (void)cb;
+ (void)u;
+ return NULL;
+#endif
+}
+#endif
- return 0;
+
+int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
+{
+ byte* certDer;
+ int derSz;
+ int pemSz;
+ int ret;
+
+ WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
+
+ if (bio == NULL || cert == NULL) {
+ return SSL_FAILURE;
+ }
+
+ if (bio->type != BIO_MEMORY) {
+ WOLFSSL_MSG("BIO type not supported for writing X509 as PEM");
+ return SSL_FAILURE;
+ }
+
+ certDer = cert->derCert->buffer;
+ derSz = cert->derCert->length;
+
+ /* Get PEM encoded length and allocate memory for it. */
+ pemSz = wc_DerToPem(certDer, derSz, NULL, 0, CERT_TYPE);
+ if (pemSz < 0) {
+ WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_X509", pemSz);
+ return SSL_FAILURE;
+ }
+ if (bio->mem != NULL) {
+ XFREE(bio->mem, NULL, DYNAMIC_TYPE_OPENSSL);
+ }
+ bio->mem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_OPENSSL);
+ if (bio->mem != NULL) {
+ return SSL_FAILURE;
+ }
+ bio->memLen = pemSz;
+
+ ret = wc_DerToPemEx(certDer, derSz, bio->mem, bio->memLen, NULL, CERT_TYPE);
+ if (ret < 0) {
+ WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_X509", ret);
+ return SSL_FAILURE;
+ }
+
+ return SSL_SUCCESS;
}
@@ -20847,7 +22093,7 @@ long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
/* stunnel compatibility functions*/
-#if defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)
+#if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX))
void WOLFSSL_ERR_remove_thread_state(void* pid)
{
(void) pid;
@@ -20863,10 +22109,12 @@ void wolfSSL_print_all_errors_fp(XFILE *fp)
int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
{
WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
+#ifdef HAVE_EX_DATA
if(session != NULL && idx < MAX_EX_DATA) {
session->ex_data[idx] = data;
return SSL_SUCCESS;
}
+#endif
return SSL_FAILURE;
}
@@ -20892,8 +22140,10 @@ int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
{
WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
+#ifdef HAVE_EX_DATA
if (session != NULL && idx < MAX_EX_DATA && idx >= 0)
return session->ex_data[idx];
+#endif
return NULL;
}
@@ -20949,11 +22199,13 @@ void wolfSSL_ERR_load_crypto_strings(void)
unsigned long wolfSSL_ERR_peek_last_error(void)
{
- unsigned long l = 0UL;
WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
- WOLFSSL_STUB("wolfSSL_ERR_peek_last_error");
- return l;
+#if defined(OPENSSL_ERR_ONE)
+ return wc_last_error;
+#else
+ return (unsigned long)(0 - NOT_COMPILED_IN);
+#endif
}
@@ -21001,35 +22253,40 @@ int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
int wolfSSL_sk_X509_NAME_num(const STACK_OF(WOLFSSL_X509_NAME) *s)
{
- (void) s;
WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
- WOLFSSL_STUB("wolfSSL_sk_X509_NAME_num");
- return SSL_FAILURE;
+ if (s == NULL)
+ return -1;
+ return (int)s->num;
}
int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s)
{
- (void) s;
WOLFSSL_ENTER("wolfSSL_sk_X509_num");
- WOLFSSL_STUB("wolfSSL_sk_X509_num");
- return SSL_FAILURE;
+ if (s == NULL)
+ return -1;
+ return (int)s->num;
}
-int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* nm,
+int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
int indent, unsigned long flags)
{
- (void)bio;
- (void)nm;
- (void)indent;
+ int i;
(void)flags;
WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
- WOLFSSL_STUB("wolfSSL_X509_NAME_print_ex");
- return SSL_FAILURE;
+ for (i = 0; i < indent; i++)
+ BIO_write(bio, " ", 1);
+
+ if (flags == XN_FLAG_RFC2253)
+ BIO_write(bio, name->name + 1, name->sz - 2);
+ else
+ BIO_write(bio, name->name, name->sz);
+
+ return SSL_SUCCESS;
}
@@ -21066,23 +22323,27 @@ int wolfSSL_get_state(const WOLFSSL* ssl)
void* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
{
- (void)sk;
- (void)i;
WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
- WOLFSSL_STUB("wolfSSL_sk_X509_NAME_value");
- return NULL;
+ for (; sk != NULL && i > 0; i--)
+ sk = sk->next;
+
+ if (i != 0 || sk == NULL)
+ return NULL;
+ return sk->data.name;
}
void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
{
- (void)sk;
- (void)i;
WOLFSSL_ENTER("wolfSSL_sk_X509_value");
- WOLFSSL_STUB("wolfSSL_sk_X509_value");
- return NULL;
+ for (; sk != NULL && i > 0; i--)
+ sk = sk->next;
+
+ if (i != 0 || sk == NULL)
+ return NULL;
+ return sk->data.x509;
}
@@ -21200,6 +22461,16 @@ void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
ctx->sniRecvCb = cb;
}
+int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
+ CallbackSniRecv cb)
+{
+ WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
+ if (ctx) {
+ ctx->sniRecvCb = cb;
+ return 1;
+ }
+ return 0;
+}
void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
{
@@ -21257,7 +22528,7 @@ void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*)
#if (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
- || defined(WOLFSSL_MYSQL_COMPATIBLE)
+ || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx)
{
int mode = 0;
@@ -21672,6 +22943,697 @@ int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
}
#endif /* WOLFSSL_ASYNC_CRYPT */
+#if defined(WOLFSSL_NGINX)
+void wolfSSL_OPENSSL_config(char *config_name)
+{
+ WOLFSSL_STUB("wolfSSL_OPENSSL_config");
+ (void)config_name;
+}
+
+int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c)
+{
+ static int x509_idx = 0;
+
+ WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
+ (void)idx;
+ (void)arg;
+ (void)a;
+ (void)b;
+ (void)c;
+
+ return x509_idx++;
+}
+
+void *wolfSSL_X509_get_ex_data(X509 *x509, int idx)
+{
+ WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
+ #ifdef HAVE_EX_DATA
+ if (x509 != NULL && idx < MAX_EX_DATA && idx >= 0) {
+ return x509->ex_data[idx];
+ }
+ #else
+ (void)x509;
+ (void)idx;
+ #endif
+ return NULL;
+}
+int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data)
+{
+ WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
+ #ifdef HAVE_EX_DATA
+ if (x509 != NULL && idx < MAX_EX_DATA)
+ {
+ x509->ex_data[idx] = data;
+ return SSL_SUCCESS;
+ }
+ #else
+ (void)x509;
+ (void)idx;
+ (void)data;
+ #endif
+ return SSL_FAILURE;
+}
+int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
+ const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
+{
+ WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
+
+ if (name == NULL || type == NULL)
+ return SSL_FAILURE;
+
+ return wolfSSL_EVP_Digest((unsigned char*)name->fullName.fullName,
+ name->fullName.fullNameLen, md, len, type, NULL);
+}
+
+long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
+
+ if (ctx == NULL)
+ return 0;
+
+ return ctx->timeout;
+}
+
+#ifdef HAVE_ECC
+int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
+
+ if (ctx == NULL || ecdh == NULL)
+ return BAD_FUNC_ARG;
+
+ ctx->ecdhCurveOID = ecdh->group->curve_oid;
+
+ return SSL_SUCCESS;
+}
+#endif
+
+/* Assumes that the session passed in is from the cache. */
+int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
+
+ if (ctx == NULL || s == NULL)
+ return BAD_FUNC_ARG;
+
+#ifdef HAVE_EXT_CACHE
+ if (!ctx->internalCacheOff)
+#endif
+ {
+ /* Don't remove session just timeout session. */
+ s->timeout = 0;
+ }
+
+#ifdef HAVE_EXT_CACHE
+ if (ctx->rem_sess_cb != NULL)
+ ctx->rem_sess_cb(ctx, s);
+#endif
+
+ return 0;
+}
+
+BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
+ (void)s;
+ /* Nginx sets the buffer size if the read BIO is different to write BIO.
+ * The setting buffer size doesn't do anything so return NULL for both.
+ */
+ return NULL;
+}
+BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
+ (void)s;
+ /* Nginx sets the buffer size if the read BIO is different to write BIO.
+ * The setting buffer size doesn't do anything so return NULL for both.
+ */
+ return NULL;
+}
+
+int wolfSSL_SSL_do_handshake(WOLFSSL *s)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
+
+ if (s == NULL)
+ return SSL_FAILURE;
+
+ if (s->options.side == WOLFSSL_CLIENT_END)
+ return wolfSSL_connect(s);
+ return wolfSSL_accept(s);
+}
+
+int wolfSSL_SSL_in_init(WOLFSSL *s)
+{
+ WOLFSSL_ENTER("wolfSSL_SSL_in_init");
+
+ if (s == NULL)
+ return SSL_FAILURE;
+
+ if (s->options.side == WOLFSSL_CLIENT_END)
+ return s->options.connectState < SECOND_REPLY_DONE;
+ return s->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
+}
+
+WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
+{
+ WOLFSSL_SESSION *session;
+
+ WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
+
+ if (ssl == NULL) {
+ return NULL;
+ }
+
+ session = wolfSSL_get_session((WOLFSSL*)ssl);
+
+#ifdef HAVE_EXT_CACHE
+ ((WOLFSSL*)ssl)->extSession = session;
+#endif
+
+ return session;
+}
+
+int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen,
+ unsigned int flags, char **peername)
+{
+ int ret;
+ DecodedCert dCert;
+
+ WOLFSSL_ENTER("wolfSSL_X509_check_host");
+
+ /* flags and peername not needed for Nginx. */
+ (void)flags;
+ (void)peername;
+
+ InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
+ ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
+ if (ret != 0)
+ return SSL_FAILURE;
+
+ ret = CheckHostName(&dCert, (char *)chk, chklen);
+ FreeDecodedCert(&dCert);
+ if (ret != 0)
+ return SSL_FAILURE;
+ return SSL_SUCCESS;
+}
+
+int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
+{
+ static char num[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ int i;
+ word32 j;
+ word32 len = 0;
+
+ WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
+
+ if (bp == NULL || a == NULL)
+ return SSL_FAILURE;
+
+ /* Skip ASN.1 INTEGER (type) byte. */
+ i = 1;
+ /* When indefinte length, can't determine length with data available. */
+ if (a->data[i] == 0x80)
+ return 0;
+ /* One length byte if less than 0x80. */
+ if (a->data[i] < 0x80)
+ len = a->data[i++];
+ /* Multiple length byte if greater than 0x80. */
+ else if (a->data[i] > 0x80) {
+ switch (a->data[i++] - 0x80) {
+ case 4:
+ len |= a->data[i++] << 24;
+ case 3:
+ len |= a->data[i++] << 16;
+ case 2:
+ len |= a->data[i++] << 8;
+ case 1:
+ len |= a->data[i++];
+ break;
+ default:
+ /* Not supporting greater than 4 bytes of length. */
+ return 0;
+ }
+ }
+
+ /* Zero length integer is the value zero. */
+ if (len == 0) {
+ wolfSSL_BIO_write(bp, "00", 2);
+ return 2;
+ }
+
+ /* Don't do negative - just write out every byte. */
+ for (j = 0; j < len; i++,j++) {
+ wolfSSL_BIO_write(bp, &num[a->data[i] >> 4], 1);
+ wolfSSL_BIO_write(bp, &num[a->data[i] & 0xf], 1);
+ }
+
+ /* Two nibbles written for each byte. */
+ return len * 2;
+}
+
+unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
+ const char **data, int *flags)
+{
+ WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
+
+ (void)line;
+ (void)file;
+
+ /* No data or flags stored - error display only in Nginx. */
+ if (data != NULL) {
+ *data = "";
+ }
+ if (flags != NULL) {
+ *flags = 0;
+ }
+
+#if defined(OPENSSL_ERR_ONE)
+ 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
+
+}
+
+#ifdef HAVE_SESSION_TICKET
+/* The ticket key callback as used in OpenSSL is stored here. */
+static int (*ticketKeyCb)(WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
+ WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc) = NULL;
+
+/* Implementation of session ticket encryption/decryption using OpenSSL
+ * callback to initialize the cipher and HMAC.
+ *
+ * ssl The SSL/TLS object.
+ * keyName The key name - used to identify the key to be used.
+ * iv The IV to use.
+ * mac The MAC of the encrypted data.
+ * enc Encrypt ticket.
+ * encTicket The ticket data.
+ * encTicketLen The length of the ticket data.
+ * encLen The encrypted/decrypted ticket length - output length.
+ * ctx Ignored. Application specific data.
+ * returns WOLFSSL_TICKET_RET_OK to indicate success,
+ * WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
+ * WOLFSSL_TICKET_RET_FATAL on error.
+ */
+static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
+ unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
+ unsigned char iv[WOLFSSL_TICKET_IV_SZ],
+ unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
+ int enc, unsigned char* encTicket,
+ int encTicketLen, int* encLen, void* ctx)
+{
+ byte digest[MAX_DIGEST_SIZE];
+ WOLFSSL_EVP_CIPHER_CTX evpCtx;
+ WOLFSSL_HMAC_CTX hmacCtx;
+ unsigned int mdSz = 0;
+ int len = 0;
+ int ret = WOLFSSL_TICKET_RET_FATAL;
+ int res;
+
+ (void)ctx;
+
+ wolfSSL_EVP_CIPHER_CTX_init(&evpCtx);
+ /* Initialize the cipher and HMAC. */
+ res = ticketKeyCb(ssl, keyName, iv, &evpCtx, &hmacCtx, enc);
+ if (res != 1 && res != 2)
+ return WOLFSSL_TICKET_RET_FATAL;
+
+ if (enc)
+ {
+ /* Encrypt in place. */
+ if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
+ encTicket, encTicketLen))
+ goto end;
+ encTicketLen = len;
+ if (!wolfSSL_EVP_EncryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
+ goto end;
+ /* Total length of encrypted data. */
+ encTicketLen += len;
+ *encLen = encTicketLen;
+
+ /* HMAC the encrypted data into the parameter 'mac'. */
+ wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen);
+ wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz);
+ }
+ else
+ {
+ /* HMAC the encrypted data and compare it to the passed in data. */
+ wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen);
+ wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz);
+ if (XMEMCMP(mac, digest, mdSz) != 0)
+ goto end;
+
+ /* Decrypt the ticket data in place. */
+ if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
+ encTicket, encTicketLen))
+ goto end;
+ encTicketLen = len;
+ if (!wolfSSL_EVP_DecryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
+ goto end;
+ /* Total length of decrypted data. */
+ *encLen = encTicketLen + len;
+ }
+
+ ret = (res == 2) ? WOLFSSL_TICKET_RET_CREATE : WOLFSSL_TICKET_RET_OK;
+end:
+ return ret;
+}
+
+/* Set the callback to use when encrypting/decrypting tickets.
+ *
+ * ctx The SSL/TLS context object.
+ * cb The OpenSSL session ticket callback.
+ * returns SSL_SUCCESS to indicate success.
+ */
+int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, int (*cb)(
+ WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
+ WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc))
+{
+ /* Store callback in a global. */
+ ticketKeyCb = cb;
+ /* Set the ticket encryption callback to be a wrapper around OpenSSL
+ * callback.
+ */
+ ctx->ticketEncCb = wolfSSL_TicketKeyCb;
+
+ return SSL_SUCCESS;
+}
+#endif /* HAVE_SESSION_TICKET */
+
+#ifdef HAVE_OCSP
+/* Not an OpenSSL API. */
+int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
+{
+ *response = ssl->ocspResp;
+ return ssl->ocspRespSz;
+}
+
+/* Not an OpenSSL API. */
+char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
+{
+ return ssl->url;
+}
+
+/* Not an OpenSSL API. */
+int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
+{
+ if (ssl == NULL)
+ return SSL_FAILURE;
+
+ ssl->url = url;
+ return SSL_SUCCESS;
+}
+
+static INLINE void ato24(const byte* c, word32* u24)
+{
+ *u24 = (c[0] << 16) | (c[1] << 8) | c[2];
+}
+
+int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, STACK_OF(X509)** chain)
+{
+ word32 idx;
+ word32 length;
+ WOLFSSL_STACK* node;
+ WOLFSSL_STACK* last = NULL;
+
+ if (ctx == NULL || chain == NULL) {
+ chain = NULL;
+ return SSL_FAILURE;
+ }
+ if (ctx->x509Chain != NULL) {
+ *chain = ctx->x509Chain;
+ return SSL_SUCCESS;
+ }
+
+ /* If there are no chains then success! */
+ *chain = NULL;
+ if (ctx->certChain == NULL || ctx->certChain->length == 0) {
+ return SSL_SUCCESS;
+ }
+
+ /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
+ for (idx = 0; idx < ctx->certChain->length; ) {
+ node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (node == NULL)
+ return SSL_FAILURE;
+ node->next = NULL;
+
+ /* 3 byte length | X509 DER data */
+ ato24(ctx->certChain->buffer + idx, &length);
+ idx += 3;
+
+ /* Create a new X509 from DER encoded data. */
+ node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
+ length);
+ if (node->data.x509 == NULL) {
+ XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
+ /* Return as much of the chain as we created. */
+ ctx->x509Chain = *chain;
+ return SSL_FAILURE;
+ }
+ idx += length;
+
+ /* Add object to the end of the stack. */
+ if (last == NULL) {
+ node->num = 1;
+ *chain = node;
+ }
+ else {
+ (*chain)->num++;
+ last->next = node;
+ }
+
+ last = node;
+ }
+
+ ctx->x509Chain = *chain;
+
+ return SSL_SUCCESS;
+}
+
+int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx,
+ int(*cb)(WOLFSSL*, void*))
+{
+ if (ctx == NULL || ctx->cm == NULL)
+ return SSL_FAILURE;
+
+ /* Ensure stapling is on for callback to be used. */
+ wolfSSL_CTX_EnableOCSPStapling(ctx);
+
+ if (ctx->cm->ocsp_stapling == NULL)
+ return SSL_FAILURE;
+
+ ctx->cm->ocsp_stapling->statusCb = cb;
+ return SSL_SUCCESS;
+}
+
+int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
+ WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
+{
+ WOLFSSL_STACK* node;
+ Signer* ca = NULL;
+#ifdef WOLFSSL_SMALL_STACK
+ DecodedCert* cert = NULL;
+#else
+ DecodedCert cert[1];
+#endif
+
+ if (issuer == NULL || ctx == NULL || x == NULL)
+ return SSL_FATAL_ERROR;
+
+ if (ctx->chain != NULL) {
+ for (node = ctx->chain; node != NULL; node = node->next) {
+ if (wolfSSL_X509_check_issued(node->data.x509, x) == X509_V_OK) {
+ *issuer = x;
+ return SSL_SUCCESS;
+ }
+ }
+ }
+
+
+#ifdef WOLFSSL_SMALL_STACK
+ cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (cert == NULL)
+ return NULL;
+#endif
+
+ /* Use existing CA retrieval APIs that use DecodedCert. */
+ InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, NULL);
+ if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
+ #ifndef NO_SKID
+ if (cert->extAuthKeyIdSet)
+ ca = GetCA(ctx->store->cm, cert->extAuthKeyId);
+ if (ca == NULL)
+ ca = GetCAByName(ctx->store->cm, cert->issuerHash);
+ #else /* NO_SKID */
+ ca = GetCA(ctx->store->cm, cert->issuerHash);
+ #endif /* NO SKID */
+ }
+ FreeDecodedCert(cert);
+#ifdef WOLFSSL_SMALL_STACK
+ XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+ if (ca == NULL)
+ return SSL_FAILURE;
+
+ *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
+ DYNAMIC_TYPE_OPENSSL);
+ if (*issuer == NULL)
+ return SSL_FAILURE;
+
+ /* Create an empty certificate as CA doesn't have a certificate. */
+ XMEMSET(*issuer, 0, sizeof(WOLFSSL_X509));
+ /* TODO: store the full certificate and dup when required. */
+
+ /* Result is ignored when passed to wolfSSL_OCSP_cert_to_id(). */
+
+ return SSL_SUCCESS;
+}
+
+void wolfSSL_X509_email_free(STACK_OF(WOLFSSL_STRING) *sk)
+{
+ WOLFSSL_STACK *curr;
+
+ while (sk != NULL) {
+ curr = sk;
+ sk = sk->next;
+
+ XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
+ }
+}
+
+STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
+{
+ WOLFSSL_STACK *list = NULL;
+
+ if (x->authInfoSz == 0)
+ return NULL;
+
+ list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
+ DYNAMIC_TYPE_OPENSSL);
+ if (list == NULL)
+ return NULL;
+
+ list->data.string = (char*)x->authInfo;
+ list->next = NULL;
+
+ return list;
+}
+
+int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
+{
+ WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
+ WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
+
+ if (issuerName == NULL || subjectName == NULL)
+ return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+
+ /* Literal matching of encoded names and key ids. */
+ if (issuerName->sz != subjectName->sz ||
+ XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
+ return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+ }
+
+ if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
+ if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
+ XMEMCMP(subject->authKeyId, issuer->subjKeyId,
+ issuer->subjKeyIdSz) != 0) {
+ return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+ }
+ }
+
+ return X509_V_OK;
+}
+
+WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
+{
+ return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length);
+}
+
+char* wolfSSL_sk_WOLFSSL_STRING_value(STACK_OF(WOLFSSL_STRING)* strings,
+ int idx)
+{
+ for (; idx > 0 && strings != NULL; idx--)
+ strings = strings->next;
+ if (strings == NULL)
+ return NULL;
+ return strings->data.string;
+}
+#endif /* HAVE_OCSP */
+
+#ifdef HAVE_ALPN
+void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
+ unsigned int *len)
+{
+ word16 nameLen;
+
+ if (ssl != NULL && data != NULL && len != NULL) {
+ TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
+ *len = nameLen;
+ }
+}
+
+int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
+ const unsigned char *in, unsigned int inLen,
+ const unsigned char *clientNames,
+ unsigned int clientLen)
+{
+ unsigned int i, j;
+ byte lenIn, lenClient;
+
+ if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
+ return OPENSSL_NPN_UNSUPPORTED;
+
+ for (i = 0; i < inLen; i += lenIn) {
+ lenIn = in[i++];
+ for (j = 0; j < clientLen; j += lenClient) {
+ lenClient = clientNames[j++];
+
+ if (lenIn != lenClient)
+ continue;
+
+ if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
+ *out = (unsigned char *)(in + i);
+ *outLen = lenIn;
+ return OPENSSL_NPN_NEGOTIATED;
+ }
+ }
+ }
+
+ *out = (unsigned char *)clientNames + 1;
+ *outLen = clientNames[0];
+ return OPENSSL_NPN_NO_OVERLAP;
+}
+
+void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
+ int (*cb) (WOLFSSL *ssl,
+ const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg), void *arg)
+{
+ if (ctx != NULL) {
+ ctx->alpnSelect = cb;
+ ctx->alpnSelectArg = arg;
+ }
+}
+#endif /* HAVE_ALPN */
+
+#endif /* WOLFSSL_NGINX */
#ifdef OPENSSL_EXTRA
int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
diff --git a/src/tls.c b/src/tls.c
index 3aa5a781b..050067601 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -1095,23 +1095,42 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
TLSX *extension;
ALPN *alpn = NULL, *list;
+ if (OPAQUE16_LEN > length)
+ return BUFFER_ERROR;
+
+ ato16(input, &size);
+ offset += OPAQUE16_LEN;
+
extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
if (extension == NULL)
extension = TLSX_Find(ssl->ctx->extensions,
TLSX_APPLICATION_LAYER_PROTOCOL);
+#ifdef WOLFSSL_NGINX
+ if (ssl->alpnSelect != NULL) {
+ const byte* out;
+ unsigned char outLen;
+
+ if (ssl->alpnSelect(ssl, &out, &outLen, input + offset, size,
+ ssl->alpnSelectArg) == 0) {
+ WOLFSSL_MSG("ALPN protocol match");
+ if (TLSX_UseALPN(&ssl->extensions, (char*)out, outLen, 0, ssl->heap)
+ == SSL_SUCCESS) {
+ if (extension == NULL) {
+ extension = TLSX_Find(ssl->extensions,
+ TLSX_APPLICATION_LAYER_PROTOCOL);
+ }
+ }
+ }
+ }
+#endif
+
if (extension == NULL || extension->data == NULL) {
WOLFSSL_MSG("No ALPN extensions not used or bad");
return isRequest ? 0 /* not using ALPN */
: BUFFER_ERROR; /* unexpected ALPN response */
}
- if (OPAQUE16_LEN > length)
- return BUFFER_ERROR;
-
- ato16(input, &size);
- offset += OPAQUE16_LEN;
-
/* validating alpn list length */
if (length != OPAQUE16_LEN + size)
return BUFFER_ERROR;
@@ -2232,9 +2251,13 @@ int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
if (csr) {
switch (csr->status_type) {
case WOLFSSL_CSR_OCSP:
- if (ssl->ctx->cm->ocspEnabled)
+ if (ssl->ctx->cm->ocspEnabled) {
+ #ifdef WOLFSSL_NGINX
+ csr->request.ocsp.ssl = ssl;
+ #endif
return CheckOcspRequest(ssl->ctx->cm->ocsp,
&csr->request.ocsp, NULL);
+ }
else
return OCSP_LOOKUP_FAIL;
}
@@ -2640,9 +2663,13 @@ int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
/* followed by */
case WOLFSSL_CSR2_OCSP_MULTI:
- if (ssl->ctx->cm->ocspEnabled)
+ if (ssl->ctx->cm->ocspEnabled) {
+ #ifdef WOLFSSL_NGINX
+ csr2->request.ocsp[0].ssl = ssl;
+ #endif
return CheckOcspRequest(ssl->ctx->cm->ocsp,
&csr2->request.ocsp[0], NULL);
+ }
else
return OCSP_LOOKUP_FAIL;
}
@@ -2861,12 +2888,10 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
: NULL;
EllipticCurve* curve = NULL;
word32 oid = 0;
- word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */
int sig = 0; /* validate signature */
int key = 0; /* validate key */
(void)oid;
- (void)octets;
if (!extension)
return 1; /* no suite restriction */
@@ -2879,63 +2904,66 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
switch (curve->name) {
#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP160R1: oid = ECC_SECP160R1_OID; octets = 20; break;
+ case WOLFSSL_ECC_SECP160R1: oid = ECC_SECP160R1_OID; break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_SECPR2
- case WOLFSSL_ECC_SECP160R2: oid = ECC_SECP160R2_OID; octets = 20; break;
+ case WOLFSSL_ECC_SECP160R2: oid = ECC_SECP160R2_OID; break;
#endif /* HAVE_ECC_SECPR2 */
#ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP160K1: oid = ECC_SECP160K1_OID; octets = 20; break;
+ case WOLFSSL_ECC_SECP160K1: oid = ECC_SECP160K1_OID; break;
#endif /* HAVE_ECC_KOBLITZ */
#endif
#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP192R1: oid = ECC_SECP192R1_OID; octets = 24; break;
+ case WOLFSSL_ECC_SECP192R1: oid = ECC_SECP192R1_OID; break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP192K1: oid = ECC_SECP192K1_OID; octets = 24; break;
+ case WOLFSSL_ECC_SECP192K1: oid = ECC_SECP192K1_OID; break;
#endif /* HAVE_ECC_KOBLITZ */
#endif
#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP224R1: oid = ECC_SECP224R1_OID; octets = 28; break;
+ case WOLFSSL_ECC_SECP224R1: oid = ECC_SECP224R1_OID; break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP224K1: oid = ECC_SECP224K1_OID; octets = 28; break;
+ case WOLFSSL_ECC_SECP224K1: oid = ECC_SECP224K1_OID; break;
#endif /* HAVE_ECC_KOBLITZ */
#endif
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP256R1: oid = ECC_SECP256R1_OID; octets = 32; break;
+ case WOLFSSL_ECC_SECP256R1: oid = ECC_SECP256R1_OID; break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_KOBLITZ
- case WOLFSSL_ECC_SECP256K1: oid = ECC_SECP256K1_OID; octets = 32; break;
+ case WOLFSSL_ECC_SECP256K1: oid = ECC_SECP256K1_OID; break;
#endif /* HAVE_ECC_KOBLITZ */
#ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP256R1: oid = ECC_BRAINPOOLP256R1_OID; octets = 32; break;
+ case WOLFSSL_ECC_BRAINPOOLP256R1: oid = ECC_BRAINPOOLP256R1_OID; break;
#endif /* HAVE_ECC_BRAINPOOL */
#endif
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP384R1: oid = ECC_SECP384R1_OID; octets = 48; break;
+ case WOLFSSL_ECC_SECP384R1: oid = ECC_SECP384R1_OID; break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP384R1: oid = ECC_BRAINPOOLP384R1_OID; octets = 48; break;
+ case WOLFSSL_ECC_BRAINPOOLP384R1: oid = ECC_BRAINPOOLP384R1_OID; break;
#endif /* HAVE_ECC_BRAINPOOL */
#endif
#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
#ifdef HAVE_ECC_BRAINPOOL
- case WOLFSSL_ECC_BRAINPOOLP512R1: oid = ECC_BRAINPOOLP512R1_OID; octets = 64; break;
+ case WOLFSSL_ECC_BRAINPOOLP512R1: oid = ECC_BRAINPOOLP512R1_OID; break;
#endif /* HAVE_ECC_BRAINPOOL */
#endif
#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
- case WOLFSSL_ECC_SECP521R1: oid = ECC_SECP521R1_OID; octets = 66; break;
+ case WOLFSSL_ECC_SECP521R1: oid = ECC_SECP521R1_OID; break;
#endif /* !NO_ECC_SECP */
#endif
default: continue; /* unsupported curve */
}
+ if (ssl->ecdhCurveOID == 0)
+ ssl->ecdhCurveOID = oid;
+
if (first == ECC_BYTE) {
switch (second) {
/* ECDHE_ECDSA */
@@ -2950,7 +2978,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
sig |= ssl->pkCurveOID == oid;
- key |= ssl->eccTempKeySz == octets;
+ key |= ssl->ecdhCurveOID == oid;
break;
#ifdef WOLFSSL_STATIC_DH
@@ -2978,7 +3006,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
sig = 1;
- key |= ssl->eccTempKeySz == octets;
+ key |= ssl->ecdhCurveOID == oid;
break;
#ifdef WOLFSSL_STATIC_DH
@@ -3010,14 +3038,14 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
sig |= ssl->pkCurveOID == oid;
- key |= ssl->eccTempKeySz == octets;
+ key |= ssl->ecdhCurveOID == oid;
break;
#ifndef NO_RSA
/* ECDHE_RSA */
case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
sig = 1;
- key |= ssl->eccTempKeySz == octets;
+ key |= ssl->ecdhCurveOID == oid;
break;
#endif
default:
@@ -4568,6 +4596,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
+ #ifndef HAVE_FIPS
#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP160R1, ssl->heap);
@@ -4592,6 +4621,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
if (ret != SSL_SUCCESS) return ret;
#endif
#endif
+ #endif
#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP224R1, ssl->heap);
diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c
index 509364825..992bdae85 100644
--- a/wolfcrypt/src/asn.c
+++ b/wolfcrypt/src/asn.c
@@ -3418,7 +3418,7 @@ static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
}
-#if defined(WOLFSSL_MYSQL_COMPATIBLE)
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
int GetTimeString(byte* date, int format, char* buf, int len)
{
struct tm t;
@@ -5808,7 +5808,7 @@ const char* END_DSA_PRIV = "-----END DSA PRIVATE KEY-----";
const char* BEGIN_PUB_KEY = "-----BEGIN PUBLIC KEY-----";
const char* END_PUB_KEY = "-----END PUBLIC KEY-----";
-#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
+#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA)
/* Used for compatibility API */
int wc_DerToPem(const byte* der, word32 derSz,
@@ -9498,6 +9498,9 @@ static int DecodeSingleResponse(byte* source,
return ASN_PARSE_E;
}
+#ifdef WOLFSSL_NGINX
+ cs->thisDateAsn = source + idx;
+#endif
if (GetBasicDate(source, &idx, cs->thisDate,
&cs->thisDateFormat, size) < 0)
return ASN_PARSE_E;
@@ -9513,6 +9516,9 @@ static int DecodeSingleResponse(byte* source,
idx++;
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
+#ifdef WOLFSSL_NGINX
+ cs->nextDateAsn = source + idx;
+#endif
if (GetBasicDate(source, &idx, cs->nextDate,
&cs->nextDateFormat, size) < 0)
return ASN_PARSE_E;
@@ -9759,7 +9765,9 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
return ASN_PARSE_E;
InitDecodedCert(&cert, resp->cert, resp->certSz, heap);
- ret = ParseCertRelative(&cert, CERT_TYPE, VERIFY, cm);
+ /* Don't verify if we don't have access to Cert Manager. */
+ ret = ParseCertRelative(&cert, CERT_TYPE,
+ cm == NULL ? NO_VERIFY : VERIFY, cm);
if (ret < 0) {
WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
FreeDecodedCert(&cert);
@@ -9818,6 +9826,7 @@ void InitOcspResponse(OcspResponse* resp, CertStatus* status,
int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap)
{
+ int ret;
int length = 0;
word32 idx = 0;
byte* source = resp->source;
@@ -9860,8 +9869,9 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
- if (DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap) < 0)
- return ASN_PARSE_E;
+ ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap);
+ if (ret < 0)
+ return ret;
return 0;
}
@@ -9871,8 +9881,8 @@ word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
{
static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
0x30, 0x01, 0x02 };
- byte seqArray[6][MAX_SEQ_SZ];
- word32 seqSz[6], totalSz = (word32)sizeof(NonceObjId);
+ byte seqArray[5][MAX_SEQ_SZ];
+ word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
WOLFSSL_ENTER("SetOcspReqExtensions");
@@ -9886,16 +9896,12 @@ word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
totalSz += seqSz[2] = 1 + SetLength(sizeof(NonceObjId), &seqArray[2][1]);
totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
- totalSz += seqSz[5] = SetExplicit(2, totalSz, seqArray[5]);
if (totalSz > size)
return 0;
totalSz = 0;
- XMEMCPY(output + totalSz, seqArray[5], seqSz[5]);
- totalSz += seqSz[5];
-
XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
totalSz += seqSz[4];
@@ -9946,8 +9952,14 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
snSz = SetSerialNumber(req->serial, req->serialSz, snArray);
extSz = 0;
- if (req->nonceSz)
- extSz = EncodeOcspRequestExtensions(req, extArray, OCSP_NONCE_EXT_SZ);
+ if (req->nonceSz) {
+ /* TLS Extensions use this function too - put extensions after
+ * ASN.1: Context Specific [2].
+ */
+ extSz = EncodeOcspRequestExtensions(req, extArray + 2,
+ OCSP_NONCE_EXT_SZ);
+ extSz += SetExplicit(2, extSz, extArray);
+ }
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
for (i = 4; i >= 0; i--) {
@@ -9956,6 +9968,8 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
if (i == 2) totalSz += extSz;
}
+ if (output == NULL)
+ return totalSz;
if (totalSz > size)
return BUFFER_E;
diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c
index 019b96366..7687b3691 100644
--- a/wolfcrypt/src/ecc.c
+++ b/wolfcrypt/src/ecc.c
@@ -1195,6 +1195,22 @@ void wc_ecc_curve_cache_free(void)
#endif /* WOLFSSL_ATECC508A */
+/* Retrieve the curve name for the ECC curve id.
+ *
+ * curve_id The id of the curve.
+ * returns the name stored from the curve if available, otherwise NULL.
+ */
+const char* wc_ecc_get_name(int curve_id)
+{
+ int x;
+
+ for (x = 0; ecc_sets[x].size != 0; x++) {
+ if (curve_id == ecc_sets[x].id)
+ return ecc_sets[x].name;
+ }
+
+ return NULL;
+}
static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
{
diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c
index fb9e56edc..9df026163 100644
--- a/wolfcrypt/src/evp.c
+++ b/wolfcrypt/src/evp.c
@@ -277,7 +277,7 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
blocks = inl / ctx->block_size;
if (blocks > 0) {
/* process blocks */
- if (evpCipherBlock(ctx, out, ctx->buf, blocks) == 0)
+ if (evpCipherBlock(ctx, out, in, blocks*ctx->block_size) == 0)
return 0;
PRINT_BUF(ctx->buf, ctx->block_size);
PRINT_BUF(out, ctx->block_size);
diff --git a/wolfssl/internal.h b/wolfssl/internal.h
index a752edeee..2fb249f56 100644
--- a/wolfssl/internal.h
+++ b/wolfssl/internal.h
@@ -1058,8 +1058,8 @@ enum Misc {
MAX_WOLFSSL_FILE_SIZE = 1024 * 1024 * 4, /* 4 mb file size alloc limit */
-#if defined(FORTRESS) || defined (HAVE_STUNNEL)
- MAX_EX_DATA = 3, /* allow for three items of ex_data */
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+ MAX_EX_DATA = 4, /* allow for four items of ex_data */
#endif
MAX_X509_SIZE = 2048, /* max static x509 buffer size */
@@ -1463,6 +1463,9 @@ struct WOLFSSL_OCSP {
WOLFSSL_CERT_MANAGER* cm; /* pointer back to cert manager */
OcspEntry* ocspList; /* OCSP response list */
wolfSSL_Mutex ocspLock; /* OCSP list lock */
+#ifdef WOLFSSL_NGINX
+ int(*statusCb)(WOLFSSL*, void*);
+#endif
};
#ifndef MAX_DATE_SIZE
@@ -1944,11 +1947,18 @@ struct WOLFSSL_CTX {
DerBuffer* certificate;
DerBuffer* certChain;
/* chain after self, in DER, with leading size for each cert */
+ #ifdef OPENSSL_EXTRA
+ STACK_OF(WOLFSSL_X509_NAME)* ca_names;
+ #endif
+ #ifdef WOLFSSL_NGINX
+ STACK_OF(WOLFSSL_X509)* x509Chain;
+ #endif
DerBuffer* privateKey;
WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */
#endif
#ifdef KEEP_OUR_CERT
WOLFSSL_X509* ourCert; /* keep alive a X509 struct of cert */
+ int ownOurCert; /* Dispose of certificate if we own */
#endif
Suites* suites; /* make dynamic, user may not need/set */
void* heap; /* for user memory overrides */
@@ -1958,6 +1968,9 @@ struct WOLFSSL_CTX {
byte failNoCertxPSK; /* fail if no cert with the exception of PSK*/
byte sessionCacheOff;
byte sessionCacheFlushOff;
+#ifdef HAVE_EXT_CACHE
+ byte internalCacheOff;
+#endif
byte sendVerify; /* for client side */
byte haveRSA; /* RSA available */
byte haveECC; /* ECC available */
@@ -1982,6 +1995,9 @@ struct WOLFSSL_CTX {
#endif
#ifdef HAVE_ECC
short minEccKeySz; /* minimum ECC key size */
+#endif
+#ifdef OPENSSL_EXTRA
+ unsigned long mask; /* store SSL_OP_ flags */
#endif
CallbackIORecv CBIORecv;
CallbackIOSend CBIOSend;
@@ -1997,6 +2013,7 @@ struct WOLFSSL_CTX {
word32 timeout; /* session timeout */
#ifdef HAVE_ECC
word16 eccTempKeySz; /* in octets 20 - 66 */
+ word32 ecdhCurveOID; /* curve Ecc_Sum */
word32 pkCurveOID; /* curve Ecc_Sum */
#endif
#ifndef NO_PSK
@@ -2015,8 +2032,14 @@ struct WOLFSSL_CTX {
byte readAhead;
void* userPRFArg; /* passed to prf callback */
#endif /* OPENSSL_EXTRA */
-#ifdef HAVE_STUNNEL
+#ifdef HAVE_EX_DATA
void* ex_data[MAX_EX_DATA];
+#endif
+#if defined(HAVE_ALPN) && defined(WOLFSSL_NGINX)
+ CallbackALPNSelect alpnSelect;
+ void* alpnSelectArg;
+#endif
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
CallbackSniRecv sniRecvCb;
void* sniRecvCbArg;
#endif
@@ -2064,6 +2087,11 @@ struct WOLFSSL_CTX {
#ifdef HAVE_WOLF_EVENT
WOLF_EVENT_QUEUE event_queue;
#endif /* HAVE_WOLF_EVENT */
+#ifdef HAVE_EXT_CACHE
+ WOLFSSL_SESSION*(*get_sess_cb)(WOLFSSL*, unsigned char*, int, int*);
+ int (*new_sess_cb)(WOLFSSL*, WOLFSSL_SESSION*);
+ void (*rem_sess_cb)(WOLFSSL_CTX*, WOLFSSL_SESSION*);
+#endif
};
@@ -2261,30 +2289,33 @@ struct WOLFSSL_X509_CHAIN {
/* wolfSSL session type */
struct WOLFSSL_SESSION {
- word32 bornOn; /* create time in seconds */
- word32 timeout; /* timeout in seconds */
- byte sessionID[ID_LEN]; /* id for protocol */
- byte sessionIDSz;
- byte masterSecret[SECRET_LEN]; /* stored secret */
- word16 haveEMS; /* ext master secret flag */
+ word32 bornOn; /* create time in seconds */
+ word32 timeout; /* timeout in seconds */
+ byte sessionID[ID_LEN]; /* id for protocol */
+ byte sessionIDSz;
+ byte masterSecret[SECRET_LEN]; /* stored secret */
+ word16 haveEMS; /* ext master secret flag */
#ifdef SESSION_CERTS
- WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */
- ProtocolVersion version; /* which version was used */
- byte cipherSuite0; /* first byte, normally 0 */
- byte cipherSuite; /* 2nd byte, actual suite */
+ WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */
+ ProtocolVersion version; /* which version was used */
+ byte cipherSuite0; /* first byte, normally 0 */
+ byte cipherSuite; /* 2nd byte, actual suite */
#endif
#ifndef NO_CLIENT_CACHE
- word16 idLen; /* serverID length */
- byte serverID[SERVER_ID_LEN]; /* for easier client lookup */
+ word16 idLen; /* serverID length */
+ byte serverID[SERVER_ID_LEN]; /* for easier client lookup */
#endif
#ifdef HAVE_SESSION_TICKET
- byte* ticket;
- word16 ticketLen;
- byte staticTicket[SESSION_TICKET_LEN];
- byte isDynamic;
+ byte* ticket;
+ word16 ticketLen;
+ byte staticTicket[SESSION_TICKET_LEN];
+ byte isDynamic;
#endif
-#ifdef HAVE_STUNNEL
- void* ex_data[MAX_EX_DATA];
+#ifdef HAVE_EXT_CACHE
+ byte isAlloced;
+#endif
+#ifdef HAVE_EX_DATA
+ void* ex_data[MAX_EX_DATA];
#endif
};
@@ -2402,6 +2433,9 @@ typedef struct Options {
word16 sendVerify:2; /* false = 0, true = 1, sendBlank = 2 */
word16 sessionCacheOff:1;
word16 sessionCacheFlushOff:1;
+#ifdef HAVE_EXT_CACHE
+ word16 internalCacheOff:1;
+#endif
word16 side:1; /* client or server end */
word16 verifyPeer:1;
word16 verifyNone:1;
@@ -2522,9 +2556,11 @@ struct WOLFSSL_STACK {
unsigned long num; /* number of nodes in stack
* (saftey measure for freeing and shortcut for count) */
union {
- WOLFSSL_X509* x509;
- WOLFSSL_BIO* bio;
+ WOLFSSL_X509* x509;
+ WOLFSSL_X509_NAME* name;
+ WOLFSSL_BIO* bio;
WOLFSSL_ASN1_OBJECT* obj;
+ char* string;
} data;
WOLFSSL_STACK* next;
};
@@ -2593,6 +2629,9 @@ struct WOLFSSL_X509 {
int certPoliciesNb;
#endif /* WOLFSSL_CERT_EXT */
#ifdef OPENSSL_EXTRA
+#ifdef HAVE_EX_DATA
+ void* ex_data[MAX_EX_DATA];
+#endif
word32 pathLength;
word16 keyUsage;
byte CRLdistSet;
@@ -2752,6 +2791,9 @@ struct WOLFSSL {
Ciphers decrypt;
Buffers buffers;
WOLFSSL_SESSION session;
+#ifdef HAVE_EXT_CACHE
+ WOLFSSL_SESSION* extSession;
+#endif
WOLFSSL_ALERT_HISTORY alert_history;
int error;
int rfd; /* read file descriptor */
@@ -2803,6 +2845,7 @@ struct WOLFSSL {
ecc_key* peerEccDsaKey; /* peer's ECDSA key */
ecc_key* eccTempKey; /* private ECDHE key */
word32 pkCurveOID; /* curve Ecc_Sum */
+ word32 ecdhCurveOID; /* curve Ecc_Sum */
word16 eccTempKeySz; /* in octets 20 - 66 */
byte peerEccKeyPresent;
byte peerEccDsaKeyPresent;
@@ -2847,8 +2890,8 @@ struct WOLFSSL {
flag found in buffers.weOwnCert) */
#endif
byte keepCert; /* keep certificate after handshake */
-#if defined(FORTRESS) || defined(HAVE_STUNNEL)
- void* ex_data[MAX_EX_DATA]; /* external data, for Fortress */
+#if defined(HAVE_EX_DATA) || defined(FORTRESS)
+ void* ex_data[MAX_EX_DATA]; /* external data, for Fortress */
#endif
int devId; /* async device id to use */
#ifdef HAVE_ONE_TIME_AUTH
@@ -2874,6 +2917,10 @@ struct WOLFSSL {
#endif /* user turned on */
#ifdef HAVE_ALPN
char* alpn_client_list; /* keep the client's list */
+ #ifdef WOLFSSL_NGINX
+ CallbackALPNSelect alpnSelect;
+ void* alpnSelectArg;
+ #endif
#endif /* of accepted protocols */
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
CallbackSessionTicket session_ticket_cb;
@@ -2881,6 +2928,13 @@ struct WOLFSSL {
byte expect_session_ticket;
#endif
#endif /* HAVE_TLS_EXTENSIONS */
+#ifdef OPENSSL_EXTRA
+ byte* ocspResp;
+ int ocspRespSz;
+#ifdef WOLFSSL_NGINX
+ char* url;
+#endif
+#endif
#ifdef HAVE_NETX
NetX_Ctx nxCtx; /* NetX IO Context */
#endif
@@ -2957,6 +3011,11 @@ typedef struct EncryptedInfo {
WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format,
int type, WOLFSSL* ssl, int userChain,
WOLFSSL_CRL* crl);
+
+ #ifdef OPENSSL_EXTRA
+ WOLFSSL_LOCAL int CheckHostName(DecodedCert* dCert, char *domainName,
+ size_t domainNameLen);
+ #endif
#endif
diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h
index 5331245c9..03d50fb92 100644
--- a/wolfssl/ocsp.h
+++ b/wolfssl/ocsp.h
@@ -37,6 +37,14 @@
typedef struct WOLFSSL_OCSP WOLFSSL_OCSP;
+#ifdef WOLFSSL_NGINX
+typedef struct OcspResponse WOLFSSL_OCSP_BASICRESP;
+
+typedef struct OcspRequest WOLFSSL_OCSP_CERTID;
+
+typedef struct OcspRequest WOLFSSL_OCSP_ONEREQ;
+#endif
+
WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP*, WOLFSSL_CERT_MANAGER*);
WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP*, int dynamic);
@@ -45,6 +53,48 @@ WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*,
WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp,
OcspRequest* ocspRequest, WOLFSSL_BUFFER_INFO* responseBuffer);
+
+#ifdef WOLFSSL_NGINX
+
+WOLFSSL_API int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
+ WOLFSSL_OCSP_CERTID* id, int* status, int* reason,
+ WOLFSSL_ASN1_TIME** revtime, WOLFSSL_ASN1_TIME** thisupd,
+ WOLFSSL_ASN1_TIME** nextupd);
+WOLFSSL_API const char *wolfSSL_OCSP_cert_status_str(long s);
+WOLFSSL_API int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
+ WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec);
+
+WOLFSSL_API void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId);
+WOLFSSL_API WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
+ const WOLFSSL_EVP_MD *dgst, const WOLFSSL_X509 *subject,
+ const WOLFSSL_X509 *issuer);
+
+WOLFSSL_API void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse);
+WOLFSSL_API int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
+ STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags);
+
+WOLFSSL_API void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response);
+WOLFSSL_API OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
+ OcspResponse** response);
+WOLFSSL_API OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
+ const unsigned char** data, int len);
+WOLFSSL_API int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
+ unsigned char** data);
+WOLFSSL_API int wolfSSL_OCSP_response_status(OcspResponse *response);
+WOLFSSL_API const char *wolfSSL_OCSP_response_status_str(long s);
+WOLFSSL_API WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(
+ OcspResponse* response);
+
+WOLFSSL_API OcspRequest* wolfSSL_OCSP_REQUEST_new(void);
+WOLFSSL_API void wolfSSL_OCSP_REQUEST_free(OcspRequest* request);
+WOLFSSL_API int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request,
+ unsigned char** data);
+WOLFSSL_API WOLFSSL_OCSP_ONEREQ* wolfSSL_OCSP_request_add0_id(OcspRequest *req,
+ WOLFSSL_OCSP_CERTID *cid);
+
+#endif
+
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h
index 7032c24df..04afe897a 100644
--- a/wolfssl/openssl/crypto.h
+++ b/wolfssl/openssl/crypto.h
@@ -3,6 +3,7 @@
#ifndef WOLFSSL_CRYPTO_H_
#define WOLFSSL_CRYPTO_H_
+#include
#include
@@ -23,7 +24,7 @@ WOLFSSL_API unsigned long wolfSSLeay(void);
#define SSLEAY_VERSION 0x0090600fL
#define SSLEAY_VERSION_NUMBER SSLEAY_VERSION
-#ifdef HAVE_STUNNEL
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
#define CRYPTO_set_mem_ex_functions wolfSSL_CRYPTO_set_mem_ex_functions
#define FIPS_mode wolfSSL_FIPS_mode
#define FIPS_mode_set wolfSSL_FIPS_mode_set
@@ -41,7 +42,9 @@ typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int i
#define CRYPTO_THREAD_r_lock wc_LockMutex
#define CRYPTO_THREAD_unlock wc_UnLockMutex
-#endif /* HAVE_STUNNEL */
+#define OPENSSL_malloc(a) XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL)
+
+#endif /* HAVE_STUNNEL || WOLFSSL_NGINX */
#endif /* header */
diff --git a/wolfssl/openssl/dsa.h b/wolfssl/openssl/dsa.h
index 98048bd9c..a4c4a5f54 100644
--- a/wolfssl/openssl/dsa.h
+++ b/wolfssl/openssl/dsa.h
@@ -4,13 +4,19 @@
#ifndef WOLFSSL_DSA_H_
#define WOLFSSL_DSA_H_
-#include
#include
#ifdef __cplusplus
extern "C" {
#endif
+#ifndef WOLFSSL_DSA_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_DSA WOLFSSL_DSA;
+#define WOLFSSL_DSA_TYPE_DEFINED
+#endif
+
+typedef WOLFSSL_DSA DSA;
+
struct WOLFSSL_DSA {
WOLFSSL_BIGNUM* p;
WOLFSSL_BIGNUM* q;
diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h
index 27fa7a600..9802c3db3 100644
--- a/wolfssl/openssl/ec.h
+++ b/wolfssl/openssl/ec.h
@@ -3,7 +3,6 @@
#ifndef WOLFSSL_EC_H_
#define WOLFSSL_EC_H_
-#include
#include
#include
@@ -44,6 +43,17 @@ enum {
OPENSSL_EC_NAMED_CURVE = 0x001
};
+#ifndef WOLFSSL_EC_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY;
+typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT;
+typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP;
+#define WOLFSSL_EC_TYPE_DEFINED
+#endif
+
+typedef WOLFSSL_EC_KEY EC_KEY;
+typedef WOLFSSL_EC_GROUP EC_GROUP;
+typedef WOLFSSL_EC_POINT EC_POINT;
+
struct WOLFSSL_EC_POINT {
WOLFSSL_BIGNUM *X;
WOLFSSL_BIGNUM *Y;
@@ -57,6 +67,7 @@ struct WOLFSSL_EC_POINT {
struct WOLFSSL_EC_GROUP {
int curve_idx; /* index of curve, used by WolfSSL as reference */
int curve_nid; /* NID of curve, used by OpenSSL/OpenSSH as reference */
+ int curve_oid; /* OID of curve, used by OpenSSL/OpenSSH as reference */
};
struct WOLFSSL_EC_KEY {
diff --git a/wolfssl/openssl/ecdsa.h b/wolfssl/openssl/ecdsa.h
index a92841fff..a56d26d3a 100644
--- a/wolfssl/openssl/ecdsa.h
+++ b/wolfssl/openssl/ecdsa.h
@@ -3,7 +3,6 @@
#ifndef WOLFSSL_ECDSA_H_
#define WOLFSSL_ECDSA_H_
-#include
#include
@@ -11,6 +10,13 @@
extern "C" {
#endif
+#ifndef WOLFSSL_ECDSA_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_ECDSA_SIG WOLFSSL_ECDSA_SIG;
+#define WOLFSSL_ECDSA_TYPE_DEFINED
+#endif
+
+typedef WOLFSSL_ECDSA_SIG ECDSA_SIG;
+
struct WOLFSSL_ECDSA_SIG {
WOLFSSL_BIGNUM *r;
WOLFSSL_BIGNUM *s;
diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h
index 086e82c4c..bdd01b733 100644
--- a/wolfssl/openssl/evp.h
+++ b/wolfssl/openssl/evp.h
@@ -56,6 +56,7 @@
#endif
typedef char WOLFSSL_EVP_CIPHER;
+typedef char WOLFSSL_EVP_MD;
#ifndef NO_MD5
WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void);
@@ -173,6 +174,24 @@ typedef struct WOLFSSL_EVP_CIPHER_CTX {
int lastUsed;
} WOLFSSL_EVP_CIPHER_CTX;
+
+#ifndef WOLFSSL_EVP_PKEY_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY;
+#define WOLFSSL_EVP_PKEY_TYPE_DEFINED
+#endif
+
+struct WOLFSSL_EVP_PKEY {
+ int type; /* openssh dereference */
+ int save_type; /* openssh dereference */
+ int pkey_sz;
+ union {
+ char* ptr; /* der format of key / or raw for NTRU */
+ } pkey;
+ #ifdef HAVE_ECC
+ int pkey_curve;
+ #endif
+};
+
typedef int WOLFSSL_ENGINE ;
typedef WOLFSSL_ENGINE ENGINE;
@@ -210,6 +229,7 @@ WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx);
WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx);
WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX*);
+WOLFSSL_API int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER*);
WOLFSSL_API int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
@@ -370,6 +390,8 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX;
#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_CIPHER_iv_length wolfSSL_EVP_CIPHER_iv_length
+
#define EVP_CipherInit wolfSSL_EVP_CipherInit
#define EVP_CipherInit_ex wolfSSL_EVP_CipherInit_ex
#define EVP_EncryptInit wolfSSL_EVP_EncryptInit
diff --git a/wolfssl/openssl/hmac.h b/wolfssl/openssl/hmac.h
index 76d2481bf..3cf92fe1c 100644
--- a/wolfssl/openssl/hmac.h
+++ b/wolfssl/openssl/hmac.h
@@ -57,6 +57,8 @@ typedef struct WOLFSSL_HMAC_CTX {
WOLFSSL_API void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key,
int keylen, const EVP_MD* type);
+WOLFSSL_API int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
+ int len, const EVP_MD* md, void* impl);
WOLFSSL_API void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx,
const unsigned char* data, int len);
WOLFSSL_API void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
@@ -69,6 +71,7 @@ typedef struct WOLFSSL_HMAC_CTX HMAC_CTX;
#define HMAC(a,b,c,d,e,f,g) wolfSSL_HMAC((a),(b),(c),(d),(e),(f),(g))
#define HMAC_Init wolfSSL_HMAC_Init
+#define HMAC_Init_ex wolfSSL_HMAC_Init_ex
#define HMAC_Update wolfSSL_HMAC_Update
#define HMAC_Final wolfSSL_HMAC_Final
#define HMAC_cleanup wolfSSL_HMAC_cleanup
diff --git a/wolfssl/openssl/ocsp.h b/wolfssl/openssl/ocsp.h
index 7463eec96..98f2c9c81 100644
--- a/wolfssl/openssl/ocsp.h
+++ b/wolfssl/openssl/ocsp.h
@@ -1 +1,44 @@
/* ocsp.h for libcurl */
+
+#ifndef WOLFSSL_OCSP_H_
+#define WOLFSSL_OCSP_H_
+
+#ifdef HAVE_OCSP
+#include
+
+#define OCSP_REQUEST OcspRequest
+#define OCSP_RESPONSE OcspResponse
+#define OCSP_BASICRESP WOLFSSL_OCSP_BASICRESP
+#define OCSP_CERTID WOLFSSL_OCSP_CERTID
+#define OCSP_ONEREQ WOLFSSL_OCSP_ONEREQ
+
+#define OCSP_RESPONSE_STATUS_SUCCESSFUL 0
+#define V_OCSP_CERTSTATUS_GOOD 0
+
+#define OCSP_resp_find_status wolfSSL_OCSP_resp_find_status
+#define OCSP_cert_status_str wolfSSL_OCSP_cert_status_str
+#define OCSP_check_validity wolfSSL_OCSP_check_validity
+
+#define OCSP_CERTID_free wolfSSL_OCSP_CERTID_free
+#define OCSP_cert_to_id wolfSSL_OCSP_cert_to_id
+
+#define OCSP_BASICRESP_free wolfSSL_OCSP_BASICRESP_free
+#define OCSP_basic_verify wolfSSL_OCSP_basic_verify
+
+#define OCSP_RESPONSE_free wolfSSL_OCSP_RESPONSE_free
+#define d2i_OCSP_RESPONSE_bio wolfSSL_d2i_OCSP_RESPONSE_bio
+#define d2i_OCSP_RESPONSE wolfSSL_d2i_OCSP_RESPONSE
+#define i2d_OCSP_RESPONSE wolfSSL_i2d_OCSP_RESPONSE
+#define OCSP_response_status wolfSSL_OCSP_response_status
+#define OCSP_response_status_str wolfSSL_OCSP_response_status_str
+#define OCSP_response_get1_basic wolfSSL_OCSP_response_get1_basic
+
+#define OCSP_REQUEST_new wolfSSL_OCSP_REQUEST_new
+#define OCSP_REQUEST_free wolfSSL_OCSP_REQUEST_free
+#define i2d_OCSP_REQUEST wolfSSL_i2d_OCSP_REQUEST
+#define OCSP_request_add0_id wolfSSL_OCSP_request_add0_id
+
+#endif /* HAVE_OCSP */
+
+#endif /* WOLFSSL_OCSP_H_ */
+
diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h
index 48955f9ec..80f9a799c 100644
--- a/wolfssl/openssl/opensslv.h
+++ b/wolfssl/openssl/opensslv.h
@@ -5,7 +5,7 @@
/* api version compatibility */
-#if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY)
+#if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || defined(WOLFSSL_NGINX)
/* version number can be increased for Lighty after compatibility for ECDH
is added */
#define OPENSSL_VERSION_NUMBER 0x10001000L
diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h
index 210a24e4c..7c8d4e63e 100644
--- a/wolfssl/openssl/rsa.h
+++ b/wolfssl/openssl/rsa.h
@@ -4,7 +4,6 @@
#ifndef WOLFSSL_RSA_H_
#define WOLFSSL_RSA_H_
-#include
#include
@@ -24,6 +23,13 @@ enum {
NID_sha512 = 674
};
+#ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_RSA WOLFSSL_RSA;
+#define WOLFSSL_RSA_TYPE_DEFINED
+#endif
+
+typedef WOLFSSL_RSA RSA;
+
struct WOLFSSL_RSA {
WOLFSSL_BIGNUM* n;
WOLFSSL_BIGNUM* e;
diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h
index 6e63fed55..60b1ea647 100644
--- a/wolfssl/openssl/ssl.h
+++ b/wolfssl/openssl/ssl.h
@@ -32,6 +32,8 @@
/* wolfssl_openssl compatibility layer */
#include
+#include
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -61,39 +63,34 @@ typedef WOLFSSL_X509_CHAIN X509_CHAIN;
#define WOLFSSL_TYPES_DEFINED
-typedef WOLFSSL_EVP_PKEY EVP_PKEY;
-typedef WOLFSSL_RSA RSA;
-typedef WOLFSSL_DSA DSA;
-typedef WOLFSSL_EC_KEY EC_KEY;
-typedef WOLFSSL_EC_GROUP EC_GROUP;
-typedef WOLFSSL_EC_POINT EC_POINT;
-typedef WOLFSSL_ECDSA_SIG ECDSA_SIG;
-typedef WOLFSSL_BIO BIO;
-typedef WOLFSSL_BIO_METHOD BIO_METHOD;
-typedef WOLFSSL_CIPHER SSL_CIPHER;
-typedef WOLFSSL_X509_LOOKUP X509_LOOKUP;
-typedef WOLFSSL_X509_LOOKUP_METHOD X509_LOOKUP_METHOD;
-typedef WOLFSSL_X509_CRL X509_CRL;
-typedef WOLFSSL_X509_EXTENSION X509_EXTENSION;
-typedef WOLFSSL_ASN1_TIME ASN1_TIME;
-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;
+typedef WOLFSSL_EVP_PKEY EVP_PKEY;
+typedef WOLFSSL_BIO BIO;
+typedef WOLFSSL_BIO_METHOD BIO_METHOD;
+typedef WOLFSSL_CIPHER SSL_CIPHER;
+typedef WOLFSSL_X509_LOOKUP X509_LOOKUP;
+typedef WOLFSSL_X509_LOOKUP_METHOD X509_LOOKUP_METHOD;
+typedef WOLFSSL_X509_CRL X509_CRL;
+typedef WOLFSSL_X509_EXTENSION X509_EXTENSION;
+typedef WOLFSSL_ASN1_TIME ASN1_TIME;
+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
+#define ASN1_UTCTIME WOLFSSL_ASN1_TIME
+#define ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME
typedef WOLFSSL_MD4_CTX MD4_CTX;
typedef WOLFSSL_COMP_METHOD COMP_METHOD;
-typedef WOLFSSL_X509_STORE X509_STORE;
typedef WOLFSSL_X509_REVOKED X509_REVOKED;
typedef WOLFSSL_X509_OBJECT X509_OBJECT;
+typedef WOLFSSL_X509_STORE X509_STORE;
typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
#define CRYPTO_free XFREE
@@ -104,7 +101,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
#define SSL_get_cipher_list(ctx,i) wolfSSL_get_cipher_list((i))
#define SSL_get_cipher_name(ctx) wolfSSL_get_cipher((ctx))
#define SSL_get_shared_ciphers(ctx,buf,len) \
- strncpy(buf, "Not Implemented, SSLv2 only", len)
+ wolfSSL_get_shared_ciphers((ctx),(buf),(len))
#define ERR_print_errors_fp(file) wolfSSL_ERR_dump_errors_fp((file))
@@ -335,7 +332,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
#define X509_get_serialNumber wolfSSL_X509_get_serialNumber
-#define ASN1_TIME_print wolfSSL_ASN1_TIME_print
+#define ASN1_TIME_print wolfSSL_ASN1_TIME_print
+#define ASN1_GENERALIZEDTIME_print wolfSSL_ASN1_GENERALIZEDTIME_print
#define ASN1_INTEGER_cmp wolfSSL_ASN1_INTEGER_cmp
#define ASN1_INTEGER_get wolfSSL_ASN1_INTEGER_get
@@ -343,6 +341,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
#define SSL_load_client_CA_file wolfSSL_load_client_CA_file
+#define SSL_CTX_get_client_CA_list wolfSSL_SSL_CTX_get_client_CA_list
#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
@@ -472,7 +471,9 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
/* Lighthttp compatibility */
-#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL)
+#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) \
+ || defined(HAVE_STUNNEL) \
+ || defined(WOLFSSL_NGINX)
typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
#define X509_NAME_free wolfSSL_X509_NAME_free
@@ -484,6 +485,7 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
#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_set_verify_depth wolfSSL_set_verify_depth
#define SSL_get_app_data wolfSSL_get_app_data
#define SSL_set_app_data wolfSSL_set_app_data
#define X509_NAME_entry_count wolfSSL_X509_NAME_entry_count
@@ -501,16 +503,17 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
#define NID_commonName 0x03 /* matchs ASN_COMMON_NAME in asn.h */
#endif
-#if defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) \
- || defined(WOLFSSL_MYSQL_COMPATIBLE)
+#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) \
+ || defined(HAVE_STUNNEL) \
+ || defined(WOLFSSL_NGINX)
#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 PEM_write_bio_X509 wolfSSL_PEM_write_bio_X509
-#endif /* HAVE_STUNNEL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE */
+#endif /* HAVE_STUNNEL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX */
#define SSL_CTX_set_tmp_dh wolfSSL_CTX_set_tmp_dh
#define BIO_new_file wolfSSL_BIO_new_file
@@ -590,15 +593,18 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
#define SSL_CTRL_GET_READ_AHEAD 40
#define SSL_CTRL_SET_READ_AHEAD 41
+#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64
+#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82
+
#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
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
#include
#define SSL2_VERSION 0x0002
@@ -646,7 +652,7 @@ 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_callback wolfSSL_CTX_set_tlsext_servername_callback
#define SSL_CTX_set_tlsext_servername_arg wolfSSL_CTX_set_servername_arg
#define PSK_MAX_PSK_LEN 256
@@ -655,7 +661,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING;
#define SSL_CTX_clear_options wolfSSL_CTX_clear_options
-#endif /* HAVE_STUNNEL */
+#endif /* HAVE_STUNNEL || WOLFSSL_NGINX */
#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
@@ -683,6 +689,98 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING;
#define SSL_CTX_set_msg_callback_arg wolfSSL_CTX_set_msg_callback_arg
#define SSL_set_msg_callback_arg wolfSSL_set_msg_callback_arg
+/* 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 WOLFSSL_NGINX
+#include
+
+#define OPENSSL_STRING WOLFSSL_STRING
+
+#define TLSEXT_TYPE_application_layer_protocol_negotiation 16
+
+#define OPENSSL_NPN_UNSUPPORTED 0
+#define OPENSSL_NPN_NEGOTIATED 1
+#define OPENSSL_NPN_NO_OVERLAP 2
+
+
+/* Nginx checks these to see if the error was a handshake error. */
+#define SSL_R_BAD_CHANGE_CIPHER_SPEC LENGTH_ERROR
+#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG BUFFER_E
+#define SSL_R_DIGEST_CHECK_FAILED VERIFY_MAC_ERROR
+#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST SUITES_ERROR
+#define SSL_R_EXCESSIVE_MESSAGE_SIZE BUFFER_ERROR
+#define SSL_R_LENGTH_MISMATCH LENGTH_ERROR
+#define SSL_R_NO_CIPHERS_SPECIFIED SUITES_ERROR
+#define SSL_R_NO_COMPRESSION_SPECIFIED COMPRESSION_ERROR
+#define SSL_R_NO_SHARED_CIPHER MATCH_SUITE_ERROR
+#define SSL_R_RECORD_LENGTH_MISMATCH HANDSHAKE_SIZE_ERROR
+#define SSL_R_UNEXPECTED_MESSAGE OUT_OF_ORDER_E
+#define SSL_R_UNEXPECTED_RECORD SANITY_MSG_E
+#define SSL_R_UNKNOWN_ALERT_TYPE BUFFER_ERROR
+#define SSL_R_UNKNOWN_PROTOCOL VERSION_ERROR
+#define SSL_R_WRONG_VERSION_NUMBER VERSION_ERROR
+#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC ENCRYPT_ERROR
+
+/* Nginx uses this to determine if reached end of certs in file.
+ * PEM_read_bio_X509 is called and the return error is lost.
+ * The error that needs to be detected is: SSL_NO_PEM_HEADER.
+ */
+#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL)
+#define PEM_R_NO_START_LINE 108
+#define ERR_LIB_PEM 9
+
+#ifdef HAVE_SESSION_TICKET
+#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
+#endif
+
+#define OPENSSL_config wolfSSL_OPENSSL_config
+#define X509_get_ex_new_index wolfSSL_X509_get_ex_new_index
+#define X509_get_ex_data wolfSSL_X509_get_ex_data
+#define X509_set_ex_data wolfSSL_X509_set_ex_data
+#define X509_NAME_digest wolfSSL_X509_NAME_digest
+#define SSL_CTX_get_timeout wolfSSL_SSL_CTX_get_timeout
+#define SSL_CTX_set_tmp_ecdh wolfSSL_SSL_CTX_set_tmp_ecdh
+#define SSL_CTX_remove_session wolfSSL_SSL_CTX_remove_session
+#define SSL_get_rbio wolfSSL_SSL_get_rbio
+#define SSL_get_wbio wolfSSL_SSL_get_wbio
+#define SSL_do_handshake wolfSSL_SSL_do_handshake
+#define SSL_in_init wolfSSL_SSL_in_init
+#define SSL_get0_session wolfSSL_SSL_get0_session
+#define X509_check_host wolfSSL_X509_check_host
+#define i2a_ASN1_INTEGER wolfSSL_i2a_ASN1_INTEGER
+#define ERR_peek_error_line_data wolfSSL_ERR_peek_error_line_data
+#define SSL_CTX_set_tlsext_ticket_key_cb wolfSSL_CTX_set_tlsext_ticket_key_cb
+#define X509_email_free wolfSSL_X509_email_free
+#define X509_get1_ocsp wolfSSL_X509_get1_ocsp
+#define SSL_CTX_set_tlsext_status_cb wolfSSL_CTX_set_tlsext_status_cb
+#define X509_check_issued wolfSSL_X509_check_issued
+#define X509_dup wolfSSL_X509_dup
+#define X509_STORE_CTX_new wolfSSL_X509_STORE_CTX_new
+#define X509_STORE_CTX_free wolfSSL_X509_STORE_CTX_free
+#define SSL_CTX_get_extra_chain_certs wolfSSL_CTX_get_extra_chain_certs
+#define X509_STORE_CTX_get1_issuer wolfSSL_X509_STORE_CTX_get1_issuer
+#define sk_OPENSSL_STRING_value wolfSSL_sk_WOLFSSL_STRING_value
+#define SSL_get0_alpn_selected wolfSSL_get0_alpn_selected
+#define SSL_select_next_proto wolfSSL_select_next_proto
+#define SSL_CTX_set_alpn_select_cb wolfSSL_CTX_set_alpn_select_cb
+
+#endif
#ifdef __cplusplus
} /* extern "C" */
diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h
index 6b94cac52..d9d1fc9c0 100644
--- a/wolfssl/ssl.h
+++ b/wolfssl/ssl.h
@@ -61,6 +61,7 @@
#ifdef OPENSSL_EXTRA
#include
+ #include
#endif
#ifdef __cplusplus
@@ -95,15 +96,28 @@ typedef struct WOLFSSL_RSA WOLFSSL_RSA;
#define WC_RNG_TYPE_DEFINED
#endif
+#ifndef WOLFSSL_DSA_TYPE_DEFINED /* guard on redeclaration */
typedef struct WOLFSSL_DSA WOLFSSL_DSA;
+#define WOLFSSL_DSA_TYPE_DEFINED
+#endif
+
+#ifndef WOLFSSL_EC_TYPE_DEFINED /* guard on redeclaration */
typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY;
typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT;
typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP;
+#define WOLFSSL_EC_TYPE_DEFINED
+#endif
+
+#ifndef WOLFSSL_ECDSA_TYPE_DEFINED /* guard on redeclaration */
typedef struct WOLFSSL_ECDSA_SIG WOLFSSL_ECDSA_SIG;
+#define WOLFSSL_ECDSA_TYPE_DEFINED
+#endif
+
typedef struct WOLFSSL_CIPHER WOLFSSL_CIPHER;
typedef struct WOLFSSL_X509_LOOKUP WOLFSSL_X509_LOOKUP;
typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD;
typedef struct WOLFSSL_X509_CRL WOLFSSL_X509_CRL;
+typedef struct WOLFSSL_X509_STORE WOLFSSL_X509_STORE;
typedef struct WOLFSSL_BIO WOLFSSL_BIO;
typedef struct WOLFSSL_BIO_METHOD WOLFSSL_BIO_METHOD;
typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION;
@@ -117,7 +131,8 @@ 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
+#define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME
+#define WOLFSSL_ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME
struct WOLFSSL_ASN1_INTEGER {
/* size can be increased set at 20 for tag, length then to hold at least 16
@@ -126,18 +141,16 @@ struct WOLFSSL_ASN1_INTEGER {
/* 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; /* der format of key / or raw for NTRU */
- } pkey;
- #ifdef HAVE_ECC
- int pkey_curve;
- #endif
-} WOLFSSL_EVP_PKEY;
+struct WOLFSSL_ASN1_TIME {
+ /* MAX_DATA_SIZE is 32 */
+ unsigned char data[32 + 2];
+ /* ASN_TIME | LENGTH | date bytes */
+};
+
+#ifndef WOLFSSL_EVP_PKEY_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY;
+#define WOLFSSL_EVP_PKEY_TYPE_DEFINED
+#endif
typedef struct WOLFSSL_MD4_CTX {
int buffer[32]; /* big enough to hold, check size in Init */
@@ -148,11 +161,22 @@ typedef struct WOLFSSL_COMP_METHOD {
int type; /* stunnel dereference */
} WOLFSSL_COMP_METHOD;
+struct WOLFSSL_X509_LOOKUP_METHOD {
+ int type;
+};
-typedef struct WOLFSSL_X509_STORE {
- int cache; /* stunnel dereference */
+struct WOLFSSL_X509_LOOKUP {
+ WOLFSSL_X509_STORE *store;
+};
+
+struct WOLFSSL_X509_STORE {
+ int cache; /* stunnel dereference */
WOLFSSL_CERT_MANAGER* cm;
-} WOLFSSL_X509_STORE;
+ WOLFSSL_X509_LOOKUP lookup;
+#ifdef OPENSSL_EXTRA
+ int isDynamic;
+#endif
+};
typedef struct WOLFSSL_ALERT {
int code;
@@ -196,6 +220,7 @@ typedef struct WOLFSSL_X509_STORE_CTX {
WOLFSSL_BUFFER_INFO* certs; /* peer certs */
} WOLFSSL_X509_STORE_CTX;
+typedef char* WOLFSSL_STRING;
/* Valid Alert types from page 16/17 */
enum AlertDescription {
@@ -347,6 +372,9 @@ WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL*, int);
WOLFSSL_API char* wolfSSL_get_cipher_list(int priority);
WOLFSSL_API int wolfSSL_get_ciphers(char*, int);
WOLFSSL_API const char* wolfSSL_get_cipher_name(WOLFSSL* ssl);
+WOLFSSL_API const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf,
+ int len);
+WOLFSSL_API const char* wolfSSL_get_curve_name(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_get_fd(const WOLFSSL*);
WOLFSSL_API void wolfSSL_set_using_nonblock(WOLFSSL*, int);
WOLFSSL_API int wolfSSL_get_using_nonblock(WOLFSSL*);
@@ -475,7 +503,7 @@ WOLFSSL_API int wolfSSL_is_init_finished(WOLFSSL*);
WOLFSSL_API const char* wolfSSL_get_version(WOLFSSL*);
WOLFSSL_API int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl);
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL*);
-WOLFSSL_API char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER*, char*, int);
+WOLFSSL_API char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER*, char*, int);
WOLFSSL_API const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher);
WOLFSSL_API const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session);
WOLFSSL_API const char* wolfSSL_get_cipher(WOLFSSL*);
@@ -517,7 +545,7 @@ WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void);
WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void);
WOLFSSL_API void wolfSSL_BIO_set_flags(WOLFSSL_BIO*, int);
-WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,const unsigned char** p);
+WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,void* p);
WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len);
@@ -662,6 +690,8 @@ WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGE
WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char*);
#endif
+WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_SSL_CTX_get_client_CA_list(
+ const WOLFSSL_CTX *s);
WOLFSSL_API void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX*,
STACK_OF(WOLFSSL_X509_NAME)*);
WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX*, int);
@@ -830,18 +860,25 @@ enum {
X509_LU_X509 = 9,
X509_LU_CRL = 12,
- X509_V_OK = 0,
- X509_V_ERR_CRL_SIGNATURE_FAILURE = 13,
- X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 14,
- X509_V_ERR_CRL_HAS_EXPIRED = 15,
- X509_V_ERR_CERT_REVOKED = 16,
- X509_V_ERR_CERT_CHAIN_TOO_LONG = 17,
- X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 18,
- X509_V_ERR_CERT_NOT_YET_VALID = 19,
- X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 20,
- X509_V_ERR_CERT_HAS_EXPIRED = 21,
- X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 22,
- X509_V_ERR_CERT_REJECTED = 23,
+ X509_V_OK = 0,
+ X509_V_ERR_CRL_SIGNATURE_FAILURE = 13,
+ X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 14,
+ X509_V_ERR_CRL_HAS_EXPIRED = 15,
+ X509_V_ERR_CERT_REVOKED = 16,
+ X509_V_ERR_CERT_CHAIN_TOO_LONG = 17,
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 18,
+ X509_V_ERR_CERT_NOT_YET_VALID = 19,
+ X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 20,
+ X509_V_ERR_CERT_HAS_EXPIRED = 21,
+ X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 22,
+ X509_V_ERR_CERT_REJECTED = 23,
+ /* Required for Nginx */
+ X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 24,
+ X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 25,
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 26,
+ X509_V_ERR_CERT_UNTRUSTED = 27,
+ X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 28,
+ X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29,
/* additional X509_V_ERR_* enums not used in wolfSSL */
X509_V_ERR_UNABLE_TO_GET_CRL,
X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE,
@@ -851,15 +888,9 @@ enum {
X509_V_ERR_CRL_NOT_YET_VALID,
X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD,
X509_V_ERR_OUT_OF_MEM,
- X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
- X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
- X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
- X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
X509_V_ERR_INVALID_CA,
X509_V_ERR_PATH_LENGTH_EXCEEDED,
X509_V_ERR_INVALID_PURPOSE,
- X509_V_ERR_CERT_UNTRUSTED,
- X509_V_ERR_SUBJECT_ISSUER_MISMATCH,
X509_V_ERR_AKID_SKID_MISMATCH,
X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH,
X509_V_ERR_KEYUSAGE_NO_CERTSIGN,
@@ -878,6 +909,7 @@ enum {
XN_FLAG_SPC_EQ = (1 << 23),
XN_FLAG_ONELINE = 0,
+ XN_FLAG_RFC2253 = 1,
CRYPTO_LOCK = 1,
CRYPTO_NUM_LOCKS = 10,
@@ -924,12 +956,14 @@ enum { /* ssl Constants */
SSL_VERIFY_CLIENT_ONCE = 4,
SSL_VERIFY_FAIL_EXCEPT_PSK = 8,
- SSL_SESS_CACHE_OFF = 30,
- SSL_SESS_CACHE_CLIENT = 31,
- SSL_SESS_CACHE_SERVER = 32,
- SSL_SESS_CACHE_BOTH = 33,
- SSL_SESS_CACHE_NO_AUTO_CLEAR = 34,
- SSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 35,
+ SSL_SESS_CACHE_OFF = 0x0000,
+ SSL_SESS_CACHE_CLIENT = 0x0001,
+ SSL_SESS_CACHE_SERVER = 0x0002,
+ SSL_SESS_CACHE_BOTH = 0x0003,
+ SSL_SESS_CACHE_NO_AUTO_CLEAR = 0x0008,
+ SSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 0x0100,
+ SSL_SESS_CACHE_NO_INTERNAL_STORE = 0x0200,
+ SSL_SESS_CACHE_NO_INTERNAL = 0x0300,
SSL_ERROR_WANT_READ = 2,
SSL_ERROR_WANT_WRITE = 3,
@@ -1037,6 +1071,8 @@ WOLFSSL_API int wolfSSL_want_write(WOLFSSL*);
WOLFSSL_API int wolfSSL_BIO_printf(WOLFSSL_BIO*, const char*, ...);
WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*,
const WOLFSSL_ASN1_UTCTIME*);
+WOLFSSL_API int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO*,
+ const WOLFSSL_ASN1_GENERALIZEDTIME*);
WOLFSSL_API int wolfSSL_sk_num(WOLFSSL_X509_REVOKED*);
WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED*, int);
@@ -1690,6 +1726,12 @@ enum {
WOLFSSL_MAX_ALPN_NUMBER = 257
};
+#ifdef WOLFSSL_NGINX
+typedef int (*CallbackALPNSelect)(WOLFSSL* ssl, const unsigned char** out,
+ unsigned char* outLen, const unsigned char* in, unsigned int inLen,
+ void *arg);
+#endif
+
WOLFSSL_API int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
unsigned int protocol_name_listSz,
unsigned char options);
@@ -1960,7 +2002,7 @@ WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack,
WOLFSSL_API void wolfSSL_cert_service(void);
#endif
-#if defined(WOLFSSL_MYSQL_COMPATIBLE)
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time,
char* buf, int len);
#endif /* WOLFSSL_MYSQL_COMPATIBLE */
@@ -2028,7 +2070,10 @@ struct WOLFSSL_X509_NAME_ENTRY {
int size;
};
-#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL)
+#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) \
+ || defined(HAVE_STUNNEL) \
+ || defined(WOLFSSL_NGINX) \
+ || defined(OPENSSL_EXTRA)
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_BIO_read_filename(WOLFSSL_BIO *b, const char *name);
@@ -2037,6 +2082,7 @@ 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_set_verify_depth(WOLFSSL *ssl,int depth);
WOLFSSL_API void* wolfSSL_get_app_data( const WOLFSSL *ssl);
WOLFSSL_API void wolfSSL_set_app_data(WOLFSSL *ssl, void *arg);
WOLFSSL_API WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne);
@@ -2070,7 +2116,7 @@ WOLFSSL_API long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx);
#endif /* HAVE_STUNNEL || HAVE_LIGHTY */
-#ifdef HAVE_STUNNEL
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
#include
@@ -2145,6 +2191,8 @@ WOLFSSL_API VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX*);
WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX *,
CallbackSniRecv);
+WOLFSSL_API int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX *,
+ CallbackSniRecv);
WOLFSSL_API void wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX *, void*);
@@ -2164,9 +2212,10 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CTX*,
WOLFSSL_X509_NAME*);
WOLFSSL_API void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*));
-#endif /* HAVE_STUNNEL */
+#endif /* HAVE_STUNNEL || WOLFSSL_NGINX */
-#if defined(HAVE_STUNNEL) || defined(WOLFSSL_MYSQL_COMPATIBLE)
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_MYSQL_COMPATIBLE) \
+ || defined(WOLFSSL_NGINX)
WOLFSSL_API int wolfSSL_CTX_get_verify_mode(WOLFSSL_CTX* ctx);
@@ -2194,6 +2243,89 @@ WOLFSSL_API int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg);
WOLFSSL_API int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg);
#endif
+#ifdef WOLFSSL_NGINX
+/* Not an OpenSSL API. */
+WOLFSSL_LOCAL int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response);
+/* Not an OpenSSL API. */
+WOLFSSL_LOCAL char* wolfSSL_get_ocsp_url(WOLFSSL* ssl);
+/* Not an OpenSSL API. */
+WOLFSSL_API int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url);
+
+WOLFSSL_API void wolfSSL_OPENSSL_config(char *config_name);
+WOLFSSL_API int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a,
+ void *b, void *c);
+WOLFSSL_API void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx);
+WOLFSSL_API int wolfSSL_X509_set_ex_data(WOLFSSL_X509 *x509, int idx,
+ void *data);
+
+WOLFSSL_API int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *data,
+ const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len);
+
+WOLFSSL_API long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx);
+WOLFSSL_API int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx,
+ WOLFSSL_EC_KEY *ecdh);
+WOLFSSL_API int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *,
+ WOLFSSL_SESSION *c);
+
+WOLFSSL_API WOLFSSL_BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s);
+WOLFSSL_API WOLFSSL_BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s);
+WOLFSSL_API int wolfSSL_SSL_do_handshake(WOLFSSL *s);
+WOLFSSL_API int wolfSSL_SSL_in_init(WOLFSSL *a); /* #define in OpenSSL */
+WOLFSSL_API WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *s);
+WOLFSSL_API int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk,
+ size_t chklen, unsigned int flags, char **peername);
+
+WOLFSSL_API int wolfSSL_i2a_ASN1_INTEGER(WOLFSSL_BIO *bp,
+ const WOLFSSL_ASN1_INTEGER *a);
+
+WOLFSSL_API unsigned long wolfSSL_ERR_peek_error_line_data(const char **file,
+ int *line, const char **data, int *flags);
+
+#ifdef HAVE_SESSION_TICKET
+WOLFSSL_API int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *, int (*)(
+ WOLFSSL *ssl, unsigned char *name, unsigned char *iv,
+ WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc));
+#endif
+
+#ifdef HAVE_OCSP
+WOLFSSL_API int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx,
+ STACK_OF(X509)** chain);
+WOLFSSL_API int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx,
+ int(*)(WOLFSSL*, void*));
+
+WOLFSSL_API int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
+ WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x);
+
+WOLFSSL_API void wolfSSL_X509_email_free(STACK_OF(WOLFSSL_STRING) *sk);
+WOLFSSL_API STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x);
+
+WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer,
+ WOLFSSL_X509 *subject);
+
+WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x);
+
+WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value(
+ STACK_OF(WOLFSSL_STRING)* strings, int idx);
+#endif /* HAVE_OCSP */
+
+WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio,
+ WOLFSSL_X509 *cert);
+#endif /* WOLFSSL_NGINX */
+
+WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl,
+ const unsigned char **data, unsigned int *len);
+WOLFSSL_API int wolfSSL_select_next_proto(unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ const unsigned char *client,
+ unsigned int client_len);
+WOLFSSL_API void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
+ int (*cb) (WOLFSSL *ssl,
+ const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg), void *arg);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/wolfssl/test.h b/wolfssl/test.h
index e0b03c3b3..61a531ce4 100644
--- a/wolfssl/test.h
+++ b/wolfssl/test.h
@@ -514,6 +514,12 @@ static INLINE void showPeer(WOLFSSL* ssl)
{
WOLFSSL_CIPHER* cipher;
+#ifdef HAVE_ECC
+ const char *name;
+#endif
+#ifndef NO_DH
+ int bits;
+#endif
#ifdef KEEP_PEER_CERT
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
if (peer)
@@ -535,6 +541,16 @@ static INLINE void showPeer(WOLFSSL* ssl)
#else
printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher));
#endif
+#ifdef HAVE_ECC
+ if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
+ printf("SSL curve name is %s\n", name);
+#endif
+#ifndef NO_DH
+ if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
+ printf("SSL DH size is %d bits\n", bits);
+#endif
+ if (wolfSSL_session_reused(ssl))
+ printf("SSL reused session\n");
#if defined(SESSION_CERTS) && defined(SHOW_CERTS)
{
diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h
index 1eb4b6d90..02ad51cc0 100644
--- a/wolfssl/wolfcrypt/asn.h
+++ b/wolfssl/wolfcrypt/asn.h
@@ -188,7 +188,7 @@ enum Misc_ASN {
MAX_CERTPOL_NB = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */
MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ,
#endif
- OCSP_NONCE_EXT_SZ = 37, /* OCSP Nonce Extension size */
+ OCSP_NONCE_EXT_SZ = 35, /* OCSP Nonce Extension size */
MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */
MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */
EIGHTK_BUF = 8192, /* Tmp buffer size */
@@ -196,7 +196,10 @@ enum Misc_ASN {
/* use bigger NTRU size */
HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */
TRAILING_ZERO = 1, /* Used for size of zero pad */
- MIN_VERSION_SZ = 3 /* Min bytes needed for GetMyVersion */
+ MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
+ MAX_TIME_STRING_SZ = 21, /* Max length of formatted time string */
+#endif
};
@@ -681,7 +684,7 @@ WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int);
WOLFSSL_LOCAL int DecryptContent(byte* input, word32 sz,const char* psw,int pswSz);
typedef struct tm wolfssl_tm;
-#if defined(WOLFSSL_MYSQL_COMPATIBLE)
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len);
#endif
WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format,
@@ -807,6 +810,10 @@ struct CertStatus {
byte nextDate[MAX_DATE_SIZE];
byte thisDateFormat;
byte nextDateFormat;
+#ifdef WOLFSSL_NGINX
+ byte* thisDateAsn;
+ byte* nextDateAsn;
+#endif
byte* rawOcspResponse;
word32 rawOcspResponseSz;
@@ -853,6 +860,10 @@ struct OcspRequest {
byte nonce[MAX_OCSP_NONCE_SZ];
int nonceSz;
void* heap;
+
+#ifdef WOLFSSL_NGINX
+ void* ssl;
+#endif
};
diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h
index 576d2d28f..242018ad7 100644
--- a/wolfssl/wolfcrypt/asn_public.h
+++ b/wolfssl/wolfcrypt/asn_public.h
@@ -240,7 +240,8 @@ WOLFSSL_API int wc_SetKeyUsage(Cert *cert, const char *value);
#endif /* WOLFSSL_PEMPUBKEY_TODER_DEFINED */
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
-#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || !defined(NO_DSA)
+#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || !defined(NO_DSA) \
+ || defined(OPENSSL_EXTRA)
WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output,
word32 outputSz, int type);
WOLFSSL_API int wc_DerToPemEx(const byte* der, word32 derSz, byte* output,
diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h
index 177d7003f..c78208b74 100644
--- a/wolfssl/wolfcrypt/ecc.h
+++ b/wolfssl/wolfcrypt/ecc.h
@@ -286,6 +286,8 @@ typedef struct ecc_key {
/* ECC predefined curve sets */
extern const ecc_set_type ecc_sets[];
+WOLFSSL_API
+const char* wc_ecc_get_name(int curve_id);
WOLFSSL_API
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key);
diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h
index e1c93cd75..3294ee57f 100644
--- a/wolfssl/wolfcrypt/settings.h
+++ b/wolfssl/wolfcrypt/settings.h
@@ -1495,6 +1495,27 @@ static char *fgets(char *buff, int sz, FILE *fp)
#undef HAVE_GMTIME_R /* don't trust macro with windows */
#endif /* WOLFSSL_MYSQL_COMPATIBLE */
+#ifdef WOLFSSL_NGINX
+ #define SSL_OP_NO_COMPRESSION SSL_OP_NO_COMPRESSION
+ #define OPENSSL_NO_ENGINE
+ #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT
+ #ifndef OPENSSL_EXTRA
+ #define OPENSSL_EXTRA
+ #endif
+ #ifndef HAVE_SESSION_TICKET
+ #define HAVE_SESSION_TICKET
+ #endif
+ #ifndef HAVE_OCSP
+ #define HAVE_OCSP
+ #endif
+ #ifndef KEEP_OUR_CERT
+ #define KEEP_OUR_CERT
+ #endif
+ #ifndef HAVE_SNI
+ #define HAVE_SNI
+ #endif
+ #define SSL_CTRL_SET_TLSEXT_HOSTNAME
+#endif
#ifdef __cplusplus
} /* extern "C" */
diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h
index 00b184668..a8a16bfde 100644
--- a/wolfssl/wolfcrypt/types.h
+++ b/wolfssl/wolfcrypt/types.h
@@ -242,7 +242,7 @@
#define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))
#endif
- #if defined(WOLFSSL_MYSQL_COMPATIBLE)
+ #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
#ifndef USE_WINDOWS_API
#define XSNPRINTF snprintf
#else