aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/luaossl.pdfbin269435 -> 272910 bytes
-rw-r--r--doc/luaossl.tex72
-rw-r--r--src/GNUmakefile2
-rw-r--r--src/openssl.c347
-rw-r--r--src/openssl.ocsp.basic.lua3
-rw-r--r--src/openssl.ocsp.response.lua3
6 files changed, 427 insertions, 0 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf
index a51c46e..28e9984 100644
--- a/doc/luaossl.pdf
+++ b/doc/luaossl.pdf
Binary files differ
diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 48faabe..d733ccf 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -555,6 +555,10 @@ Returns a copy of the \module{x509.extension} object identified by $key$ where $
Returns the integer count of the number of extensions.
+\subsubsection[\fn{x509:getOCSP}]{\fn{x509:getOCSP()}}
+
+Returns the OCSP urls for the certificate.
+
\subsubsection[\fn{x509:isIssuedBy}]{\fn{x509:isIssuedBy($issuer$)}}
Returns a boolean according to whether the specified issuer---an \module{openssl.x509.name} object---signed the instance certificate.
@@ -926,6 +930,20 @@ Sets the advertised ALPN protocols. $table$ is an array of protocol string ident
\emph{Only supported since OpenSSL 1.0.2.}
+\subsubsection[\fn{context:setTLSextStatusType}]{\fn{context:setTLSextStatusType($type$)}}
+
+Sets the default TLS extension status for SSL objects derived from this context.
+See \fn{ssl:setTLSextStatusType}
+
+\emph{Only supported since OpenSSL 1.1.0.}
+
+\subsubsection[\fn{context:getTLSextStatusType}]{\fn{context:getTLSextStatusType()}}
+
+Gets the default TLS extension status for SSL objects derived from this context as a string.
+See \fn{ssl:getTLSextStatusType}
+
+\emph{Only supported since OpenSSL 1.1.0.}
+
\end{Module}
@@ -1013,6 +1031,30 @@ Sets the advertised ALPN protocols. $table$ is an array of protocol string ident
\emph{Only supported since OpenSSL 1.0.2.}
+\subsubsection[\fn{ssl:setTLSextStatusType}]{\fn{ssl:setTLSextStatusType($type$)}}
+
+Sets the TLS extension status.
+
+Only the $type$ ``ocsp'' is currently supported, this is used by a client to request that a server sends a stapled OCSP response as part of the TLS handshake.
+
+See also: \fn{context:setTLSextStatusType()}
+
+\subsubsection[\fn{ssl:getTLSextStatusType}]{\fn{ssl:getTLSextStatusType()}}
+
+Gets the TLS extension status. As set by \fn{ssl:setTLSextStatusType} or \fn{context:setTLSextStatusType}.
+
+Only the type ``ocsp'' is currently known.
+
+\emph{Only supported since OpenSSL 1.1.0.}
+
+\subsubsection[\fn{ssl:setTLSextStatusOCSPResp}]{\fn{ssl:setTLSextStatusOCSPResp($or$)}}
+
+Sets an \module{openssl.ocsp.response}. Used by a server to staple an OCSP response into a TLS handshake.
+
+\subsubsection[\fn{ssl:getTLSextStatusOCSPResp}]{\fn{ssl:getTLSextStatusOCSPResp()}}
+
+Returns the \module{openssl.ocsp.response} associated with the ssl object (or $nil$ if one has not been set).
+
\end{Module}
@@ -1095,6 +1137,36 @@ Update the cipher with the specified string(s). Returns the final output string
\end{Module}
+\begin{Module}{openssl.ocsp.response}
+
+Binds OpenSSL's \texttt{OCSP\_RESPONSE} object.
+
+\subsubsection[\fn{response:getBasic}]{\fn{response:getBasic()}}
+
+Returns a \module{openssl.ocsp.basic} representation of the object contained within the OCSP response.
+
+\subsubsection[\fn{response:tostring}]{\fn{response:tostring()}}
+
+Returns a human readable description of the OCSP response as a string.
+
+\subsubsection[\fn{response:toPEM}]{\fn{response:toPEM()}}
+
+Returns the OCSP response as a PEM encoded string.
+
+\end{Module}
+
+
+\begin{Module}{openssl.ocsp.basic}
+
+Binds OpenSSL's \texttt{OCSP\_BASICRESP} object.
+
+\subsubsection[\fn{basic:verify}]{\fn{basic:verify([$certs$ [, $store$[, $flags$]]])}}
+
+Verifies that the OCSP response is signed by a certificate in the \module{openssl.x509.chain} $certs$ or a trusted certificate in \module{openssl.x509.store} $store$.
+
+\end{Module}
+
+
\begin{Module}{openssl.rand}
Binds OpenSSL's random number interfaces.
diff --git a/src/GNUmakefile b/src/GNUmakefile
index 015a93c..132f3bf 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -92,6 +92,8 @@ MODS$(1)_$(d) = \
$$(DESTDIR)$(3)/openssl.lua \
$$(DESTDIR)$(3)/openssl/auxlib.lua \
$$(DESTDIR)$(3)/openssl/bignum.lua \
+ $$(DESTDIR)$(3)/openssl/ocsp/basic.lua \
+ $$(DESTDIR)$(3)/openssl/ocsp/response.lua \
$$(DESTDIR)$(3)/openssl/pkey.lua \
$$(DESTDIR)$(3)/openssl/pubkey.lua \
$$(DESTDIR)$(3)/openssl/x509.lua \
diff --git a/src/openssl.c b/src/openssl.c
index 317796a..e902edf 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -69,6 +69,7 @@
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/des.h>
+#include <openssl/ocsp.h>
#include <lua.h>
#include <lualib.h>
@@ -272,6 +273,14 @@
#define HAVE_SSL_CTX_CERT_STORE (!OPENSSL_PREREQ(1,1,0))
#endif
+#ifndef HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
+#define HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
+#define HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
+#endif
+
#ifndef HAVE_SSL_GET0_ALPN_SELECTED
#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
#endif
@@ -288,6 +297,10 @@
#define HAVE_SSL_SET1_PARAM OPENSSL_PREREQ(1,0,2)
#endif
+#ifndef HAVE_SSL_GET_TLSEXT_STATUS_TYPE
+#define HAVE_SSL_GET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
+#endif
+
#ifndef HAVE_SSL_UP_REF
#define HAVE_SSL_UP_REF OPENSSL_PREREQ(1,1,0)
#endif
@@ -382,6 +395,8 @@
#define DIGEST_CLASS "EVP_MD_CTX*"
#define HMAC_CLASS "HMAC_CTX*"
#define CIPHER_CLASS "EVP_CIPHER_CTX*"
+#define OCSP_RESPONSE_CLASS "OCSP_RESPONSE*"
+#define OCSP_BASICRESP_CLASS "OCSP_BASICRESP*"
#if __GNUC__
@@ -6023,6 +6038,40 @@ static int xc_getExtensionCount(lua_State *L) {
} /* xc_getExtensionCount() */
+static int sk_openssl_string__gc(lua_State *L) {
+ STACK_OF(OPENSSL_STRING) **res = lua_touserdata(L, 1);
+
+ if (*res) {
+ sk_OPENSSL_STRING_free(*res);
+ *res = NULL;
+ }
+
+ return 0;
+} /* sk_openssl_string__gc() */
+
+
+static int xc_getOCSP(lua_State *L) {
+ X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
+ STACK_OF(OPENSSL_STRING) **res = prepsimple(L, NULL, &sk_openssl_string__gc);
+ int num, i;
+
+ *res = X509_get1_ocsp(crt);
+ if (!*res)
+ return 0;
+
+ num = sk_OPENSSL_STRING_num(*res);
+ luaL_checkstack(L, num, "too many authorityInfoAccess");
+ for (i = 0; i < num; i++) {
+ lua_pushstring(L, sk_OPENSSL_STRING_value(*res, i));
+ }
+
+ sk_OPENSSL_STRING_free(*res);
+ *res = NULL;
+
+ return num;
+} /* xc_getOCSP */
+
+
static int xc_isIssuedBy(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
X509 *issuer = checksimple(L, 2, X509_CERT_CLASS);
@@ -6258,6 +6307,7 @@ static const auxL_Reg xc_methods[] = {
{ "addExtension", &xc_addExtension },
{ "getExtension", &xc_getExtension },
{ "getExtensionCount", &xc_getExtensionCount },
+ { "getOCSP", &xc_getOCSP },
{ "isIssuedBy", &xc_isIssuedBy },
{ "getPublicKey", &xc_getPublicKey },
{ "setPublicKey", &xc_setPublicKey },
@@ -8062,6 +8112,48 @@ static int sx_setAlpnSelect(lua_State *L) {
#endif
+int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp };
+const char *TLSEXT_STATUSTYPEs_names[] = { "ocsp", NULL };
+#define checkTLSEXT_STATUSTYPE(L, idx) \
+ (TLSEXT_STATUSTYPEs[luaL_checkoption((L), (idx), NULL, TLSEXT_STATUSTYPEs_names)])
+
+
+#if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
+static int sx_setTLSextStatusType(lua_State *L) {
+ SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
+ int type = checkTLSEXT_STATUSTYPE(L, 2);
+
+ if(!SSL_CTX_set_tlsext_status_type(ctx, type))
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusType");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* sx_setTLSextStatusType() */
+#endif
+
+
+#if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
+static int sx_getTLSextStatusType(lua_State *L) {
+ SSL_CTX *ctx = checksimple(L, 1, SSL_CLASS);
+
+ int type = SSL_CTX_get_tlsext_status_type(ctx);
+ switch(type) {
+ case -1:
+ lua_pushnil(L);
+ break;
+ case TLSEXT_STATUSTYPE_ocsp:
+ lua_pushliteral(L, "ocsp");
+ break;
+ default:
+ luaL_error(L, "unknown TLS extension %d", type);
+ }
+
+ return 1;
+} /* sx_getTLSextStatusType() */
+#endif
+
+
static int sx__gc(lua_State *L) {
SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS);
@@ -8094,6 +8186,12 @@ static const auxL_Reg sx_methods[] = {
#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
{ "setAlpnSelect", &sx_setAlpnSelect },
#endif
+#if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
+ { "setTLSextStatusType", &sx_setTLSextStatusType },
+#endif
+#if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
+ { "getTLSextStatusType", &sx_getTLSextStatusType },
+#endif
{ NULL, NULL },
};
@@ -8446,6 +8544,87 @@ static int ssl_setAlpnProtos(lua_State *L) {
#endif
+static int ssl_setTLSextStatusType(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ int type = checkTLSEXT_STATUSTYPE(L, 2);
+
+ if(!SSL_set_tlsext_status_type(ssl, type))
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusType");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setTLSextStatusType() */
+
+
+#if HAVE_SSL_GET_TLSEXT_STATUS_TYPE
+static int ssl_getTLSextStatusType(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+
+ int type = SSL_get_tlsext_status_type(ssl);
+ switch(type) {
+ case -1:
+ lua_pushnil(L);
+ break;
+ case TLSEXT_STATUSTYPE_ocsp:
+ lua_pushliteral(L, "ocsp");
+ break;
+ default:
+ luaL_error(L, "unknown TLS extension %d", type);
+ }
+
+ return 1;
+} /* ssl_getTLSextStatusType() */
+#endif
+
+
+static int ssl_setTLSextStatusOCSPResp(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ OCSP_RESPONSE *or = testsimple(L, 2, OCSP_RESPONSE_CLASS);
+
+ unsigned char *resp = NULL;
+ long resp_len;
+
+ if (or) {
+ resp_len = i2d_OCSP_RESPONSE(or, &resp);
+ if (resp_len <= 0)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusOCSPResp");
+ } else {
+ resp_len = 0;
+ }
+
+ if (!SSL_set_tlsext_status_ocsp_resp(ssl, resp, resp_len))
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusOCSPResp");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setTLSextStatusOCSPResp() */
+
+
+static int ssl_getTLSextStatusOCSPResp(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+
+ OCSP_RESPONSE **ud = prepsimple(L, OCSP_RESPONSE_CLASS);
+ const unsigned char *resp;
+ long resp_len;
+
+ resp_len = SSL_get_tlsext_status_ocsp_resp(ssl, &resp);
+ if (resp == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+ if (resp_len == -1)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:getTLSextStatusOCSPResp");
+
+ *ud = d2i_OCSP_RESPONSE(NULL, &resp, resp_len);
+ if(*ud == NULL)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:getTLSextStatusOCSPResp");
+
+ return 1;
+} /* ssl_getTLSextStatusOCSPResp() */
+
+
static int ssl__gc(lua_State *L) {
SSL **ud = luaL_checkudata(L, 1, SSL_CLASS);
@@ -8478,6 +8657,12 @@ static const auxL_Reg ssl_methods[] = {
#if HAVE_SSL_SET_ALPN_PROTOS
{ "setAlpnProtos", &ssl_setAlpnProtos },
#endif
+ { "setTLSextStatusType", &ssl_setTLSextStatusType },
+#if HAVE_SSL_GET_TLSEXT_STATUS_TYPE
+ { "getTLSextStatusType", &ssl_getTLSextStatusType },
+#endif
+ { "setTLSextStatusOCSPResp", &ssl_setTLSextStatusOCSPResp },
+ { "getTLSextStatusOCSPResp", &ssl_getTLSextStatusOCSPResp },
{ NULL, NULL },
};
@@ -9215,6 +9400,166 @@ int luaopen__openssl_cipher(lua_State *L) {
/*
+ * OCSP_RESPONSE - openssl.ocsp.response
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static int or_tostring(lua_State *L) {
+ OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
+ BIO *bio = getbio(L);
+ size_t len;
+ char *bytes;
+
+ if (!OCSP_RESPONSE_print(bio, resp, 0))
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:tostring");
+
+ len = BIO_get_mem_data(bio, &bytes);
+ lua_pushlstring(L, bytes, len);
+
+ return 1;
+} /* or__tostring() */
+
+
+static int or_toPEM(lua_State *L) {
+ OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
+ BIO *bio = getbio(L);
+ size_t len;
+ char *bytes;
+
+ if (!PEM_write_bio_OCSP_RESPONSE(bio, resp))
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:toPEM");
+
+ len = BIO_get_mem_data(bio, &bytes);
+ lua_pushlstring(L, bytes, len);
+
+ return 1;
+} /* or_toPEM() */
+
+
+static int or_getBasic(lua_State *L) {
+ OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
+
+ OCSP_BASICRESP **basic = prepsimple(L, OCSP_BASICRESP_CLASS);
+
+ *basic = OCSP_response_get1_basic(resp);
+ if (!*basic)
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:getBasic");
+
+ return 1;
+} /* or_getBasic() */
+
+
+static int or__gc(lua_State *L) {
+ OCSP_RESPONSE **ud = luaL_checkudata(L, 1, OCSP_RESPONSE_CLASS);
+
+ if (*ud) {
+ OCSP_RESPONSE_free(*ud);
+ *ud = NULL;
+ }
+
+ return 0;
+} /* or__gc() */
+
+static const auxL_Reg or_methods[] = {
+ { "tostring", &or_tostring },
+ { "toPEM", &or_toPEM },
+ { "getBasic", &or_getBasic },
+ { NULL, NULL },
+};
+
+static const auxL_Reg or_metatable[] = {
+ { "__tostring", &or_tostring },
+ { "__gc", &or__gc },
+ { NULL, NULL },
+};
+
+static const auxL_Reg or_globals[] = {
+ { NULL, NULL },
+};
+
+int luaopen__openssl_ocsp_response(lua_State *L) {
+ initall(L);
+
+ auxL_newlib(L, or_globals, 0);
+
+ return 1;
+} /* luaopen__openssl_ocsp_response() */
+
+
+/*
+ * OCSP_BASICRESP - openssl.ocsp.basic
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static int ob_verify(lua_State *L) {
+ OCSP_BASICRESP *basic = checksimple(L, 1, OCSP_BASICRESP_CLASS);
+ STACK_OF(X509) *certs = testsimple(L, 2, X509_CHAIN_CLASS);
+ X509_STORE *store = testsimple(L, 3, X509_STORE_CLASS);
+ unsigned long flags = luaL_optinteger(L, 4, 0);
+
+ int res = OCSP_basic_verify(basic, certs, store, flags);
+ if (res == -1)
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_BASICRESP:verify");
+
+ lua_pushboolean(L, res);
+ if (res) {
+ return 1;
+ } else {
+ auxL_pusherror(L, auxL_EOPENSSL, NULL);
+ return 2;
+ }
+} /* ob_verify() */
+
+
+static int ob__gc(lua_State *L) {
+ OCSP_BASICRESP **ud = luaL_checkudata(L, 1, OCSP_BASICRESP_CLASS);
+
+ if (*ud) {
+ OCSP_BASICRESP_free(*ud);
+ *ud = NULL;
+ }
+
+ return 0;
+} /* or__gc() */
+
+
+static const auxL_Reg ob_methods[] = {
+ { "verify", &ob_verify },
+ { NULL, NULL },
+};
+
+static const auxL_Reg ob_metatable[] = {
+ { "__gc", &ob__gc },
+ { NULL, NULL },
+};
+
+static const auxL_Reg ob_globals[] = {
+ { NULL, NULL },
+};
+
+static const auxL_IntegerReg ob_verify_flags[] = {
+ { "NOSIGS", OCSP_NOSIGS},
+ { "NOVERIFY", OCSP_NOVERIFY},
+ { "NOCHAIN", OCSP_NOCHAIN},
+ { "NOCHECKS", OCSP_NOCHECKS},
+ { "NOEXPLICIT", OCSP_NOEXPLICIT},
+ { "TRUSTOTHER", OCSP_TRUSTOTHER},
+ { "NOINTERN", OCSP_NOINTERN},
+ { "TRUSTOTHER", OCSP_TRUSTOTHER},
+ { NULL, 0 },
+};
+
+int luaopen__openssl_ocsp_basic(lua_State *L) {
+ initall(L);
+
+ auxL_newlib(L, ob_globals, 0);
+ auxL_setintegers(L, ob_verify_flags);
+
+ return 1;
+} /* luaopen__openssl_ocsp_basic() */
+
+
+/*
* Rand - openssl.rand
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -9779,5 +10124,7 @@ static void initall(lua_State *L) {
auxL_addclass(L, DIGEST_CLASS, md_methods, md_metatable, 0);
auxL_addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable, 0);
auxL_addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable, 0);
+ auxL_addclass(L, OCSP_RESPONSE_CLASS, or_methods, or_metatable, 0);
+ auxL_addclass(L, OCSP_BASICRESP_CLASS, ob_methods, ob_metatable, 0);
} /* initall() */
diff --git a/src/openssl.ocsp.basic.lua b/src/openssl.ocsp.basic.lua
new file mode 100644
index 0000000..355faf7
--- /dev/null
+++ b/src/openssl.ocsp.basic.lua
@@ -0,0 +1,3 @@
+local ob = require "_openssl.ocsp.basic"
+
+return ob
diff --git a/src/openssl.ocsp.response.lua b/src/openssl.ocsp.response.lua
new file mode 100644
index 0000000..2226096
--- /dev/null
+++ b/src/openssl.ocsp.response.lua
@@ -0,0 +1,3 @@
+local ocsp_response = require "_openssl.ocsp.response"
+
+return ocsp_response