aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/luaossl.pdfbin284349 -> 284785 bytes
-rw-r--r--doc/luaossl.tex21
-rw-r--r--src/openssl.c142
3 files changed, 118 insertions, 45 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf
index f493d99..c2b2418 100644
--- a/doc/luaossl.pdf
+++ b/doc/luaossl.pdf
Binary files differ
diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index b52026d..b7b8c15 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -487,6 +487,10 @@ Returns the public key component as an \module{openssl.pkey} object.
Sets the public key component referenced by the \module{openssl.pkey} object $key$.
+\subsubsection[\fn{x509:getPublicKeyDigest}]{\fn{x509:getPublicKeyDigest([$type$])}}
+
+Returns the digest of the public key as a binary string. $type$ is an optional string describing the digest type, and defaults to ``sha1''.
+
\subsubsection[\fn{x509:sign}]{\fn{x509:sign($key$ [, $type$])}}
Signs and updates the instance certificate using the \module{openssl.pkey} $key$. $type$ is an optional string describing the digest type. See \module{pkey:sign}, regarding which types of digests are valid. If $type$ is omitted than a default type is used---``sha1'' for RSA keys, ``dss1'' for DSA keys, and ``ecdsa-with-SHA1'' for EC keys.
@@ -694,22 +698,25 @@ Returns a new context object. $protocol$ is an optional string identifier select
\begin{ctabular}{ c | p{14cm} }
\multicolumn{2}{c}{$protocol$ identifiers}\\\hline\hline
name & \href{https://www.openssl.org/docs/ssl/SSL_CTX_new.html}{description} \\\hline
-TLS & Supports TLS 1.0 and above. Internally uses \fn{SSLv23\_method} and disables SSLv2 and
+TLS & Supports TLS 1.0 \emph{and above}. Internally uses \fn{SSLv23\_method} and disables SSLv2 and
SSLv3 using \texttt{SSL\_OP\_NO\_SSLv2} and \texttt{SSL\_OP\_NO\_SSLv3}.\\
-SSL & Supports SSL 3.0 and above. Internally uses \fn{SSLv23\_method} and disables SSLv2 using \texttt{SSL\_OP\_NO\_SSLv2}.\\
+SSL & Supports SSL 3.0 \emph{and above}. Internally uses \fn{SSLv23\_method} and disables SSLv2 using \texttt{SSL\_OP\_NO\_SSLv2}.\\
SSLv23 & A catchall for all versions of SSL/TLS supported by OpenSSL. Individual versions can be disabled using \method{context:setOptions}. Internally uses \fn{SSLv23\_method}.\\
-TLSv1\_2 & Supports \emph{only} TLS 1.2; \emph{not} anything lower \emph{or} higher. Internally uses \fn{TLSv1\_2\_method}.\\
+TLSv1\_2 & Supports \emph{only} TLS 1.2. Internally uses \fn{TLSv1\_2\_method}.\\
-TLSv1\_1 & Supports \emph{only} TLS 1.1; \emph{not} anything lower \emph{or} higher. Internally uses \fn{TLSv1\_1\_method}.\\
+TLSv1\_1 & Supports \emph{only} TLS 1.1. Internally uses \fn{TLSv1\_1\_method}.\\
-TLSv1 & Supports \emph{only} TLS 1.0; \emph{not} anything lower \emph{or} higher. Internally uses \fn{TLSv1\_method}.\\
+TLSv1 & Supports \emph{only} TLS 1.0. Internally uses \fn{TLSv1\_method}.\\
-SSLv3 & Supports \emph{only} SSL 3.0; \emph{not} anything lower \emph{or} higher. Internally uses \fn{SSLv3\_method}.\\
+SSLv3 & Supports \emph{only} SSL 3.0. Internally uses \fn{SSLv3\_method}.\\
-SSLv2 & Supports \emph{only} SSL 2.0; \emph{not} anything lower \emph{or} higher. Internally uses \fn{SSLv2\_method}.
+SSLv2 & Supports \emph{only} SSL 2.0. Internally uses \fn{SSLv2\_method}. \\
+DTLS & Supports DTLS 1.0 \emph{and above}. Internally uses \fn{DTLS\_method}. \\
+DTLSv1 & Supports \emph{only} DTLS 1.0. Internally uses \fn{DTLSv1\_method}. \\
+DTLSv1\_2 & Supports \emph{only} DTLS 1.2. Internally uses \fn{DTLSv1\_2\_method}.
\end{ctabular}
diff --git a/src/openssl.c b/src/openssl.c
index 3b75e63..63c3985 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -76,12 +76,18 @@
#include "compat52.h"
#endif
+#define OPENSSL_PREREQ(M, m, p) \
+ (OPENSSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)) && !defined LIBRESSL_VERSION_NUMBER)
+
+#define LIBRESSL_PREREQ(M, m, p) \
+ (LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)))
+
#ifndef HAVE_DLADDR
#define HAVE_DLADDR (!defined _AIX) /* TODO: https://root.cern.ch/drupal/content/aix-and-dladdr */
#endif
#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
-#define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined LIBRESSL_VERSION_NUMBER)
+#define HAVE_SSL_CTX_SET_ALPN_PROTOS OPENSSL_PREREQ(1, 0, 2)
#endif
#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
@@ -96,6 +102,30 @@
#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
#endif
+#ifndef HAVE_DTLSV1_CLIENT_METHOD
+#define HAVE_DTLSV1_CLIENT_METHOD (!defined OPENSSL_NO_DTLS1)
+#endif
+
+#ifndef HAVE_DTLSV1_SERVER_METHOD
+#define HAVE_DTLSV1_SERVER_METHOD HAVE_DTLSV1_CLIENT_METHOD
+#endif
+
+#ifndef HAVE_DTLS_CLIENT_METHOD
+#define HAVE_DTLS_CLIENT_METHOD (OPENSSL_PREREQ(1, 0, 2) && !defined OPENSSL_NO_DTLS1)
+#endif
+
+#ifndef HAVE_DTLS_SERVER_METHOD
+#define HAVE_DTLS_SERVER_METHOD HAVE_DTLS_CLIENT_METHOD
+#endif
+
+#ifndef HAVE_DTLSV1_2_CLIENT_METHOD
+#define HAVE_DTLSV1_2_CLIENT_METHOD (OPENSSL_PREREQ(1, 0, 2) && !defined OPENSSL_NO_DTLS1)
+#endif
+
+#ifndef HAVE_DTLSV1_2_SERVER_METHOD
+#define HAVE_DTLSV1_2_SERVER_METHOD HAVE_DTLSV1_2_CLIENT_METHOD
+#endif
+
#ifndef STRERROR_R_CHAR_P
#define STRERROR_R_CHAR_P (defined __GLIBC__ && (_GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)))
#endif
@@ -279,7 +309,13 @@ static void addclass(lua_State *L, const char *name, const luaL_Reg *methods, co
} /* addclass() */
-static int checkoption(struct lua_State *L, int index, const char *def, const char *const opts[]) {
+static int badoption(lua_State *L, int index, const char *opt) {
+ opt = (opt)? opt : luaL_checkstring(L, index);
+
+ return luaL_argerror(L, index, lua_pushfstring(L, "invalid option %s", opt));
+} /* badoption() */
+
+static int checkoption(lua_State *L, int index, const char *def, const char *const opts[]) {
const char *opt = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index);
int i;
@@ -288,7 +324,7 @@ static int checkoption(struct lua_State *L, int index, const char *def, const ch
return i;
}
- return luaL_argerror(L, index, lua_pushfstring(L, "invalid option %s", opt));
+ return badoption(L, index, opt);
} /* checkoption() */
@@ -820,7 +856,6 @@ static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPT
static int compat_init(void) {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int store_index = -1, ssl_ctx_index = -1, done;
- X509_STORE *store;
int error = 0;
if ((error = pthread_mutex_lock(&mutex)))
@@ -1615,7 +1650,6 @@ static int bn__mul(lua_State *L) {
static int bn__div(lua_State *L) {
BIGNUM *r, *a, *b;
- BN_CTX *ctx;
bn_prepops(L, &r, &a, &b, 0);
@@ -1628,7 +1662,6 @@ static int bn__div(lua_State *L) {
static int bn__mod(lua_State *L) {
BIGNUM *r, *a, *b;
- BN_CTX *ctx;
bn_prepops(L, &r, &a, &b, 0);
@@ -1641,7 +1674,6 @@ static int bn__mod(lua_State *L) {
static int bn__pow(lua_State *L) {
BIGNUM *r, *a, *b;
- BN_CTX *ctx;
bn_prepops(L, &r, &a, &b, 0);
@@ -2291,7 +2323,6 @@ static int pk__tostring(lua_State *L) {
BIO *bio = getbio(L);
char *data;
long len;
- int ok = 0;
switch (type) {
case X509_PEM:
@@ -2845,7 +2876,6 @@ static int xe_new(lua_State *L) {
ASN1_STRING *oct = NULL;
CONF *conf = NULL;
X509V3_CTX cbuf = { 0 }, *ctx = NULL;
- X509_EXTENSION *ext = NULL;
if (!lua_isnil(L, 3)) {
size_t len;
@@ -3199,7 +3229,6 @@ static double timeutc(ASN1_TIME *time) {
char buf[32] = "", *cp;
struct tm tm = { 0 };
int gmtoff = 0, year, i;
- double ts;
if (!ASN1_TIME_check(time))
return 0;
@@ -3297,7 +3326,6 @@ static int xc_getLifetime(lua_State *L) {
static int xc_setLifetime(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
- ASN1_TIME *time;
double ut;
const char *dt;
@@ -3757,6 +3785,25 @@ static int xc_setPublicKey(lua_State *L) {
} /* xc_setPublicKey() */
+static int xc_getPublicKeyDigest(lua_State *L) {
+ ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(checksimple(L, 1, X509_CERT_CLASS));
+ const char *id = luaL_optstring(L, 2, "sha1");
+ const EVP_MD *md;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ unsigned int len;
+
+ if (!(md = EVP_get_digestbyname(id)))
+ return luaL_error(L, "x509.cert:getPublicKeyDigest: %s: invalid digest type", id);
+
+ if (!EVP_Digest(pk->data, pk->length, digest, &len, md, NULL))
+ return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest");
+
+ lua_pushlstring(L, (char *)digest, len);
+
+ return 1;
+} /* xc_getPublicKeyDigest() */
+
+
static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) {
const char *id;
const EVP_MD *md;
@@ -3918,6 +3965,7 @@ static const luaL_Reg xc_methods[] = {
{ "isIssuedBy", &xc_isIssuedBy },
{ "getPublicKey", &xc_getPublicKey },
{ "setPublicKey", &xc_setPublicKey },
+ { "getPublicKeyDigest", &xc_getPublicKeyDigest },
{ "sign", &xc_sign },
{ "text", &xc_text },
{ "tostring", &xc__tostring },
@@ -4246,7 +4294,6 @@ static int xx_getLastUpdate(lua_State *L) {
static int xx_setLastUpdate(lua_State *L) {
X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
double updated = luaL_checknumber(L, 2);
- ASN1_TIME *time = NULL;
/* lastUpdate always present */
if (!ASN1_TIME_set(X509_CRL_get_lastUpdate(crl), updated))
@@ -5027,15 +5074,17 @@ int luaopen__openssl_pkcs12(lua_State *L) {
*/
static int sx_new(lua_State *L) {
static const char *const opts[] = {
- "SSLv2", "SSLv3", "SSLv23",
- "TLSv1", "TLSv1.0",
-#if defined SSL_OP_NO_TLSv1_1
- "TLSv1_1", "TLSv1.1",
-#endif
-#if defined SSL_OP_NO_TLSv1_2
- "TLSv1_2", "TLSv1.2",
-#endif
- "SSL", "TLS",
+ [0] = "SSL",
+ [1] = "TLS",
+ [2] = "SSLv2",
+ [3] = "SSLv3",
+ [4] = "SSLv23",
+ [5] = "TLSv1", [6] = "TLSv1.0",
+ [7] = "TLSv1_1", [8] = "TLSv1.1",
+ [9] = "TLSv1_2", [10] = "TLSv1.2",
+ [11] = "DTLS",
+ [12] = "DTLSv1", [13] = "DTLSv1.0",
+ [14] = "DTLSv1_2", [15] = "DTLSv1.2",
NULL
};
/* later versions of SSL declare a const qualifier on the return type */
@@ -5048,41 +5097,60 @@ static int sx_new(lua_State *L) {
srv = lua_toboolean(L, 2);
switch (checkoption(L, 1, "TLS", opts)) {
+ case 0: /* SSL */
+ method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
+ options = SSL_OP_NO_SSLv2;
+ break;
+ case 1: /* TLS */
+ method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
+ options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ break;
#ifndef OPENSSL_NO_SSL2
- case 0: /* SSLv2 */
+ case 2: /* SSLv2 */
method = (srv)? &SSLv2_server_method : &SSLv2_client_method;
break;
#endif
- case 1: /* SSLv3 */
+ case 3: /* SSLv3 */
method = (srv)? &SSLv3_server_method : &SSLv3_client_method;
break;
- case 2: /* SSLv23 */
+ case 4: /* SSLv23 */
method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
break;
- case 3: /* TLSv1 */
- case 4: /* TLSv1.0 */
+ case 5: /* TLSv1 */
+ case 6: /* TLSv1.0 */
method = (srv)? &TLSv1_server_method : &TLSv1_client_method;
break;
#if defined SSL_OP_NO_TLSv1_1
- case 5: /* TLSv1_1 */
- case 6: /* TLSv1.1 */
+ case 7: /* TLSv1_1 */
+ case 8: /* TLSv1.1 */
method = (srv)? &TLSv1_1_server_method : &TLSv1_1_client_method;
break;
#endif
#if defined SSL_OP_NO_TLSv1_2
- case 7: /* TLSv1_2 */
- case 8: /* TLSv1.2 */
+ case 9: /* TLSv1_2 */
+ case 10: /* TLSv1.2 */
method = (srv)? &TLSv1_2_server_method : &TLSv1_2_client_method;
break;
#endif
- case 9: /* SSL */
- method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
- options = SSL_OP_NO_SSLv2;
+#if HAVE_DTLS_CLIENT_METHOD
+ case 11: /* DTLS */
+ method = (srv)? &DTLS_server_method : &DTLS_client_method;
break;
- case 10: /* TLS */
- method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
- options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+#endif
+#if HAVE_DTLSV1_CLIENT_METHOD
+ case 12: /* DTLSv1 */
+ case 13: /* DTLSv1.0 */
+ method = (srv)? &DTLSv1_server_method : &DTLSv1_client_method;
break;
+#endif
+#if HAVE_DTLSV1_2_CLIENT_METHOD
+ case 14: /* DTLSv1_2 */
+ case 15: /* DTLSv1.2 */
+ method = (srv)? &DTLSv1_server_method : &DTLSv1_client_method;
+ break;
+#endif
+ default:
+ return badoption(L, 1, NULL);
}
ud = prepsimple(L, SSL_CTX_CLASS);
@@ -5364,7 +5432,6 @@ noack:
static int sx_setAlpnSelect(lua_State *L) {
SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
- struct ex_data *data;
int error;
luaL_checktype(L, 2, LUA_TFUNCTION);
@@ -5848,7 +5915,6 @@ static void md_update_(lua_State *L, EVP_MD_CTX *ctx, int from, int to) {
static int md_update(lua_State *L) {
EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
- int i;
md_update_(L, ctx, 2, lua_gettop(L));