aboutsummaryrefslogtreecommitdiffstats
path: root/src/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openssl.c')
-rw-r--r--src/openssl.c1004
1 files changed, 814 insertions, 190 deletions
diff --git a/src/openssl.c b/src/openssl.c
index 2275d49..ed7222e 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -23,6 +23,10 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE.
* ==========================================================================
*/
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <limits.h> /* INT_MAX INT_MIN LLONG_MAX LLONG_MIN UCHAR_MAX ULLONG_MAX */
#include <stdint.h> /* uintptr_t */
#include <string.h> /* memset(3) strerror_r(3) */
@@ -79,24 +83,40 @@
#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 */
+#ifndef HAVE_ASN1_STRING_GET0_DATA
+#define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
-#define HAVE_SSL_CTX_SET_ALPN_PROTOS OPENSSL_PREREQ(1, 0, 2)
+#ifndef HAVE_DH_GET0_KEY
+#define HAVE_DH_GET0_KEY OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
-#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifndef HAVE_DH_GET0_PQG
+#define HAVE_DH_GET0_PQG OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_SET_ALPN_PROTOS
-#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifndef HAVE_DH_SET0_KEY
+#define HAVE_DH_SET0_KEY OPENSSL_PREREQ(1,1,0)
#endif
-#ifndef HAVE_SSL_GET0_ALPN_SELECTED
-#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifndef HAVE_DH_SET0_PQG
+#define HAVE_DH_SET0_PQG OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_GET0_KEY
+#define HAVE_DSA_GET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_GET0_PQG
+#define HAVE_DSA_GET0_PQG OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_SET0_KEY
+#define HAVE_DSA_SET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_DSA_SET0_PQG
+#define HAVE_DSA_SET0_PQG OPENSSL_PREREQ(1,1,0)
#endif
#ifndef HAVE_DTLSV1_CLIENT_METHOD
@@ -108,7 +128,7 @@
#endif
#ifndef HAVE_DTLS_CLIENT_METHOD
-#define HAVE_DTLS_CLIENT_METHOD (OPENSSL_PREREQ(1, 0, 2) && !defined OPENSSL_NO_DTLS1)
+#define HAVE_DTLS_CLIENT_METHOD (OPENSSL_PREREQ(1,0,2) && !defined OPENSSL_NO_DTLS1)
#endif
#ifndef HAVE_DTLS_SERVER_METHOD
@@ -116,13 +136,133 @@
#endif
#ifndef HAVE_DTLSV1_2_CLIENT_METHOD
-#define HAVE_DTLSV1_2_CLIENT_METHOD (OPENSSL_PREREQ(1, 0, 2) && !defined OPENSSL_NO_DTLS1)
+#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 HAVE_EVP_CIPHER_CTX_FREE
+#define HAVE_EVP_CIPHER_CTX_FREE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_CIPHER_CTX_NEW
+#define HAVE_EVP_CIPHER_CTX_NEW OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_MD_CTX_FREE
+#define HAVE_EVP_MD_CTX_FREE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_MD_CTX_NEW
+#define HAVE_EVP_MD_CTX_NEW OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID
+#define HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID OPENSSL_PREREQ(0,9,9)
+#endif
+
+#ifndef HAVE_EVP_PKEY_BASE_ID
+#define HAVE_EVP_PKEY_BASE_ID OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_PKEY_GET0
+#define HAVE_EVP_PKEY_GET0 OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_EVP_PKEY_ID
+#define HAVE_EVP_PKEY_ID OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_HMAC_CTX_FREE
+#define HAVE_HMAC_CTX_FREE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_HMAC_CTX_NEW
+#define HAVE_HMAC_CTX_NEW OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_I2D_RE_X509_REQ_TBS
+#define HAVE_I2D_RE_X509_REQ_TBS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_GET0_CRT_PARAMS
+#define HAVE_RSA_GET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_GET0_FACTORS
+#define HAVE_RSA_GET0_FACTORS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_GET0_KEY
+#define HAVE_RSA_GET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_SET0_CRT_PARAMS
+#define HAVE_RSA_SET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_SET0_FACTORS
+#define HAVE_RSA_SET0_FACTORS OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_RSA_SET0_KEY
+#define HAVE_RSA_SET0_KEY OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_CLIENT_VERSION
+#define HAVE_SSL_CLIENT_VERSION OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
+#define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,1,3))
+#endif
+
+#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
+#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS
+#endif
+
+#ifndef HAVE_SSL_CTX_SET1_CERT_STORE
+#define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */
+#endif
+
+#ifndef HAVE_SSL_CTX_CERT_STORE
+#define HAVE_SSL_CTX_CERT_STORE (!OPENSSL_PREREQ(1,1,0))
+#endif
+
+#ifndef HAVE_SSL_SET_ALPN_PROTOS
+#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
+#endif
+
+#ifndef HAVE_SSL_GET0_ALPN_SELECTED
+#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
+#endif
+
+#ifndef HAVE_SSL_UP_REF
+#define HAVE_SSL_UP_REF OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSLV2_CLIENT_METHOD
+#define HAVE_SSLV2_CLIENT_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
+#endif
+
+#ifndef HAVE_SSLV2_SERVER_METHOD
+#define HAVE_SSLV2_SERVER_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
+#endif
+
+#ifndef HAVE_X509_STORE_REFERENCES
+#define HAVE_X509_STORE_REFERENCES (!OPENSSL_PREREQ(1,1,0))
+#endif
+
+#ifndef HAVE_X509_UP_REF
+#define HAVE_X509_UP_REF OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HMAC_INIT_EX_INT
+#define HMAC_INIT_EX_INT OPENSSL_PREREQ(1,0,0)
+#endif
+
#ifndef STRERROR_R_CHAR_P
#define STRERROR_R_CHAR_P (defined __GLIBC__ && (_GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)))
#endif
@@ -161,9 +301,9 @@
#define PKCS12_CLASS "PKCS12*"
#define SSL_CTX_CLASS "SSL_CTX*"
#define SSL_CLASS "SSL*"
-#define DIGEST_CLASS "EVP_MD_CTX" /* not a pointer */
-#define HMAC_CLASS "HMAC_CTX" /* not a pointer */
-#define CIPHER_CLASS "EVP_CIPHER_CTX" /* not a pointer */
+#define DIGEST_CLASS "EVP_MD_CTX*"
+#define HMAC_CLASS "HMAC_CTX*"
+#define CIPHER_CLASS "EVP_CIPHER_CTX*"
#if __GNUC__
@@ -488,6 +628,13 @@ static const char *aux_strerror_r(int error, char *dst, size_t lim) {
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+static void auxS_bn_free_and_set0(BIGNUM **dst, BIGNUM *src) {
+ if (*dst) {
+ BN_clear_free(*dst);
+ }
+ *dst = src;
+} /* auxS_bn_free_and_set0() */
+
static size_t auxS_nid2sn(void *dst, size_t lim, int nid) {
const char *sn;
@@ -1021,14 +1168,173 @@ static struct {
.X509_STORE_free = &X509_STORE_free,
};
+#if !HAVE_ASN1_STRING_GET0_DATA
+#define ASN1_STRING_get0_data(s) ASN1_STRING_data((s))
+#endif
+
+#if !HAVE_DH_GET0_KEY
+#define DH_get0_key(...) compat_DH_get0_key(__VA_ARGS__)
+
+static void compat_DH_get0_key(const DH *d, const BIGNUM **pub_key, const BIGNUM **priv_key) {
+ if (pub_key)
+ *pub_key = d->pub_key;
+ if (priv_key)
+ *priv_key = d->priv_key;
+} /* compat_DH_get0_key() */
+#endif
+
+#if !HAVE_DH_GET0_PQG
+#define DH_get0_pqg(...) compat_DH_get0_pqg(__VA_ARGS__)
+
+static void compat_DH_get0_pqg(const DH *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
+ if (p)
+ *p = d->p;
+ if (q)
+ *q = d->q;
+ if (g)
+ *g = d->g;
+} /* compat_DH_get0_pqg() */
+#endif
+
+#if !HAVE_DH_SET0_KEY
+#define DH_set0_key(...) compat_DH_set0_key(__VA_ARGS__)
+
+static void compat_DH_set0_key(DH *d, BIGNUM *pub_key, BIGNUM *priv_key) {
+ if (pub_key)
+ auxS_bn_free_and_set0(&d->pub_key, pub_key);
+ if (priv_key)
+ auxS_bn_free_and_set0(&d->priv_key, priv_key);
+} /* compat_DH_set0_key() */
+#endif
+
+#if !HAVE_DH_SET0_PQG
+#define DH_set0_pqg(...) compat_DH_set0_pqg(__VA_ARGS__)
+
+static void compat_DH_set0_pqg(DH *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
+ if (p)
+ auxS_bn_free_and_set0(&d->p, p);
+ if (q)
+ auxS_bn_free_and_set0(&d->q, q);
+ if (g)
+ auxS_bn_free_and_set0(&d->g, g);
+} /* compat_DH_set0_pqg() */
+#endif
+
+#if !HAVE_DSA_GET0_KEY
+#define DSA_get0_key(...) compat_DSA_get0_key(__VA_ARGS__)
+
+static void compat_DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) {
+ if (pub_key)
+ *pub_key = d->pub_key;
+ if (priv_key)
+ *priv_key = d->priv_key;
+} /* compat_DSA_get0_key() */
+#endif
+
+#if !HAVE_DSA_GET0_PQG
+#define DSA_get0_pqg(...) compat_DSA_get0_pqg(__VA_ARGS__)
+
+static void compat_DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
+ if (p)
+ *p = d->p;
+ if (q)
+ *q = d->q;
+ if (g)
+ *g = d->g;
+} /* compat_DSA_get0_pqg() */
+#endif
+
+#if !HAVE_DSA_SET0_KEY
+#define DSA_set0_key(...) compat_DSA_set0_key(__VA_ARGS__)
+
+static void compat_DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) {
+ if (pub_key)
+ auxS_bn_free_and_set0(&d->pub_key, pub_key);
+ if (priv_key)
+ auxS_bn_free_and_set0(&d->priv_key, priv_key);
+} /* compat_DSA_set0_key() */
+#endif
+
+#if !HAVE_DSA_SET0_PQG
+#define DSA_set0_pqg(...) compat_DSA_set0_pqg(__VA_ARGS__)
+
+static void compat_DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
+ if (p)
+ auxS_bn_free_and_set0(&d->p, p);
+ if (q)
+ auxS_bn_free_and_set0(&d->q, q);
+ if (g)
+ auxS_bn_free_and_set0(&d->g, g);
+} /* compat_DSA_set0_pqg() */
+#endif
+
+#if !HAVE_EVP_CIPHER_CTX_FREE
+#define EVP_CIPHER_CTX_free(ctx) compat_EVP_CIPHER_CTX_free((ctx))
+
+static void compat_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) {
+ EVP_CIPHER_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+} /* compat_EVP_CIPHER_CTX_free() */
+#endif
+
+#if !HAVE_EVP_CIPHER_CTX_NEW
+#define EVP_CIPHER_CTX_new() compat_EVP_CIPHER_CTX_new()
+
+static EVP_CIPHER_CTX *compat_EVP_CIPHER_CTX_new(void) {
+ EVP_CIPHER_CTX *ctx;
+
+ if (!(ctx = OPENSSL_malloc(sizeof *ctx)))
+ return NULL;
+ memset(ctx, 0, sizeof *ctx);
+ EVP_CIPHER_CTX_init(ctx);
+
+ return ctx;
+} /* compat_EVP_CIPHER_CTX_new() */
+#endif
+
+#if !HAVE_EVP_MD_CTX_FREE
+#define EVP_MD_CTX_free(md) EVP_MD_CTX_destroy((md))
+#endif
+
+#if !HAVE_EVP_MD_CTX_NEW
+#define EVP_MD_CTX_new(md) EVP_MD_CTX_create()
+#endif
+
+#if !HAVE_EVP_PKEY_ID
+#define EVP_PKEY_id(key) ((key)->type)
+#endif
+
#if !HAVE_EVP_PKEY_BASE_ID
#define EVP_PKEY_base_id(key) compat_EVP_PKEY_base_id((key))
static int compat_EVP_PKEY_base_id(EVP_PKEY *key) {
- return EVP_PKEY_type(key->type);
+ return EVP_PKEY_type(EVP_PKEY_id(key));
} /* compat_EVP_PKEY_base_id() */
#endif
+#if !HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID
+#define EVP_PKEY_get_default_digest_nid(...) \
+ compat_EVP_PKEY_get_default_digest_nid(__VA_ARGS__)
+
+static int compat_EVP_PKEY_get_default_digest_nid(EVP_PKEY *key, int *nid) {
+ switch (EVP_PKEY_base_id(key)) {
+ case EVP_PKEY_RSA:
+ *nid = EVP_MD_nid(EVP_sha1());
+ break;
+ case EVP_PKEY_DSA:
+ *nid = EVP_MD_nid(EVP_dss1());
+ break;
+ case EVP_PKEY_EC:
+ *nid = EVP_MD_nid(EVP_ecdsa());
+ break;
+ default:
+ *nid = EVP_MD_nid(EVP_sha1());
+ break;
+ }
+
+ return 1;
+} /* compat_EVP_PKEY_get_default_digest_nid() */
+#endif
#if !HAVE_EVP_PKEY_GET0
#define EVP_PKEY_get0(key) compat_EVP_PKEY_get0((key))
@@ -1065,6 +1371,123 @@ static void *compat_EVP_PKEY_get0(EVP_PKEY *key) {
} /* compat_EVP_PKEY_get0() */
#endif
+#if !HAVE_HMAC_CTX_FREE
+#define HMAC_CTX_free(ctx) compat_HMAC_CTX_free((ctx))
+
+static void compat_HMAC_CTX_free(HMAC_CTX *ctx) {
+ HMAC_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+} /* compat_HMAC_CTX_free() */
+#endif
+
+#if !HAVE_HMAC_CTX_NEW
+#define HMAC_CTX_new() compat_HMAC_CTX_new()
+
+static HMAC_CTX *compat_HMAC_CTX_new(void) {
+ HMAC_CTX *ctx;
+
+ if (!(ctx = OPENSSL_malloc(sizeof *ctx)))
+ return NULL;
+ memset(ctx, 0, sizeof *ctx);
+
+ return ctx;
+} /* compat_HMAC_CTX_new() */
+#endif
+
+#if !HAVE_RSA_GET0_CRT_PARAMS
+#define RSA_get0_crt_params(...) compat_RSA_get0_crt_params(__VA_ARGS__)
+
+static void compat_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) {
+ if (dmp1)
+ *dmp1 = r->dmp1;
+ if (dmq1)
+ *dmq1 = r->dmq1;
+ if (iqmp)
+ *iqmp = r->iqmp;
+} /* compat_RSA_get0_crt_params() */
+#endif
+
+#if !HAVE_RSA_GET0_FACTORS
+#define RSA_get0_factors(...) compat_RSA_get0_factors(__VA_ARGS__)
+
+static void compat_RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) {
+ if (p)
+ *p = r->p;
+ if (q)
+ *q = r->q;
+} /* compat_RSA_get0_factors() */
+#endif
+
+#if !HAVE_RSA_GET0_KEY
+#define RSA_get0_key(...) compat_RSA_get0_key(__VA_ARGS__)
+
+static void compat_RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) {
+ if (n)
+ *n = r->n;
+ if (e)
+ *e = r->e;
+ if (d)
+ *d = r->d;
+} /* compat_RSA_get0_key() */
+#endif
+
+#if !HAVE_RSA_SET0_CRT_PARAMS
+#define RSA_set0_crt_params(...) compat_RSA_set0_crt_params(__VA_ARGS__)
+
+static void compat_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) {
+ if (dmp1)
+ auxS_bn_free_and_set0(&r->dmp1, dmp1);
+ if (dmq1)
+ auxS_bn_free_and_set0(&r->dmq1, dmq1);
+ if (iqmp)
+ auxS_bn_free_and_set0(&r->iqmp, iqmp);
+} /* compat_RSA_set0_crt_params() */
+#endif
+
+#if !HAVE_RSA_SET0_FACTORS
+#define RSA_set0_factors(...) compat_RSA_set0_factors(__VA_ARGS__)
+
+static void compat_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) {
+ if (p)
+ auxS_bn_free_and_set0(&r->p, p);
+ if (q)
+ auxS_bn_free_and_set0(&r->q, q);
+} /* compat_RSA_set0_factors() */
+#endif
+
+#if !HAVE_RSA_SET0_KEY
+#define RSA_set0_key(...) compat_RSA_set0_key(__VA_ARGS__)
+
+static void compat_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
+ if (n)
+ auxS_bn_free_and_set0(&r->n, n);
+ if (e)
+ auxS_bn_free_and_set0(&r->e, e);
+ if (d)
+ auxS_bn_free_and_set0(&r->d, d);
+} /* compat_RSA_set0_key() */
+#endif
+
+#if !HAVE_SSL_CLIENT_VERSION
+#define SSL_client_version(...) compat_SSL_client_version(__VA_ARGS__)
+
+static int compat_SSL_client_version(const SSL *ssl) {
+ return ssl->client_version;
+} /* compat_SSL_client_version() */
+#endif
+
+#if !HAVE_SSL_UP_REF
+#define SSL_up_ref(...) compat_SSL_up_ref(__VA_ARGS__)
+
+static int compat_SSL_up_ref(SSL *ssl) {
+ /* our caller should already have had a proper reference */
+ if (CRYPTO_add(&ssl->references, 1, CRYPTO_LOCK_SSL) < 2)
+ return 0; /* fail */
+
+ return 1;
+} /* compat_SSL_up_ref() */
+#endif
+
#if !HAVE_X509_GET0_EXT
#define X509_get0_ext(crt, i) X509_get_ext((crt), (i))
#endif
@@ -1081,13 +1504,18 @@ static void *compat_EVP_PKEY_get0(EVP_PKEY *key) {
#define X509_EXTENSION_get0_data(ext) X509_EXTENSION_get_data((ext))
#endif
+#if HAVE_X509_STORE_REFERENCES
/*
* X509_STORE_free in OpenSSL versions < 1.0.2 doesn't obey reference count
*/
#define X509_STORE_free(store) \
(compat.X509_STORE_free)((store))
-static void compat_X509_STORE_free(X509_STORE *store) {
+/* to support preprocessor detection below */
+#define compat_X509_STORE_free(store) \
+ compat_X509_STORE_free((store))
+
+static void (compat_X509_STORE_free)(X509_STORE *store) {
int i;
i = CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE);
@@ -1097,12 +1525,21 @@ static void compat_X509_STORE_free(X509_STORE *store) {
(X509_STORE_free)(store);
} /* compat_X509_STORE_free() */
+#endif
-#if !HAVE_SSL_CTX_set1_cert_store
+#if !HAVE_SSL_CTX_SET1_CERT_STORE
+#if !HAVE_SSL_CTX_CERT_STORE || !HAVE_X509_STORE_REFERENCES
#define SSL_CTX_set1_cert_store(ctx, store) \
+ SSL_CTX_set_cert_store((ctx), (store))
+#else
+#define SSL_CTX_set1_cert_store(ctx, store) \
+ compat_SSL_CTX_set1_cert_store((ctx), (store))
+
+/* to support preprocessor detection below */
+#define compat_SSL_CTX_set1_cert_store(ctx, store) \
compat_SSL_CTX_set1_cert_store((ctx), (store))
-static void compat_SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) {
+static void (compat_SSL_CTX_set1_cert_store)(SSL_CTX *ctx, X509_STORE *store) {
int n;
/*
@@ -1122,6 +1559,9 @@ static void compat_SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) {
CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
} /* compat_SSL_CTX_set1_cert_store() */
#endif
+#endif
+
+#if HAVE_SSL_CTX_CERT_STORE
static void compat_init_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
SSL_CTX *ctx = _ctx;
@@ -1132,6 +1572,8 @@ static void compat_init_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX
}
} /* compat_init_SSL_CTX_onfree() */
+#endif
+
/* helper routine to determine if X509_STORE_free obeys reference count */
static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
/* unfortunately there's no way to remove a handler */
@@ -1142,6 +1584,18 @@ static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPT
compat.tmp.store = NULL;
} /* compat_init_X509_STORE_onfree() */
+#if !HAVE_X509_UP_REF
+#define X509_up_ref(...) compat_X509_up_ref(__VA_ARGS__)
+
+static int compat_X509_up_ref(X509 *crt) {
+ /* our caller should already have had a proper reference */
+ if (CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509) < 2)
+ return 0; /* fail */
+
+ return 1;
+} /* compat_X509_up_ref() */
+#endif
+
static int compat_init(void) {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int store_index = -1, ssl_ctx_index = -1, done;
@@ -1161,6 +1615,7 @@ static int compat_init(void) {
if ((error = dl_anchor()))
goto epilog;
+#if defined compat_X509_STORE_free
/*
* Test if X509_STORE_free obeys reference counts by installing an
* onfree callback.
@@ -1210,6 +1665,7 @@ static int compat_init(void) {
compat.flags |= COMPAT_X509_STORE_FREE_BUG;
}
+#endif
done = 1;
epilog:
@@ -1262,7 +1718,13 @@ static struct ex_type {
[EX_SSL_CTX_ALPN_SELECT_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data },
};
-static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, CRYPTO_EX_DATA *from NOTUSED, void *from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
+#if OPENSSL_PREREQ(1,1,0)
+typedef const CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
+#else
+typedef CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
+#endif
+
+static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, const_CRYPTO_EX_DATA *from NOTUSED, void *from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
struct ex_data **data = from_d;
if (*data)
@@ -1861,13 +2323,13 @@ static BIGNUM *(checkbig)(lua_State *L, int index, _Bool *lvalue) {
if (hex) {
luaL_argcheck(L, len > 2+(size_t)neg, index, "invalid hex string");
for (i = 2+neg; i < len; i++) {
- if (!isxdigit(str[i]))
+ if (!isxdigit((unsigned char)str[i]))
luaL_argerror(L, 1, "invalid hex string");
}
} else {
luaL_argcheck(L, len > neg, index, "invalid decimal string");
for (i = neg; i < len; i++) {
- if (!isdigit(str[i]))
+ if (!isdigit((unsigned char)str[i]))
luaL_argerror(L, 1, "invalid decimal string");
}
}
@@ -2644,7 +3106,7 @@ static int pk_interpose(lua_State *L) {
static int pk_type(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
- int nid = key->type;
+ int nid = EVP_PKEY_id(key);
auxL_pushnid(L, nid);
@@ -2718,7 +3180,7 @@ static int pk_setPrivateKey(lua_State *L) {
static int pk_sign(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
- EVP_MD_CTX *md = luaL_checkudata(L, 2, DIGEST_CLASS);
+ EVP_MD_CTX *md = checksimple(L, 2, DIGEST_CLASS);
luaL_Buffer B;
unsigned n;
@@ -2742,7 +3204,7 @@ static int pk_verify(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
size_t len;
const void *sig = luaL_checklstring(L, 2, &len);
- EVP_MD_CTX *md = luaL_checkudata(L, 3, DIGEST_CLASS);
+ EVP_MD_CTX *md = checksimple(L, 3, DIGEST_CLASS);
switch (EVP_VerifyFinal(md, sig, len, key)) {
case 0: /* WRONG */
@@ -2806,7 +3268,7 @@ static int pk_toPEM(lua_State *L) {
#if 0
case 4: case 5: /* params, Parameters */
/* EVP_PKEY_base_id not in OS X */
- switch (EVP_PKEY_type(key->type)) {
+ switch (EVP_PKEY_base_id(key)) {
case EVP_PKEY_RSA:
break;
case EVP_PKEY_DSA: {
@@ -2849,7 +3311,7 @@ static int pk_toPEM(lua_State *L) {
}
#endif
default:
- return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_type(key->type));
+ return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_base_id(key));
}
lua_pushlstring(L, pem, len);
@@ -2869,6 +3331,26 @@ static int pk_toPEM(lua_State *L) {
} /* pk_toPEM() */
+static int pk_getDefaultDigestName(lua_State *L) {
+ EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
+ int nid;
+ char txt[256];
+ size_t len;
+
+ if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
+ return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
+
+ if (!(len = auxS_nid2txt(txt, sizeof txt, nid)))
+ return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
+ if (len > sizeof txt)
+ return auxL_error(L, EOVERFLOW, "pkey:getDefaultDigestName");
+
+ lua_pushlstring(L, txt, len);
+
+ return 1;
+} /* pk_getDefaultDigestName() */
+
+
enum pk_param {
#define PK_RSA_OPTLIST { "n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp", NULL }
#define PK_RSA_OPTOFFSET PK_RSA_N
@@ -2965,82 +3447,100 @@ static void pk_pushparam(lua_State *L, void *base_key, enum pk_param which) {
EC_KEY *ec;
#endif
} key = { base_key };
+ const BIGNUM *i;
switch (which) {
case PK_RSA_N:
/* RSA public modulus n */
- bn_dup_nil(L, key.rsa->n);
+ RSA_get0_key(key.rsa, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_E:
/* RSA public exponent e */
- bn_dup_nil(L, key.rsa->e);
+ RSA_get0_key(key.rsa, NULL, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_D:
/* RSA secret exponent d */
- bn_dup_nil(L, key.rsa->d);
+ RSA_get0_key(key.rsa, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_RSA_P:
/* RSA secret prime p */
- bn_dup_nil(L, key.rsa->p);
+ RSA_get0_factors(key.rsa, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_Q:
/* RSA secret prime q with p < q */
- bn_dup_nil(L, key.rsa->q);
+ RSA_get0_factors(key.rsa, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_RSA_DMP1:
/* exponent1 */
- bn_dup_nil(L, key.rsa->dmp1);
+ RSA_get0_crt_params(key.rsa, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_DMQ1:
/* exponent2 */
- bn_dup_nil(L, key.rsa->dmq1);
+ RSA_get0_crt_params(key.rsa, NULL, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_RSA_IQMP:
/* coefficient */
- bn_dup_nil(L, key.rsa->iqmp);
+ RSA_get0_crt_params(key.rsa, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DSA_P:
- bn_dup_nil(L, key.dsa->p);
+ DSA_get0_pqg(key.dsa, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DSA_Q:
- bn_dup_nil(L, key.dsa->q);
+ DSA_get0_pqg(key.dsa, NULL, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DSA_G:
- bn_dup_nil(L, key.dsa->g);
+ DSA_get0_pqg(key.dsa, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DSA_PUB_KEY:
- bn_dup_nil(L, key.dsa->pub_key);
+ DSA_get0_key(key.dsa, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DSA_PRIV_KEY:
- bn_dup_nil(L, key.dsa->priv_key);
+ DSA_get0_key(key.dsa, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DH_P:
- bn_dup_nil(L, key.dh->p);
+ DH_get0_pqg(key.dh, &i, NULL, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DH_G:
- bn_dup_nil(L, key.dh->g);
+ DH_get0_pqg(key.dh, NULL, NULL, &i);
+ bn_dup_nil(L, i);
break;
case PK_DH_PUB_KEY:
- bn_dup_nil(L, key.dh->pub_key);
+ DH_get0_key(key.dh, &i, NULL);
+ bn_dup_nil(L, i);
break;
case PK_DH_PRIV_KEY:
- bn_dup_nil(L, key.dh->priv_key);
+ DH_get0_key(key.dh, NULL, &i);
+ bn_dup_nil(L, i);
break;
#ifndef OPENSSL_NO_EC
@@ -3073,22 +3573,9 @@ static void pk_pushparam(lua_State *L, void *base_key, enum pk_param which) {
} /* pk_pushparam() */
-static _Bool pk_bn_set_nothrow(BIGNUM **dst, BIGNUM *src) {
- BIGNUM *tmp;
-
- if (!(tmp = BN_dup(src)))
- return 0;
-
- if (*dst)
- BN_clear_free(*dst);
- *dst = tmp;
-
- return 1;
-} /* pk_bn_set_nothrow() */
-
-#define pk_bn_set(L, dst, index) do { \
- BIGNUM *n = checkbig((L), (index)); \
- if (!pk_bn_set_nothrow((dst), n)) \
+#define pk_setparam_bn_dup(L, index, dst) do { \
+ BIGNUM *tmp = checkbig((L), (index)); \
+ if (!(*dst = BN_dup(tmp))) \
goto sslerr; \
} while (0)
@@ -3101,74 +3588,92 @@ static void pk_setparam(lua_State *L, void *base_key, enum pk_param which, int i
EC_KEY *ec;
#endif
} key = { base_key };
+ BIGNUM *i;
switch (which) {
case PK_RSA_N:
- pk_bn_set(L, &key.rsa->n, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_key(key.rsa, i, NULL, NULL);
break;
case PK_RSA_E:
- pk_bn_set(L, &key.rsa->e, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_key(key.rsa, NULL, i, NULL);
break;
case PK_RSA_D:
- pk_bn_set(L, &key.rsa->d, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_key(key.rsa, NULL, NULL, i);
break;
case PK_RSA_P:
- pk_bn_set(L, &key.rsa->p, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_factors(key.rsa, i, NULL);
break;
case PK_RSA_Q:
- pk_bn_set(L, &key.rsa->q, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_factors(key.rsa, NULL, i);
break;
case PK_RSA_DMP1:
- pk_bn_set(L, &key.rsa->dmp1, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_crt_params(key.rsa, i, NULL, NULL);
break;
case PK_RSA_DMQ1:
- pk_bn_set(L, &key.rsa->dmq1, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_crt_params(key.rsa, NULL, i, NULL);
break;
case PK_RSA_IQMP:
- pk_bn_set(L, &key.rsa->iqmp, index);
+ pk_setparam_bn_dup(L, index, &i);
+ RSA_set0_crt_params(key.rsa, NULL, NULL, i);
break;
case PK_DSA_P:
- pk_bn_set(L, &key.dsa->p, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_pqg(key.dsa, i, NULL, NULL);
break;
case PK_DSA_Q:
- pk_bn_set(L, &key.dsa->q, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_pqg(key.dsa, NULL, i, NULL);
break;
case PK_DSA_G:
- pk_bn_set(L, &key.dsa->g, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_pqg(key.dsa, NULL, NULL, i);
break;
case PK_DSA_PUB_KEY:
- pk_bn_set(L, &key.dsa->pub_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_key(key.dsa, i, NULL);
break;
case PK_DSA_PRIV_KEY:
- pk_bn_set(L, &key.dsa->priv_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DSA_set0_key(key.dsa, NULL, i);
break;
case PK_DH_P:
- pk_bn_set(L, &key.dh->p, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_pqg(key.dh, i, NULL, NULL);
break;
case PK_DH_G:
- pk_bn_set(L, &key.dh->g, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_pqg(key.dh, NULL, NULL, i);
break;
case PK_DH_PUB_KEY:
- pk_bn_set(L, &key.dh->pub_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_key(key.dh, i, NULL);
break;
case PK_DH_PRIV_KEY:
- pk_bn_set(L, &key.dh->priv_key, index);
+ pk_setparam_bn_dup(L, index, &i);
+ DH_set0_key(key.dh, NULL, i);
break;
#ifndef OPENSSL_NO_EC
@@ -3399,6 +3904,7 @@ static const auxL_Reg pk_methods[] = {
{ "setPrivateKey", &pk_setPrivateKey },
{ "sign", &pk_sign },
{ "verify", &pk_verify },
+ { "getDefaultDigestName", &pk_getDefaultDigestName },
{ "toPEM", &pk_toPEM },
{ "getParameters", &pk_getParameters },
{ "setParameters", &pk_setParameters },
@@ -3474,21 +3980,6 @@ static EC_GROUP *ecg_dup_nil(lua_State *L, const EC_GROUP *src) {
return (src)? ecg_dup(L, src) : (lua_pushnil(L), (EC_GROUP *)0);
} /* ecg_dup_nil() */
-static EC_GROUP *ecg_new_by_nid(int nid) {
- EC_GROUP *group;
-
- if (!(group = EC_GROUP_new_by_curve_name(nid)))
- return NULL;
-
- /* flag as named for benefit of __tostring */
- EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-
- /* compressed points may be patented */
- EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
-
- return group;
-} /* ecg_new_by_nid() */
-
static EC_GROUP *ecg_push_by_nid(lua_State *L, int nid) {
EC_GROUP **group = prepsimple(L, EC_GROUP_CLASS);
@@ -3743,7 +4234,7 @@ static int xn_all(lua_State *L) {
lua_setfield(L, -2, "id");
len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
- lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len);
+ lua_pushlstring(L, (char *)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), len);
lua_setfield(L, -2, "blob");
@@ -3777,7 +4268,7 @@ static int xn__next(lua_State *L) {
lua_pushlstring(L, txt, len);
len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
- lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len);
+ lua_pushlstring(L, (char *)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), len);
break;
}
@@ -3955,7 +4446,7 @@ text:
gen->type = type;
- if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()))
+ if (!(gen->d.ia5 = ASN1_STRING_type_new(V_ASN1_IA5STRING)))
goto error;
if (!ASN1_STRING_set(gen->d.ia5, (unsigned char *)txt, len))
@@ -3976,7 +4467,7 @@ error:
#define GN_PUSHSTRING(L, o) \
- lua_pushlstring((L), (char *)M_ASN1_STRING_data((o)), M_ASN1_STRING_length((o)))
+ lua_pushlstring((L), (char *)ASN1_STRING_get0_data((o)), ASN1_STRING_length((o)))
static int gn__next(lua_State *L) {
GENERAL_NAMES *gens = checksimple(L, lua_upvalueindex(1), X509_GENS_CLASS);
@@ -4013,8 +4504,8 @@ static int gn__next(lua_State *L) {
break;
case GEN_IPADD:
- txt = (char *)M_ASN1_STRING_data(name->d.iPAddress);
- len = M_ASN1_STRING_length(name->d.iPAddress);
+ txt = (char *)ASN1_STRING_get0_data(name->d.iPAddress);
+ len = ASN1_STRING_length(name->d.iPAddress);
switch (len) {
case 16:
@@ -4259,7 +4750,7 @@ static int xe_getLongName(lua_State *L) {
static int xe_getData(lua_State *L) {
ASN1_STRING *data = X509_EXTENSION_get0_data(checksimple(L, 1, X509_EXT_CLASS));
- lua_pushlstring(L, (char *)ASN1_STRING_data(data), ASN1_STRING_length(data));
+ lua_pushlstring(L, (char *)ASN1_STRING_get0_data(data), ASN1_STRING_length(data));
return 1;
} /* xe_getData() */
@@ -4332,6 +4823,7 @@ static const auxL_IntegerReg xe_textopts[] = {
{ "ERROR_UNKNOWN", X509V3_EXT_ERROR_UNKNOWN },
{ "PARSE_UNKNOWN", X509V3_EXT_PARSE_UNKNOWN },
{ "DUMP_UNKNOWN", X509V3_EXT_DUMP_UNKNOWN },
+ { NULL, 0 },
};
int luaopen__openssl_x509_extension(lua_State *L) {
@@ -4588,7 +5080,7 @@ static double timeutc(ASN1_TIME *time) {
if (!ASN1_TIME_check(time))
return 0;
- cp = strncpy(buf, (const char *)ASN1_STRING_data((ASN1_STRING *)time), sizeof buf - 1);
+ cp = strncpy(buf, (const char *)ASN1_STRING_get0_data((ASN1_STRING *)time), sizeof buf - 1);
if (ASN1_STRING_type(time) == V_ASN1_GENERALIZEDTIME) {
if (!scan(&year, &cp, 4, 1))
@@ -4992,7 +5484,7 @@ static int xc_setBasicConstraint(lua_State *L) {
if (pathLen >= 0) {
ASN1_INTEGER_free(bs->pathlen);
- if (!(bs->pathlen = M_ASN1_INTEGER_new()))
+ if (!(bs->pathlen = ASN1_STRING_type_new(V_ASN1_INTEGER)))
goto error;
if (!ASN1_INTEGER_set(bs->pathlen, pathLen))
@@ -5179,20 +5671,21 @@ static int xc_getPublicKeyDigest(lua_State *L) {
static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) {
const char *id;
const EVP_MD *md;
+ int nid;
- if ((id = luaL_optstring(L, index, NULL)))
- return ((md = EVP_get_digestbyname(id)))? md : EVP_md_null();
-
- switch (EVP_PKEY_type(key->type)) {
- case EVP_PKEY_RSA:
- return EVP_sha1();
- case EVP_PKEY_DSA:
- return EVP_dss1();
- case EVP_PKEY_EC:
- return EVP_ecdsa();
- default:
- return EVP_md_null();
+ if ((id = luaL_optstring(L, index, NULL))) {
+ if (!(md = EVP_get_digestbyname(id)))
+ goto unknown;
+ } else {
+ if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
+ goto unknown;
+ if (!(md = EVP_get_digestbynid(nid)))
+ goto unknown;
}
+
+ return md;
+unknown:
+ return EVP_sha1();
} /* xc_signature() */
static int xc_sign(lua_State *L) {
@@ -5491,6 +5984,103 @@ static int xr_setPublicKey(lua_State *L) {
} /* xr_setPublicKey() */
+static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) {
+ STACK_OF(X509_EXTENSION) *sk = NULL;
+ int has_attrs=0;
+
+ /*
+ * Replace existing if it's there. Extensions are stored in a CSR in
+ * an interesting way:
+ *
+ * They are stored as a list under either (most likely) the
+ * "official" NID_ext_req or under NID_ms_ext_req which means
+ * everything is stored under a list in a single "attribute" so we
+ * can't use X509_REQ_add1_attr or similar.
+ *
+ * Instead we have to get the extensions, find and replace the SAN
+ * if it's in there, then *replace* the extensions in the list of
+ * attributes. (If we just try to add it the old ones are found
+ * first and don't take priority.)
+ */
+ has_attrs = X509_REQ_get_attr_count(csr);
+
+ sk = X509_REQ_get_extensions(csr);
+ if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE))
+ goto error;
+ if (X509_REQ_add_extensions(csr, sk) == 0)
+ goto error;
+ sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
+ sk = NULL;
+
+ /*
+ * Delete the old extensions attribute, so that the one we just
+ * added takes priority.
+ */
+ if (has_attrs) {
+ X509_ATTRIBUTE *attr = NULL;
+ int idx, *pnid;
+
+ for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) {
+ idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1);
+ if (idx == -1)
+ continue;
+ if (!(attr = X509_REQ_delete_attr(csr, idx)))
+ goto error;
+ X509_ATTRIBUTE_free(attr);
+ break;
+ }
+ if (!attr)
+ goto error;
+ }
+
+ /*
+ * We have to mark the encoded form as invalid, otherwise when we
+ * write it out again it will use the loaded version.
+ */
+#if HAVE_I2D_RE_X509_REQ_TBS
+ (void)i2d_re_X509_REQ_tbs(csr, NULL); /* sets csr->req_info->enc.modified */
+#else
+ csr->req_info->enc.modified = 1;
+#endif
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+error:
+ if (sk)
+ sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
+
+ return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid");
+} /* xr_setExtensionByNid() */
+
+
+static int xr_setSubjectAlt(lua_State *L) {
+ X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
+ GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
+
+ return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens);
+} /* xr_setSubjectAlt */
+
+
+static int xr_getSubjectAlt(lua_State *L) {
+ X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
+ STACK_OF(X509_EXTENSION) *exts;
+ GENERAL_NAMES *gens;
+
+ exts = X509_REQ_get_extensions(csr);
+ gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ if (!gens) goto error;
+
+ gn_dup(L, gens);
+
+ return 1;
+error:
+ return 0;
+} /* xr_getSubjectAlt() */
+
+
+
static int xr_sign(lua_State *L) {
X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
@@ -5548,6 +6138,8 @@ static const auxL_Reg xr_methods[] = {
{ "setSubject", &xr_setSubject },
{ "getPublicKey", &xr_getPublicKey },
{ "setPublicKey", &xr_setPublicKey },
+ { "getSubjectAlt", &xr_getSubjectAlt },
+ { "setSubjectAlt", &xr_setSubjectAlt },
{ "sign", &xr_sign },
{ "tostring", &xr__tostring },
{ NULL, NULL },
@@ -6010,7 +6602,7 @@ static void xl_dup(lua_State *L, STACK_OF(X509) *src, _Bool copy) {
for (i = 0; i < n; i++) {
if (!(crt = sk_X509_value(*dst, i)))
continue;
- CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(crt);
}
}
@@ -6195,8 +6787,8 @@ static int xs_verify(lua_State *L) {
X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
X509 *crt = checksimple(L, 2, X509_CERT_CLASS);
STACK_OF(X509) *chain = NULL, **proof;
- X509_STORE_CTX ctx;
- int ok, why;
+ X509_STORE_CTX *ctx = NULL;
+ int nr = 0, ok, why;
/* pre-allocate space for a successful return */
lua_settop(L, 3);
@@ -6207,53 +6799,56 @@ static int xs_verify(lua_State *L) {
int i, n;
if (!(chain = sk_X509_dup(checksimple(L, 3, X509_CHAIN_CLASS))))
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ goto eossl;
n = sk_X509_num(chain);
for (i = 0; i < n; i++) {
if (!(elm = sk_X509_value(chain, i)))
continue;
- CRYPTO_add(&elm->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(elm);
}
}
- if (!X509_STORE_CTX_init(&ctx, store, crt, chain)) {
+ if (!(ctx = X509_STORE_CTX_new()) || !X509_STORE_CTX_init(ctx, store, crt, chain)) {
sk_X509_pop_free(chain, X509_free);
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ goto eossl;
}
ERR_clear_error();
- ok = X509_verify_cert(&ctx);
+ ok = X509_verify_cert(ctx);
switch (ok) {
case 1: /* verified */
- *proof = X509_STORE_CTX_get1_chain(&ctx);
-
- X509_STORE_CTX_cleanup(&ctx);
-
- if (!*proof)
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ if (!(*proof = X509_STORE_CTX_get1_chain(ctx)))
+ goto eossl;
lua_pushboolean(L, 1);
lua_pushvalue(L, -2);
+ nr = 2;
- return 2;
+ break;
case 0: /* not verified */
- why = X509_STORE_CTX_get_error(&ctx);
-
- X509_STORE_CTX_cleanup(&ctx);
+ why = X509_STORE_CTX_get_error(ctx);
lua_pushboolean(L, 0);
lua_pushstring(L, X509_verify_cert_error_string(why));
+ nr = 2;
- return 2;
+ break;
default:
- X509_STORE_CTX_cleanup(&ctx);
-
- return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
+ goto eossl;
}
+
+ X509_STORE_CTX_free(ctx);
+
+ return nr;
+eossl:
+ if (ctx)
+ X509_STORE_CTX_free(ctx);
+
+ return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
} /* xs_verify() */
@@ -6529,7 +7124,7 @@ static int sx_new(lua_State *L) {
method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
break;
-#ifndef OPENSSL_NO_SSL2
+#if HAVE_SSLV2_CLIENT_METHOD && HAVE_SSLV2_SERVER_METHOD
case 2: /* SSLv2 */
method = (srv)? &SSLv2_server_method : &SSLv2_client_method;
break;
@@ -7001,7 +7596,7 @@ int luaopen__openssl_ssl_context(lua_State *L) {
static SSL *ssl_push(lua_State *L, SSL *ssl) {
SSL **ud = prepsimple(L, SSL_CLASS);
- CRYPTO_add(&(ssl)->references, 1, CRYPTO_LOCK_SSL);
+ SSL_up_ref(ssl);
*ud = ssl;
return *ud;
@@ -7152,7 +7747,7 @@ static int ssl_getVersion(lua_State *L) {
static int ssl_getClientVersion(lua_State *L) {
SSL *ssl = checksimple(L, 1, SSL_CLASS);
int format = luaL_checkoption(L, 2, "d", (const char *[]){ "d", ".", "f", NULL });
- int version = ssl->client_version;
+ int version = SSL_client_version(ssl);
int major, minor;
switch (format) {
@@ -7306,13 +7901,10 @@ static const EVP_MD *md_optdigest(lua_State *L, int index) {
static int md_new(lua_State *L) {
const EVP_MD *type = md_optdigest(L, 1);
- EVP_MD_CTX *ctx;
-
- ctx = prepudata(L, sizeof *ctx, DIGEST_CLASS, NULL);
-
- EVP_MD_CTX_init(ctx);
+ EVP_MD_CTX **ctx;
- if (!EVP_DigestInit_ex(ctx, type, NULL))
+ ctx = prepsimple(L, DIGEST_CLASS, NULL);
+ if (!(*ctx = EVP_MD_CTX_new()) || !EVP_DigestInit_ex(*ctx, type, NULL))
return auxL_error(L, auxL_EOPENSSL, "digest.new");
return 1;
@@ -7340,7 +7932,7 @@ 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);
+ EVP_MD_CTX *ctx = checksimple(L, 1, DIGEST_CLASS);
md_update_(L, ctx, 2, lua_gettop(L));
@@ -7351,7 +7943,7 @@ static int md_update(lua_State *L) {
static int md_final(lua_State *L) {
- EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
+ EVP_MD_CTX *ctx = checksimple(L, 1, DIGEST_CLASS);
unsigned char md[EVP_MAX_MD_SIZE];
unsigned len;
@@ -7367,9 +7959,10 @@ static int md_final(lua_State *L) {
static int md__gc(lua_State *L) {
- EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
+ EVP_MD_CTX **ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
- EVP_MD_CTX_cleanup(ctx);
+ EVP_MD_CTX_free(*ctx);
+ *ctx = NULL;
return 0;
} /* md__gc() */
@@ -7410,16 +8003,25 @@ static int hmac_new(lua_State *L) {
const void *key;
size_t len;
const EVP_MD *type;
- HMAC_CTX *ctx;
+ HMAC_CTX **ctx;
key = luaL_checklstring(L, 1, &len);
type = md_optdigest(L, 2);
- ctx = prepudata(L, sizeof *ctx, HMAC_CLASS, NULL);
+ ctx = prepsimple(L, HMAC_CLASS, NULL);
+ if (!(*ctx = HMAC_CTX_new()))
+ goto eossl;
- HMAC_Init_ex(ctx, key, len, type, NULL);
+#if HMAC_INIT_EX_INT
+ if (!HMAC_Init_ex(*ctx, key, len, type, NULL))
+ goto eossl;
+#else
+ HMAC_Init_ex(*ctx, key, len, type, NULL);
+#endif
return 1;
+eossl:
+ return auxL_error(L, auxL_EOPENSSL, "hmac.new");
} /* hmac_new() */
@@ -7443,7 +8045,7 @@ static void hmac_update_(lua_State *L, HMAC_CTX *ctx, int from, int to) {
static int hmac_update(lua_State *L) {
- HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS);
+ HMAC_CTX *ctx = checksimple(L, 1, HMAC_CLASS);
hmac_update_(L, ctx, 2, lua_gettop(L));
@@ -7454,7 +8056,7 @@ static int hmac_update(lua_State *L) {
static int hmac_final(lua_State *L) {
- HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS);
+ HMAC_CTX *ctx = checksimple(L, 1, HMAC_CLASS);
unsigned char hmac[EVP_MAX_MD_SIZE];
unsigned len;
@@ -7469,9 +8071,10 @@ static int hmac_final(lua_State *L) {
static int hmac__gc(lua_State *L) {
- HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS);
+ HMAC_CTX **ctx = luaL_checkudata(L, 1, HMAC_CLASS);
- HMAC_CTX_cleanup(ctx);
+ HMAC_CTX_free(*ctx);
+ *ctx = NULL;
return 0;
} /* hmac__gc() */
@@ -7521,23 +8124,26 @@ static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) {
static int cipher_new(lua_State *L) {
const EVP_CIPHER *type;
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX **ctx;
unsigned char key[EVP_MAX_KEY_LENGTH] = { 0 };
type = cipher_checktype(L, 1);
- ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL);
- EVP_CIPHER_CTX_init(ctx);
+ ctx = prepsimple(L, CIPHER_CLASS, NULL);
+ if (!(*ctx = EVP_CIPHER_CTX_new()))
+ goto eossl;
/*
* NOTE: For some ciphers like AES calling :update or :final without
* setting a key causes a SEGV. Set a dummy key here. Same solution
* as used by Ruby OSSL.
*/
- if (!EVP_CipherInit_ex(ctx, type, NULL, key, NULL, -1))
- return auxL_error(L, auxL_EOPENSSL, "cipher.new");
+ if (!EVP_CipherInit_ex(*ctx, type, NULL, key, NULL, -1))
+ goto eossl;
return 1;
+eossl:
+ return auxL_error(L, auxL_EOPENSSL, "cipher.new");
} /* cipher_new() */
@@ -7547,7 +8153,7 @@ static int cipher_interpose(lua_State *L) {
static int cipher_init(lua_State *L, _Bool encrypt) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
const void *key, *iv;
size_t n, m;
@@ -7619,7 +8225,7 @@ static _Bool cipher_update_(lua_State *L, EVP_CIPHER_CTX *ctx, luaL_Buffer *B, i
static int cipher_update(lua_State *L) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
luaL_buffinit(L, &B);
@@ -7639,7 +8245,7 @@ sslerr:
static int cipher_final(lua_State *L) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
luaL_Buffer B;
size_t block;
int out;
@@ -7670,9 +8276,10 @@ sslerr:
static int cipher__gc(lua_State *L) {
- EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
+ EVP_CIPHER_CTX **ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
- EVP_CIPHER_CTX_cleanup(ctx);
+ EVP_CIPHER_CTX_free(*ctx);
+ *ctx = NULL;
return 0;
} /* cipher__gc() */
@@ -7719,49 +8326,61 @@ static struct randL_state *randL_getstate(lua_State *L) {
return lua_touserdata(L, lua_upvalueindex(1));
} /* randL_getstate() */
-#ifndef HAVE_SYS_SYSCTL_H
-#define HAVE_SYS_SYSCTL_H (!defined __sun && !defined _AIX)
+#if HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h> /* SYS_getrandom syscall(2) */
#endif
#if HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h> /* CTL_KERN KERN_RANDOM RANDOM_UUID KERN_URND KERN_ARND sysctl(2) */
-#endif
-
-#ifndef HAVE_RANDOM_UUID
-#define HAVE_RANDOM_UUID (defined __linux) /* RANDOM_UUID is an enum, not macro */
-#endif
-
-#ifndef HAVE_KERN_URND
-#define HAVE_KERN_URND (defined KERN_URND)
-#endif
-
-#ifndef HAVE_KERN_ARND
-#define HAVE_KERN_ARND (defined KERN_ARND)
+#include <sys/sysctl.h> /* CTL_KERN KERN_RANDOM RANDOM_UUID sysctl(2) */
#endif
static int randL_stir(struct randL_state *st, unsigned rqstd) {
unsigned count = 0;
int error;
unsigned char data[256];
-#if HAVE_RANDOM_UUID || HAVE_KERN_URND || HAVE_KERN_ARND
-#if HAVE_RANDOM_UUID
- int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
-#elif HAVE_KERN_URND
- int mib[] = { CTL_KERN, KERN_URND };
-#else
- int mib[] = { CTL_KERN, KERN_ARND };
+
+#if HAVE_ARC4RANDOM_BUF
+ while (count < rqstd) {
+ size_t n = MIN(rqstd - count, sizeof data);
+
+ arc4random_buf(data, n);
+
+ RAND_seed(data, n);
+
+ count += n;
+ }
+#endif
+
+#if HAVE_SYSCALL && HAVE_DECL_SYS_GETRANDOM
+ while (count < rqstd) {
+ size_t lim = MIN(rqstd - count, sizeof data);
+ int n;
+
+ n = syscall(SYS_getrandom, data, lim, 0);
+
+ if (n == -1) {
+ break;
+ }
+
+ RAND_seed(data, n);
+
+ count += n;
+ }
#endif
+#if HAVE_SYS_SYSCTL_H && HAVE_DECL_RANDOM_UUID
while (count < rqstd) {
+ int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
size_t n = MIN(rqstd - count, sizeof data);
if (0 != sysctl(mib, countof(mib), data, &n, (void *)0, 0))
break;
- RAND_add(data, n, n);
+ RAND_seed(data, n);
count += n;
}
+
#endif
if (count < rqstd) {
@@ -7792,7 +8411,7 @@ static int randL_stir(struct randL_state *st, unsigned rqstd) {
goto error;
default:
- RAND_add(data, n, n);
+ RAND_seed(data, n);
count += n;
}
@@ -7830,7 +8449,12 @@ error:;
#elif defined __sun
/*
* NOTE: Linux requires -lrt for clock_gettime, and in any event
- * already has RANDOM_UUID. The BSDs have KERN_URND and KERN_ARND.
+ * should have RANDOM_UUID or getrandom. (Though, some middle-aged
+ * kernels might have neither). The BSDs have arc4random which
+ * should be using KERN_URND, KERN_ARND, and more recently
+ * getentropy. (Though, again, some older BSD kernels used an
+ * arc4random implementation that opened /dev/urandom.)
+ *
* Just do this for Solaris to keep things simple. We've already
* crossed the line of what can be reasonably accomplished on
* unreasonable platforms.