diff options
Diffstat (limited to 'server/resty/openssl/include')
34 files changed, 2388 insertions, 0 deletions
diff --git a/server/resty/openssl/include/asn1.lua b/server/resty/openssl/include/asn1.lua new file mode 100644 index 0000000..ba59ebc --- /dev/null +++ b/server/resty/openssl/include/asn1.lua @@ -0,0 +1,94 @@ +local ffi = require "ffi" +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X + +ffi.cdef [[ + typedef struct ASN1_VALUE_st ASN1_VALUE; + + typedef struct asn1_type_st ASN1_TYPE; + + ASN1_IA5STRING *ASN1_IA5STRING_new(); + + int ASN1_STRING_type(const ASN1_STRING *x); + ASN1_STRING *ASN1_STRING_type_new(int type); + int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); + + ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); + BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + + typedef int time_t; + ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); + + int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); + long ASN1_INTEGER_get(const ASN1_INTEGER *a); + int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); + + int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); + + int ASN1_STRING_length(const ASN1_STRING *x); +]] + +local function declare_asn1_functions(typ, has_ex) + local t = {} + for i=1, 7 do + t[i] = typ + end + + ffi.cdef(string.format([[ + %s *%s_new(void); + void %s_free(%s *a); + %s *%s_dup(%s *a); + ]], unpack(t))) + + if OPENSSL_3X and has_ex then + ffi.cdef(string.format([[ + %s *%s_new_ex(OSSL_LIB_CTX *libctx, const char *propq); + ]], typ, typ)) + end +end + +declare_asn1_functions("ASN1_INTEGER") +declare_asn1_functions("ASN1_OBJECT") +declare_asn1_functions("ASN1_STRING") +declare_asn1_functions("ASN1_ENUMERATED") + +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110 + +local ASN1_STRING_get0_data +if OPENSSL_11_OR_LATER then + ffi.cdef[[ + const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + ]] + ASN1_STRING_get0_data = C.ASN1_STRING_get0_data +elseif OPENSSL_10 then + ffi.cdef[[ + unsigned char *ASN1_STRING_data(ASN1_STRING *x); + typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ + } ASN1_ENCODING; + ]] + ASN1_STRING_get0_data = C.ASN1_STRING_data +end + +if BORINGSSL_110 then + ffi.cdef [[ + // required by resty/openssl/include/x509/crl.lua + typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ + } ASN1_ENCODING; + ]] +end + +return { + ASN1_STRING_get0_data = ASN1_STRING_get0_data, + declare_asn1_functions = declare_asn1_functions, + has_new_ex = true, +} diff --git a/server/resty/openssl/include/bio.lua b/server/resty/openssl/include/bio.lua new file mode 100644 index 0000000..45297fc --- /dev/null +++ b/server/resty/openssl/include/bio.lua @@ -0,0 +1,13 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" + +ffi.cdef [[ + typedef struct bio_method_st BIO_METHOD; + long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); + BIO *BIO_new_mem_buf(const void *buf, int len); + BIO *BIO_new(const BIO_METHOD *type); + int BIO_free(BIO *a); + const BIO_METHOD *BIO_s_mem(void); + int BIO_read(BIO *b, void *data, int dlen); +]] diff --git a/server/resty/openssl/include/bn.lua b/server/resty/openssl/include/bn.lua new file mode 100644 index 0000000..93d2dda --- /dev/null +++ b/server/resty/openssl/include/bn.lua @@ -0,0 +1,77 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X + +local BN_ULONG +if ffi.abi('64bit') then + BN_ULONG = 'unsigned long long' +else -- 32bit + BN_ULONG = 'unsigned int' +end + +ffi.cdef( +[[ + BIGNUM *BN_new(void); + void BN_free(BIGNUM *a); + + BN_CTX *BN_CTX_new(void); + void BN_CTX_init(BN_CTX *c); + void BN_CTX_free(BN_CTX *c); + + BIGNUM *BN_dup(const BIGNUM *a); + int BN_add_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w); + int BN_set_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w); + ]] .. BN_ULONG ..[[ BN_get_word(BIGNUM *a); + int BN_num_bits(const BIGNUM *a); + BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); + int BN_hex2bn(BIGNUM **a, const char *str); + int BN_dec2bn(BIGNUM **a, const char *str); + int BN_bn2bin(const BIGNUM *a, unsigned char *to); + char *BN_bn2hex(const BIGNUM *a); + char *BN_bn2dec(const BIGNUM *a); + + void BN_set_negative(BIGNUM *a, int n); + int BN_is_negative(const BIGNUM *a); + + int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx); + int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d, + BN_CTX *ctx); + int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); + int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); + int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); + int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); + int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx); + int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + + int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); + int BN_rshift(BIGNUM *r, BIGNUM *a, int n); + + int BN_cmp(BIGNUM *a, BIGNUM *b); + int BN_ucmp(BIGNUM *a, BIGNUM *b); + + // openssl >= 1.1 only + int BN_is_zero(BIGNUM *a); + int BN_is_one(BIGNUM *a); + int BN_is_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w); + int BN_is_odd(BIGNUM *a); + + int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb); + int BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +]] +) + +if OPENSSL_3X then + ffi.cdef [[ + int BN_check_prime(const BIGNUM *p, BN_CTX *ctx, BN_GENCB *cb); + ]] +end
\ No newline at end of file diff --git a/server/resty/openssl/include/conf.lua b/server/resty/openssl/include/conf.lua new file mode 100644 index 0000000..d655993 --- /dev/null +++ b/server/resty/openssl/include/conf.lua @@ -0,0 +1,9 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" + +ffi.cdef [[ + CONF *NCONF_new(CONF_METHOD *meth); + void NCONF_free(CONF *conf); + int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +]]
\ No newline at end of file diff --git a/server/resty/openssl/include/crypto.lua b/server/resty/openssl/include/crypto.lua new file mode 100644 index 0000000..6ca1f08 --- /dev/null +++ b/server/resty/openssl/include/crypto.lua @@ -0,0 +1,31 @@ +local ffi = require "ffi" +local C = ffi.C + +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER + +local OPENSSL_free +if OPENSSL_10 then + ffi.cdef [[ + void CRYPTO_free(void *ptr); + ]] + OPENSSL_free = C.CRYPTO_free +elseif OPENSSL_11_OR_LATER then + ffi.cdef [[ + void CRYPTO_free(void *ptr, const char *file, int line); + ]] + OPENSSL_free = function(ptr) + -- file and line is for debuggin only, since we can't know the c file info + -- the macro is expanded, just ignore this + C.CRYPTO_free(ptr, "", 0) + end +end + +ffi.cdef [[ + int FIPS_mode(void); + int FIPS_mode_set(int ONOFF); +]] + +return { + OPENSSL_free = OPENSSL_free, +} diff --git a/server/resty/openssl/include/dh.lua b/server/resty/openssl/include/dh.lua new file mode 100644 index 0000000..504879d --- /dev/null +++ b/server/resty/openssl/include/dh.lua @@ -0,0 +1,80 @@ +local ffi = require "ffi" +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.objects" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); + int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); + void DH_get0_key(const DH *dh, + const BIGNUM **pub_key, const BIGNUM **priv_key); + int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); + ]] +elseif OPENSSL_10 then + ffi.cdef [[ + struct dh_st { + /* + * This first argument is used to pick up errors when a DH is passed + * instead of a EVP_PKEY + */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x */ + BIGNUM *priv_key; /* x */ + int flags; + /*BN_MONT_CTX*/ void *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + int references; + /* trimmer */ + // CRYPTO_EX_DATA ex_data; + // const DH_METHOD *meth; + // ENGINE *engine; + }; + ]] +end + +ffi.cdef [[ + DH *DH_get_1024_160(void); + DH *DH_get_2048_224(void); + DH *DH_get_2048_256(void); + DH *DH_new_by_nid(int nid); +]]; + + +local dh_groups = { + -- per https://tools.ietf.org/html/rfc5114 + dh_1024_160 = function() return C.DH_get_1024_160() end, + dh_2048_224 = function() return C.DH_get_2048_224() end, + dh_2048_256 = function() return C.DH_get_2048_256() end, +} + +local groups = { + "ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", "ffdhe8192", + "modp_2048", "modp_3072", "modp_4096", "modp_6144", "modp_8192", + -- following cannot be used with FIPS provider + "modp_1536", -- and the RFC5114 ones +} + +for _, group in ipairs(groups) do + local nid = C.OBJ_sn2nid(group) + if nid ~= 0 then + dh_groups[group] = function() return C.DH_new_by_nid(nid) end + end +end + +return { + dh_groups = dh_groups, +} diff --git a/server/resty/openssl/include/ec.lua b/server/resty/openssl/include/ec.lua new file mode 100644 index 0000000..674ef42 --- /dev/null +++ b/server/resty/openssl/include/ec.lua @@ -0,0 +1,59 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" + +ffi.cdef [[ + /** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ + typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 + } point_conversion_form_t; + + EC_KEY *EC_KEY_new(void); + void EC_KEY_free(EC_KEY *key); + + EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); + void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); + void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + int EC_GROUP_get_curve_name(const EC_GROUP *group); + + + void EC_GROUP_free(EC_GROUP *group); + + BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); + // for BoringSSL + size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + // OpenSSL < 1.1.1 + int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + // OpenSSL >= 1.1.1 + int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, const BIGNUM *bn, + EC_POINT *p, BN_CTX *ctx); + + point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); + + const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + + const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y); + + const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); +]] diff --git a/server/resty/openssl/include/err.lua b/server/resty/openssl/include/err.lua new file mode 100644 index 0000000..142098c --- /dev/null +++ b/server/resty/openssl/include/err.lua @@ -0,0 +1,9 @@ +local ffi = require "ffi" + +ffi.cdef [[ + unsigned long ERR_peek_error(void); + unsigned long ERR_peek_last_error_line(const char **file, int *line); + unsigned long ERR_get_error_line(const char **file, int *line); + void ERR_clear_error(void); + void ERR_error_string_n(unsigned long e, char *buf, size_t len); +]] diff --git a/server/resty/openssl/include/evp.lua b/server/resty/openssl/include/evp.lua new file mode 100644 index 0000000..beeaf91 --- /dev/null +++ b/server/resty/openssl/include/evp.lua @@ -0,0 +1,109 @@ +local ffi = require "ffi" +local C = ffi.C +local bit = require("bit") + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.err" +require "resty.openssl.include.objects" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +if BORINGSSL then + ffi.cdef [[ + int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, const EVP_MD *digest, + size_t key_len, uint8_t *out_key); + int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + uint64_t N, uint64_t r, uint64_t p, + size_t max_mem, uint8_t *out_key, + size_t key_len); + ]] +else + ffi.cdef [[ + /* KDF */ + int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); + + int EVP_PBE_scrypt(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen); + ]] +end + +if OPENSSL_3X then + require "resty.openssl.include.provider" + + ffi.cdef [[ + int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq); + int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable); + int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX *libctx); + + // const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand); + // EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + // const char *properties); + ]] +end + +local EVP_PKEY_ALG_CTRL = 0x1000 + +local _M = { + EVP_PKEY_RSA = C.OBJ_txt2nid("rsaEncryption"), + EVP_PKEY_DH = C.OBJ_txt2nid("dhKeyAgreement"), + EVP_PKEY_EC = C.OBJ_txt2nid("id-ecPublicKey"), + EVP_PKEY_X25519 = C.OBJ_txt2nid("X25519"), + EVP_PKEY_ED25519 = C.OBJ_txt2nid("ED25519"), + EVP_PKEY_X448 = C.OBJ_txt2nid("X448"), + EVP_PKEY_ED448 = C.OBJ_txt2nid("ED448"), + + EVP_PKEY_OP_PARAMGEN = bit.lshift(1, 1), + EVP_PKEY_OP_KEYGEN = bit.lshift(1, 2), + EVP_PKEY_OP_SIGN = bit.lshift(1, 3), + EVP_PKEY_OP_VERIFY = bit.lshift(1, 4), + EVP_PKEY_OP_DERIVE = OPENSSL_3X and bit.lshift(1, 12) or bit.lshift(1, 10), + + EVP_PKEY_ALG_CTRL = EVP_PKEY_ALG_CTRL, + + + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN = EVP_PKEY_ALG_CTRL + 1, + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = EVP_PKEY_ALG_CTRL + 1, + EVP_PKEY_CTRL_EC_PARAM_ENC = EVP_PKEY_ALG_CTRL + 2, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS = EVP_PKEY_ALG_CTRL + 3, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP = EVP_PKEY_ALG_CTRL + 4, + EVP_PKEY_CTRL_RSA_PADDING = EVP_PKEY_ALG_CTRL + 1, + EVP_PKEY_CTRL_RSA_PSS_SALTLEN = EVP_PKEY_ALG_CTRL + 2, + + EVP_CTRL_AEAD_SET_IVLEN = 0x9, + EVP_CTRL_AEAD_GET_TAG = 0x10, + EVP_CTRL_AEAD_SET_TAG = 0x11, + + EVP_PKEY_CTRL_TLS_MD = EVP_PKEY_ALG_CTRL, + EVP_PKEY_CTRL_TLS_SECRET = EVP_PKEY_ALG_CTRL + 1, + EVP_PKEY_CTRL_TLS_SEED = EVP_PKEY_ALG_CTRL + 2, + EVP_PKEY_CTRL_HKDF_MD = EVP_PKEY_ALG_CTRL + 3, + EVP_PKEY_CTRL_HKDF_SALT = EVP_PKEY_ALG_CTRL + 4, + EVP_PKEY_CTRL_HKDF_KEY = EVP_PKEY_ALG_CTRL + 5, + EVP_PKEY_CTRL_HKDF_INFO = EVP_PKEY_ALG_CTRL + 6, + EVP_PKEY_CTRL_HKDF_MODE = EVP_PKEY_ALG_CTRL + 7, + EVP_PKEY_CTRL_PASS = EVP_PKEY_ALG_CTRL + 8, + EVP_PKEY_CTRL_SCRYPT_SALT = EVP_PKEY_ALG_CTRL + 9, + EVP_PKEY_CTRL_SCRYPT_N = EVP_PKEY_ALG_CTRL + 10, + EVP_PKEY_CTRL_SCRYPT_R = EVP_PKEY_ALG_CTRL + 11, + EVP_PKEY_CTRL_SCRYPT_P = EVP_PKEY_ALG_CTRL + 12, + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES = EVP_PKEY_ALG_CTRL + 13, +} + +-- clean up error occurs during OBJ_txt2* +C.ERR_clear_error() + +_M.ecx_curves = { + Ed25519 = _M.EVP_PKEY_ED25519, + X25519 = _M.EVP_PKEY_X25519, + Ed448 = _M.EVP_PKEY_ED448, + X448 = _M.EVP_PKEY_X448, +} + +return _M diff --git a/server/resty/openssl/include/evp/cipher.lua b/server/resty/openssl/include/evp/cipher.lua new file mode 100644 index 0000000..c803766 --- /dev/null +++ b/server/resty/openssl/include/evp/cipher.lua @@ -0,0 +1,123 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +ffi.cdef [[ + // openssl < 3.0 + int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); + + const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); + const EVP_CIPHER *EVP_get_cipherbyname(const char *name); + int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); + int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); + int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); + + + int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv, int enc); + int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); + int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + + // list functions + typedef void* fake_openssl_cipher_list_fn(const EVP_CIPHER *ciph, const char *from, + const char *to, void *x); + //void EVP_CIPHER_do_all_sorted(fake_openssl_cipher_list_fn*, void *arg); + void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +]] + +if BORINGSSL then + ffi.cdef [[ + int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, + size_t data_len, unsigned count, uint8_t *key, + uint8_t *iv); + ]] +else + ffi.cdef [[ + int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, + const unsigned char *data, int datal, int count, + unsigned char *key, unsigned char *iv); + ]] +end + +if OPENSSL_3X then + require "resty.openssl.include.provider" + + ffi.cdef [[ + int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_get_key_length(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx); + + int EVP_CIPHER_get_nid(const EVP_CIPHER *cipher); + + const OSSL_PROVIDER *EVP_CIPHER_get0_provider(const EVP_CIPHER *cipher); + EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties); + + typedef void* fake_openssl_cipher_provided_list_fn(EVP_CIPHER *cipher, void *arg); + void EVP_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, + fake_openssl_cipher_provided_list_fn*, + void *arg); + int EVP_CIPHER_up_ref(EVP_CIPHER *cipher); + void EVP_CIPHER_free(EVP_CIPHER *cipher); + + const char *EVP_CIPHER_get0_name(const EVP_CIPHER *cipher); + + int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]); + const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(EVP_CIPHER_CTX *ctx); + ]] +end + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); + int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); + void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c); + ]] +elseif OPENSSL_10 then + ffi.cdef [[ + void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); + int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); + + // # define EVP_MAX_IV_LENGTH 16 + // # define EVP_MAX_BLOCK_LENGTH 32 + + struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is + * ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + unsigned char oiv[16]; /* original iv EVP_MAX_IV_LENGTH */ + unsigned char iv[16]; /* working iv EVP_MAX_IV_LENGTH */ + unsigned char buf[32]; /* saved partial block EVP_MAX_BLOCK_LENGTH */ + int num; /* used by cfb/ofb/ctr mode */ + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[32]; /* possible final block EVP_MAX_BLOCK_LENGTH */ + } /* EVP_CIPHER_CTX */ ; + ]] +end
\ No newline at end of file diff --git a/server/resty/openssl/include/evp/kdf.lua b/server/resty/openssl/include/evp/kdf.lua new file mode 100644 index 0000000..1fd408f --- /dev/null +++ b/server/resty/openssl/include/evp/kdf.lua @@ -0,0 +1,148 @@ +local ffi = require "ffi" +local ffi_cast = ffi.cast +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.evp.md" +local evp = require("resty.openssl.include.evp") +local ctypes = require "resty.openssl.auxiliary.ctypes" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +local void_ptr = ctypes.void_ptr + +local _M = { + EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND = 0, + EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY = 1, + EVP_PKEY_HKDEF_MODE_EXPAND_ONLY = 2, +} + +if OPENSSL_3X then + require "resty.openssl.include.provider" + + ffi.cdef [[ + const OSSL_PROVIDER *EVP_KDF_get0_provider(const EVP_KDF *kdf); + + typedef void* fake_openssl_kdf_provided_list_fn(EVP_KDF *kdf, void *arg); + void EVP_KDF_do_all_provided(OSSL_LIB_CTX *libctx, + fake_openssl_kdf_provided_list_fn*, + void *arg); + int EVP_KDF_up_ref(EVP_KDF *kdf); + void EVP_KDF_free(EVP_KDF *kdf); + + const char *EVP_KDF_get0_name(const EVP_KDF *kdf); + + EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties); + EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf); + void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); + void EVP_KDF_CTX_reset(EVP_KDF_CTX *ctx); + + size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx); + int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]); + + int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); + int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF_CTX *ctx); + const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF_CTX *ctx); + ]] +end + +if OPENSSL_3X or BORINGSSL then + ffi.cdef [[ + int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); + int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *pctx, + const unsigned char *sec, int seclen); + int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *pctx, + const unsigned char *seed, int seedlen); + + int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); + int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen); + int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const unsigned char *key, int keylen); + int EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX *ctx, int mode); + int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const unsigned char *info, int infolen); + ]] + + _M.EVP_PKEY_CTX_set_tls1_prf_md = function(pctx, md) + return C.EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) + end + _M.EVP_PKEY_CTX_set1_tls1_prf_secret = function(pctx, sec) + return C.EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, #sec) + end + _M.EVP_PKEY_CTX_add1_tls1_prf_seed = function(pctx, seed) + return C.EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, #seed) + end + + _M.EVP_PKEY_CTX_set_hkdf_md = function(pctx, md) + return C.EVP_PKEY_CTX_set_hkdf_md(pctx, md) + end + _M.EVP_PKEY_CTX_set1_hkdf_salt = function(pctx, salt) + return C.EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, #salt) + end + _M.EVP_PKEY_CTX_set1_hkdf_key = function(pctx, key) + return C.EVP_PKEY_CTX_set1_hkdf_key(pctx, key, #key) + end + _M.EVP_PKEY_CTX_set_hkdf_mode = function(pctx, mode) + return C.EVP_PKEY_CTX_set_hkdf_mode(pctx, mode) + end + _M.EVP_PKEY_CTX_add1_hkdf_info = function(pctx, info) + return C.EVP_PKEY_CTX_add1_hkdf_info(pctx, info, #info) + end + +else + _M.EVP_PKEY_CTX_set_tls1_prf_md = function(pctx, md) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_TLS_MD, + 0, ffi_cast(void_ptr, md)) + end + _M.EVP_PKEY_CTX_set1_tls1_prf_secret = function(pctx, sec) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_TLS_SECRET, + #sec, ffi_cast(void_ptr, sec)) + end + _M.EVP_PKEY_CTX_add1_tls1_prf_seed = function(pctx, seed) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_TLS_SEED, + #seed, ffi_cast(void_ptr, seed)) + end + + _M.EVP_PKEY_CTX_set_hkdf_md = function(pctx, md) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_HKDF_MD, + 0, ffi_cast(void_ptr, md)) + end + _M.EVP_PKEY_CTX_set1_hkdf_salt = function(pctx, salt) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_HKDF_SALT, + #salt, ffi_cast(void_ptr, salt)) + end + _M.EVP_PKEY_CTX_set1_hkdf_key = function(pctx, key) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_HKDF_KEY, + #key, ffi_cast(void_ptr, key)) + end + _M.EVP_PKEY_CTX_set_hkdf_mode = function(pctx, mode) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_HKDF_MODE, + mode, nil) + end + _M.EVP_PKEY_CTX_add1_hkdf_info = function(pctx, info) + return C.EVP_PKEY_CTX_ctrl(pctx, -1, + evp.EVP_PKEY_OP_DERIVE, + evp.EVP_PKEY_CTRL_HKDF_INFO, + #info, ffi_cast(void_ptr, info)) + end +end + +return _M
\ No newline at end of file diff --git a/server/resty/openssl/include/evp/mac.lua b/server/resty/openssl/include/evp/mac.lua new file mode 100644 index 0000000..a831076 --- /dev/null +++ b/server/resty/openssl/include/evp/mac.lua @@ -0,0 +1,38 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.provider" + +ffi.cdef [[ + typedef struct evp_mac_st EVP_MAC; + typedef struct evp_mac_ctx_st EVP_MAC_CTX; + + EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac); + void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx); + + const OSSL_PROVIDER *EVP_MAC_get0_provider(const EVP_MAC *mac); + EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties); + + int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen, + const OSSL_PARAM params[]); + int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen); + int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize); + + size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx); + + typedef void* fake_openssl_mac_provided_list_fn(EVP_MAC *mac, void *arg); + void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx, + fake_openssl_mac_provided_list_fn*, + void *arg); + int EVP_MAC_up_ref(EVP_MAC *mac); + void EVP_MAC_free(EVP_MAC *mac); + + const char *EVP_MAC_get0_name(const EVP_MAC *mac); + + int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *EVP_MAC_CTX_settable_params(EVP_MAC_CTX *ctx); + int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); + const OSSL_PARAM *EVP_MAC_CTX_gettable_params(EVP_MAC_CTX *ctx); +]]
\ No newline at end of file diff --git a/server/resty/openssl/include/evp/md.lua b/server/resty/openssl/include/evp/md.lua new file mode 100644 index 0000000..1794ce1 --- /dev/null +++ b/server/resty/openssl/include/evp/md.lua @@ -0,0 +1,86 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X + +ffi.cdef [[ + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, + size_t cnt); + int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); + const EVP_MD *EVP_get_digestbyname(const char *name); + int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, + size_t cnt); + int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); + + const EVP_MD *EVP_md_null(void); + // openssl < 3.0 + int EVP_MD_size(const EVP_MD *md); + int EVP_MD_type(const EVP_MD *md); + + typedef void* fake_openssl_md_list_fn(const EVP_MD *ciph, const char *from, + const char *to, void *x); + void EVP_MD_do_all_sorted(fake_openssl_md_list_fn*, void *arg); + + const EVP_MD *EVP_get_digestbyname(const char *name); +]] + +if OPENSSL_3X then + require "resty.openssl.include.provider" + + ffi.cdef [[ + int EVP_MD_get_size(const EVP_MD *md); + int EVP_MD_get_type(const EVP_MD *md); + const OSSL_PROVIDER *EVP_MD_get0_provider(const EVP_MD *md); + + EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties); + + typedef void* fake_openssl_md_provided_list_fn(EVP_MD *md, void *arg); + void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx, + fake_openssl_md_provided_list_fn*, + void *arg); + int EVP_MD_up_ref(EVP_MD *md); + void EVP_MD_free(EVP_MD *md); + + const char *EVP_MD_get0_name(const EVP_MD *md); + + int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]); + const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx); + int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]); + const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx); + ]] +end + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + EVP_MD_CTX *EVP_MD_CTX_new(void); + void EVP_MD_CTX_free(EVP_MD_CTX *ctx); + ]] +elseif OPENSSL_10 then + ffi.cdef [[ + EVP_MD_CTX *EVP_MD_CTX_create(void); + void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); + + // crypto/evp/evp.h + // only needed for openssl 1.0.x where initializer for HMAC_CTX is not avaiable + // HACK: renamed from env_md_ctx_st to evp_md_ctx_st to match typedef (lazily) + // it's an internal struct thus name is not exported so we will be fine + struct evp_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is + * ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); + } /* EVP_MD_CTX */ ; + ]] +end
\ No newline at end of file diff --git a/server/resty/openssl/include/evp/pkey.lua b/server/resty/openssl/include/evp/pkey.lua new file mode 100644 index 0000000..ee1a213 --- /dev/null +++ b/server/resty/openssl/include/evp/pkey.lua @@ -0,0 +1,234 @@ +local ffi = require "ffi" +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.evp.md" +local evp = require("resty.openssl.include.evp") +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +ffi.cdef [[ + EVP_PKEY *EVP_PKEY_new(void); + void EVP_PKEY_free(EVP_PKEY *pkey); + + RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); + EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); + DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey); + + int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); + // openssl < 3.0 + int EVP_PKEY_base_id(const EVP_PKEY *pkey); + int EVP_PKEY_size(const EVP_PKEY *pkey); + + EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); + EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); + void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); + // TODO replace EVP_PKEY_CTX_ctrl with EVP_PKEY_CTX_ctrl_str to reduce + // some hardcoded macros + int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + + int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + + EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, + const unsigned char *key, size_t keylen); + EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, + const unsigned char *key, size_t keylen); + + int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len); + int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len); + + int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + + int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); + int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, + size_t tbslen); + int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); + int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, size_t tbslen); + + int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + + int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); + int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + + int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); + int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +]] + +if OPENSSL_3X then + require "resty.openssl.include.provider" + + ffi.cdef [[ + int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode); + + int EVP_PKEY_get_base_id(const EVP_PKEY *pkey); + int EVP_PKEY_get_size(const EVP_PKEY *pkey); + + const OSSL_PROVIDER *EVP_PKEY_get0_provider(const EVP_PKEY *key); + const OSSL_PROVIDER *EVP_PKEY_CTX_get0_provider(const EVP_PKEY_CTX *ctx); + + const OSSL_PARAM *EVP_PKEY_settable_params(const EVP_PKEY *pkey); + int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[]); + int EVP_PKEY_get_params(EVP_PKEY *ctx, OSSL_PARAM params[]); + const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *ctx); + ]] +end + +if OPENSSL_10 then + ffi.cdef [[ + // crypto/evp/evp.h + // only needed for openssl 1.0.x where getters are not available + // needed to get key to extract parameters + // Note: this struct is trimmed + struct evp_pkey_st { + int type; + int save_type; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + ENGINE *pmeth_engine; + union { + void *ptr; + struct rsa_st *rsa; + struct dsa_st *dsa; + struct dh_st *dh; + struct ec_key_st *ec; + } pkey; + // trimmed + + // CRYPTO_REF_COUNT references; + // CRYPTO_RWLOCK *lock; + // STACK_OF(X509_ATTRIBUTE) *attributes; + // int save_parameters; + + // struct { + // EVP_KEYMGMT *keymgmt; + // void *provkey; + // } pkeys[10]; + // size_t dirty_cnt_copy; + }; + ]] +end + +local _M = {} + +if OPENSSL_3X or BORINGSSL then + ffi.cdef [[ + int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); + int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc); + + int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits); + int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); + + int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); + int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len); + + int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits); + ]] + _M.EVP_PKEY_CTX_set_ec_paramgen_curve_nid = function(pctx, nid) + return C.EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) + end + _M.EVP_PKEY_CTX_set_ec_param_enc = function(pctx, param_enc) + return C.EVP_PKEY_CTX_set_ec_param_enc(pctx, param_enc) + end + + _M.EVP_PKEY_CTX_set_rsa_keygen_bits = function(pctx, mbits) + return C.EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, mbits) + end + _M.EVP_PKEY_CTX_set_rsa_keygen_pubexp = function(pctx, pubexp) + return C.EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, pubexp) + end + + _M.EVP_PKEY_CTX_set_rsa_padding = function(pctx, pad) + return C.EVP_PKEY_CTX_set_rsa_padding(pctx, pad) + end + _M.EVP_PKEY_CTX_set_rsa_pss_saltlen = function(pctx, len) + return C.EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, len) + end + _M.EVP_PKEY_CTX_set_dh_paramgen_prime_len = function(pctx, pbits) + return C.EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, pbits) + end + +else + _M.EVP_PKEY_CTX_set_ec_paramgen_curve_nid = function(pctx, nid) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_EC, + evp.EVP_PKEY_OP_PARAMGEN + evp.EVP_PKEY_OP_KEYGEN, + evp.EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, + nid, nil) + end + _M.EVP_PKEY_CTX_set_ec_param_enc = function(pctx, param_enc) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_EC, + evp.EVP_PKEY_OP_PARAMGEN + evp.EVP_PKEY_OP_KEYGEN, + evp.EVP_PKEY_CTRL_EC_PARAM_ENC, + param_enc, nil) + end + + _M.EVP_PKEY_CTX_set_rsa_keygen_bits = function(pctx, mbits) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_RSA, + evp.EVP_PKEY_OP_KEYGEN, + evp.EVP_PKEY_CTRL_RSA_KEYGEN_BITS, + mbits, nil) + end + _M.EVP_PKEY_CTX_set_rsa_keygen_pubexp = function(pctx, pubexp) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_RSA, evp.EVP_PKEY_OP_KEYGEN, + evp.EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, + 0, pubexp) + end + + _M.EVP_PKEY_CTX_set_rsa_padding = function(pctx, pad) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_RSA, + -1, + evp.EVP_PKEY_CTRL_RSA_PADDING, + pad, nil) + end + _M.EVP_PKEY_CTX_set_rsa_pss_saltlen = function(pctx, len) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_RSA, + evp.EVP_PKEY_OP_SIGN + evp.EVP_PKEY_OP_VERIFY, + evp.EVP_PKEY_CTRL_RSA_PSS_SALTLEN, + len, nil) + end + + _M.EVP_PKEY_CTX_set_dh_paramgen_prime_len = function(pctx, pbits) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_DH, evp.EVP_PKEY_OP_PARAMGEN, + evp.EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, + pbits, nil) + end +end + +return _M
\ No newline at end of file diff --git a/server/resty/openssl/include/hmac.lua b/server/resty/openssl/include/hmac.lua new file mode 100644 index 0000000..e08f031 --- /dev/null +++ b/server/resty/openssl/include/hmac.lua @@ -0,0 +1,48 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.evp" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +if BORINGSSL then + ffi.cdef [[ + int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl); + ]] +else + ffi.cdef [[ + int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); + ]] +end + +ffi.cdef [[ + int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, + size_t len); + int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, + unsigned int *len); +]] + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + HMAC_CTX *HMAC_CTX_new(void); + void HMAC_CTX_free(HMAC_CTX *ctx); + ]] +elseif OPENSSL_10 then + ffi.cdef [[ + // # define HMAC_MAX_MD_CBLOCK 128/* largest known is SHA512 */ + struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[128]; + }; + + void HMAC_CTX_init(HMAC_CTX *ctx); + void HMAC_CTX_cleanup(HMAC_CTX *ctx); + ]] +end
\ No newline at end of file diff --git a/server/resty/openssl/include/objects.lua b/server/resty/openssl/include/objects.lua new file mode 100644 index 0000000..aecd324 --- /dev/null +++ b/server/resty/openssl/include/objects.lua @@ -0,0 +1,19 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" + +ffi.cdef [[ + int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); + ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); + int OBJ_txt2nid(const char *s); + const char *OBJ_nid2sn(int n); + int OBJ_ln2nid(const char *s); + int OBJ_sn2nid(const char *s); + const char *OBJ_nid2ln(int n); + const char *OBJ_nid2sn(int n); + int OBJ_obj2nid(const ASN1_OBJECT *o); + const ASN1_OBJECT *OBJ_nid2obj(int n); + int OBJ_create(const char *oid, const char *sn, const char *ln); + + int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +]] diff --git a/server/resty/openssl/include/ossl_typ.lua b/server/resty/openssl/include/ossl_typ.lua new file mode 100644 index 0000000..198c889 --- /dev/null +++ b/server/resty/openssl/include/ossl_typ.lua @@ -0,0 +1,71 @@ +local ffi = require "ffi" + +ffi.cdef( +[[ + typedef struct rsa_st RSA; + typedef struct evp_pkey_st EVP_PKEY; + typedef struct bignum_st BIGNUM; + typedef struct bn_gencb_st BN_GENCB; + typedef struct bignum_ctx BN_CTX; + typedef struct bio_st BIO; + typedef struct evp_cipher_st EVP_CIPHER; + typedef struct evp_md_ctx_st EVP_MD_CTX; + typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + typedef struct evp_md_st EVP_MD; + typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; + typedef struct engine_st ENGINE; + typedef struct x509_st X509; + typedef struct x509_attributes_st X509_ATTRIBUTE; + typedef struct X509_extension_st X509_EXTENSION; + typedef struct X509_name_st X509_NAME; + typedef struct X509_name_entry_st X509_NAME_ENTRY; + typedef struct X509_req_st X509_REQ; + typedef struct X509_crl_st X509_CRL; + typedef struct x509_store_st X509_STORE; + typedef struct x509_store_ctx_st X509_STORE_CTX; + typedef struct x509_purpose_st X509_PURPOSE; + typedef struct v3_ext_ctx X509V3_CTX; + typedef struct asn1_string_st ASN1_INTEGER; + typedef struct asn1_string_st ASN1_ENUMERATED; + typedef struct asn1_string_st ASN1_BIT_STRING; + typedef struct asn1_string_st ASN1_OCTET_STRING; + typedef struct asn1_string_st ASN1_PRINTABLESTRING; + typedef struct asn1_string_st ASN1_T61STRING; + typedef struct asn1_string_st ASN1_IA5STRING; + typedef struct asn1_string_st ASN1_GENERALSTRING; + typedef struct asn1_string_st ASN1_UNIVERSALSTRING; + typedef struct asn1_string_st ASN1_BMPSTRING; + typedef struct asn1_string_st ASN1_UTCTIME; + typedef struct asn1_string_st ASN1_TIME; + typedef struct asn1_string_st ASN1_GENERALIZEDTIME; + typedef struct asn1_string_st ASN1_VISIBLESTRING; + typedef struct asn1_string_st ASN1_UTF8STRING; + typedef struct asn1_string_st ASN1_STRING; + typedef struct asn1_object_st ASN1_OBJECT; + typedef struct conf_st CONF; + typedef struct conf_method_st CONF_METHOD; + typedef int ASN1_BOOLEAN; + typedef int ASN1_NULL; + typedef struct ec_key_st EC_KEY; + typedef struct ec_method_st EC_METHOD; + typedef struct ec_point_st EC_POINT; + typedef struct ec_group_st EC_GROUP; + typedef struct rsa_meth_st RSA_METHOD; + // typedef struct evp_keymgmt_st EVP_KEYMGMT; + // typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + // typedef struct bn_mont_ctx_st BN_MONT_CTX; + // typedef struct bn_blinding_st BN_BLINDING; + // crypto.h + // typedef void CRYPTO_RWLOCK; + typedef struct hmac_ctx_st HMAC_CTX; + typedef struct x509_revoked_st X509_REVOKED; + typedef struct dh_st DH; + typedef struct PKCS12_st PKCS12; + typedef struct ssl_st SSL; + typedef struct ssl_ctx_st SSL_CTX; + typedef struct evp_kdf_st EVP_KDF; + typedef struct evp_kdf_ctx_st EVP_KDF_CTX; + typedef struct ossl_lib_ctx_st OSSL_LIB_CTX; +]]) + diff --git a/server/resty/openssl/include/param.lua b/server/resty/openssl/include/param.lua new file mode 100644 index 0000000..9c7a2e9 --- /dev/null +++ b/server/resty/openssl/include/param.lua @@ -0,0 +1,71 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" + +ffi.cdef [[ + typedef struct ossl_param_st { + const char *key; /* the name of the parameter */ + unsigned int data_type; /* declare what kind of content is in buffer */ + void *data; /* value being passed in or out */ + size_t data_size; /* data size */ + size_t return_size; /* returned content size */ + } OSSL_PARAM; + + OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf); + OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf); + OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, + size_t bsize); + OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf); + OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, + size_t bsize); + OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf, + size_t bsize); + OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf, + size_t bsize); + OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf, + size_t bsize); + OSSL_PARAM OSSL_PARAM_construct_end(void); + + int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val); + int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val); + int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val); + int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val); + // int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val); + // int OSSL_PARAM_get_time_t(const OSSL_PARAM *p, time_t *val); + + int OSSL_PARAM_set_int(OSSL_PARAM *p, int val); + int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val); + int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val); + int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val); + int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val); + int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val); + int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val); + int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val); + // int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val); + // int OSSL_PARAM_set_time_t(OSSL_PARAM *p, time_t val); + + int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val); + int OSSL_PARAM_set_double(OSSL_PARAM *p, double val); + + int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val); + int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val); + + int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len); + int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val); + + int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len, + size_t *used_len); + int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val, size_t len); + + int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val); + int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val); + + int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, + size_t *used_len); + int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, + size_t used_len); + + int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val); + int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val, + size_t *used_len); +]] diff --git a/server/resty/openssl/include/pem.lua b/server/resty/openssl/include/pem.lua new file mode 100644 index 0000000..50185e5 --- /dev/null +++ b/server/resty/openssl/include/pem.lua @@ -0,0 +1,50 @@ + +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" + +ffi.cdef [[ + // all pem_password_cb* has been modified to pem_password_cb to avoid a table overflow issue + typedef int (*pem_password_cb)(char *buf, int size, int rwflag, void *userdata); + EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, + // the following signature has been modified to avoid ffi.cast + pem_password_cb cb, const char *u); + // pem_password_cb *cb, void *u); + EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, + // the following signature has been modified to avoid ffi.cast + pem_password_cb cb, const char *u); + // pem_password_cb *cb, void *u); + int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + int PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x); + + RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x, + // the following signature has been modified to avoid ffi.cast + pem_password_cb cb, const char *u); + // pem_password_cb *cb, void *u); + RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x, + // the following signature has been modified to avoid ffi.cast + pem_password_cb cb, const char *u); + // pem_password_cb *cb, void *u); + int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x); + + X509_REQ *PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x, pem_password_cb cb, void *u); + int PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x); + + X509_CRL *PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x, pem_password_cb cb, void *u); + int PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x); + + X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb cb, void *u); + int PEM_write_bio_X509(BIO *bp, X509 *x); + + DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb cb, void *u); + int PEM_write_bio_DHparams(BIO *bp, DH *x); + + EC_GROUP *PEM_read_bio_ECPKParameters(BIO *bp, EC_GROUP **x, pem_password_cb cb, void *u); + int PEM_write_bio_ECPKParameters(BIO *bp, const EC_GROUP *x); + +]] diff --git a/server/resty/openssl/include/pkcs12.lua b/server/resty/openssl/include/pkcs12.lua new file mode 100644 index 0000000..fb74025 --- /dev/null +++ b/server/resty/openssl/include/pkcs12.lua @@ -0,0 +1,31 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.stack" + +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X + +ffi.cdef [[ + // hack by changing char* to const char* here + PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, + OPENSSL_STACK *ca, // STACK_OF(X509) + int nid_key, int nid_cert, int iter, int mac_iter, int keytype); + + int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + OPENSSL_STACK **ca); // STACK_OF(X509) **ca); + + void PKCS12_free(PKCS12 *p12); + int i2d_PKCS12_bio(BIO *bp, PKCS12 *a); + PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **a); +]] + +if OPENSSL_3X then + ffi.cdef [[ + PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, + OPENSSL_STACK *ca, // STACK_OF(X509) + int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq); + ]] +end diff --git a/server/resty/openssl/include/provider.lua b/server/resty/openssl/include/provider.lua new file mode 100644 index 0000000..a2bb472 --- /dev/null +++ b/server/resty/openssl/include/provider.lua @@ -0,0 +1,27 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.param" + +ffi.cdef [[ + typedef struct ossl_provider_st OSSL_PROVIDER; + typedef struct ossl_lib_ctx_st OSSL_LIB_CTX; + + void OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, + const char *path); + + + OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name); + OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name); + int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); + int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name); + + const OSSL_PARAM *OSSL_PROVIDER_gettable_params(OSSL_PROVIDER *prov); + int OSSL_PROVIDER_get_params(OSSL_PROVIDER *prov, OSSL_PARAM params[]); + + // int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name, + // ossl_provider_init_fn *init_fn); + + const char *OSSL_PROVIDER_get0_name(const OSSL_PROVIDER *prov); + int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov); +]] diff --git a/server/resty/openssl/include/rand.lua b/server/resty/openssl/include/rand.lua new file mode 100644 index 0000000..90f44c1 --- /dev/null +++ b/server/resty/openssl/include/rand.lua @@ -0,0 +1,24 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +if BORINGSSL then + ffi.cdef [[ + int RAND_bytes(uint8_t *buf, size_t num); + int RAND_priv_bytes(uint8_t *buf, size_t num); + ]] +elseif OPENSSL_3X then + ffi.cdef [[ + int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, + unsigned int strength); + int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, + unsigned int strength); + ]] +else + ffi.cdef [[ + int RAND_bytes(unsigned char *buf, int num); + int RAND_priv_bytes(unsigned char *buf, int num); + ]] +end diff --git a/server/resty/openssl/include/rsa.lua b/server/resty/openssl/include/rsa.lua new file mode 100644 index 0000000..d7de5f4 --- /dev/null +++ b/server/resty/openssl/include/rsa.lua @@ -0,0 +1,70 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER + +ffi.cdef [[ + RSA *RSA_new(void); + void RSA_free(RSA *r); +]] + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); + void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); + void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp); + + int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); + int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); + int RSA_set0_crt_params(RSA *r,BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); + struct rsa_st; + ]] +elseif OPENSSL_10 then + ffi.cdef [[ + // crypto/rsa/rsa_locl.h + // needed to extract parameters + // Note: this struct is trimmed + struct rsa_st { + int pad; + // the following has been changed in OpenSSL 1.1.x to int32_t + long version; + const RSA_METHOD *meth; + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + // trimmed + + // CRYPTO_EX_DATA ex_data; + // int references; + // int flags; + // BN_MONT_CTX *_method_mod_n; + // BN_MONT_CTX *_method_mod_p; + // BN_MONT_CTX *_method_mod_q; + + // char *bignum_data; + // BN_BLINDING *blinding; + // BN_BLINDING *mt_blinding; + }; + ]] +end + +return { + paddings = { + RSA_PKCS1_PADDING = 1, + RSA_SSLV23_PADDING = 2, + RSA_NO_PADDING = 3, + RSA_PKCS1_OAEP_PADDING = 4, + RSA_X931_PADDING = 5, + RSA_PKCS1_PSS_PADDING = 6, + }, +} diff --git a/server/resty/openssl/include/ssl.lua b/server/resty/openssl/include/ssl.lua new file mode 100644 index 0000000..1219ac3 --- /dev/null +++ b/server/resty/openssl/include/ssl.lua @@ -0,0 +1,113 @@ +local ffi = require "ffi" +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.stack" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +ffi.cdef [[ + // SSL_METHOD + typedef struct ssl_method_st SSL_METHOD; + const SSL_METHOD *TLS_method(void); + const SSL_METHOD *TLS_server_method(void); + + // SSL_CIPHER + typedef struct ssl_cipher_st SSL_CIPHER; + const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher); + SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + + SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); + void SSL_CTX_free(SSL_CTX *a); + + // SSL_SESSION + typedef struct ssl_session_st SSL_SESSION; + SSL_SESSION *SSL_get_session(const SSL *ssl); + long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); + long SSL_SESSION_get_timeout(const SSL_SESSION *s); + + typedef int (*SSL_CTX_alpn_select_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); + void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + SSL_CTX_alpn_select_cb_func cb, + void *arg); + + int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *server, + unsigned int server_len, + const unsigned char *client, + unsigned int client_len); + + SSL *SSL_new(SSL_CTX *ctx); + void SSL_free(SSL *ssl); + + int SSL_set_cipher_list(SSL *ssl, const char *str); + int SSL_set_ciphersuites(SSL *s, const char *str); + + long SSL_set_options(SSL *ssl, long options); + long SSL_clear_options(SSL *ssl, long options); + long SSL_get_options(SSL *ssl); + + /*STACK_OF(SSL_CIPHER)*/ OPENSSL_STACK *SSL_get_ciphers(const SSL *ssl); + /*STACK_OF(SSL_CIPHER)*/ OPENSSL_STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + OPENSSL_STACK *SSL_get_peer_cert_chain(const SSL *ssl); + + typedef int (*verify_callback)(int preverify_ok, X509_STORE_CTX *x509_ctx); + void SSL_set_verify(SSL *s, int mode, + int (*verify_callback)(int, X509_STORE_CTX *)); + + int SSL_add_client_CA(SSL *ssl, X509 *cacert); + + long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +]] + +if OPENSSL_3X then + ffi.cdef [[ + X509 *SSL_get1_peer_certificate(const SSL *ssl); + ]] +else + ffi.cdef [[ + X509 *SSL_get_peer_certificate(const SSL *ssl); + ]] +end + +if BORINGSSL then + ffi.cdef [[ + int SSL_set_min_proto_version(SSL *ssl, int version); + int SSL_set_max_proto_version(SSL *ssl, int version); + ]] +end + +local SSL_CTRL_SET_MIN_PROTO_VERSION = 123 +local SSL_CTRL_SET_MAX_PROTO_VERSION = 124 + +local SSL_set_min_proto_version +if BORINGSSL then + SSL_set_min_proto_version = function(ctx, version) + return C.SSL_set_min_proto_version(ctx, version) + end +else + SSL_set_min_proto_version = function(ctx, version) + return C.SSL_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nil) + end +end + +local SSL_set_max_proto_version +if BORINGSSL then + SSL_set_max_proto_version = function(ctx, version) + return C.SSL_set_max_proto_version(ctx, version) + end +else + SSL_set_max_proto_version = function(ctx, version) + return C.SSL_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nil) + end +end + +return { + SSL_set_min_proto_version = SSL_set_min_proto_version, + SSL_set_max_proto_version = SSL_set_max_proto_version, +} diff --git a/server/resty/openssl/include/stack.lua b/server/resty/openssl/include/stack.lua new file mode 100644 index 0000000..5732608 --- /dev/null +++ b/server/resty/openssl/include/stack.lua @@ -0,0 +1,95 @@ +--[[ + The OpenSSL stack library. Note `safestack` is not usable here in ffi because + those symbols are eaten after preprocessing. + Instead, we should do a Lua land type checking by having a nested field indicating + which type of cdata its ctx holds. +]] + +local ffi = require "ffi" +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local BORINGSSL = require("resty.openssl.version").BORINGSSL + +local _M = {} + +ffi.cdef [[ + typedef char *OPENSSL_STRING; +]] + +if OPENSSL_11_OR_LATER and not BORINGSSL then + ffi.cdef [[ + typedef struct stack_st OPENSSL_STACK; + + OPENSSL_STACK *OPENSSL_sk_new_null(void); + int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data); + void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *)); + int OPENSSL_sk_num(const OPENSSL_STACK *); + void *OPENSSL_sk_value(const OPENSSL_STACK *, int); + OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *st); + void OPENSSL_sk_free(OPENSSL_STACK *); + void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc); + + typedef void (*OPENSSL_sk_freefunc)(void *); + typedef void *(*OPENSSL_sk_copyfunc)(const void *); + OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *, + OPENSSL_sk_copyfunc c, + OPENSSL_sk_freefunc f); + ]] + _M.OPENSSL_sk_pop_free = C.OPENSSL_sk_pop_free + + _M.OPENSSL_sk_new_null = C.OPENSSL_sk_new_null + _M.OPENSSL_sk_push = C.OPENSSL_sk_push + _M.OPENSSL_sk_pop_free = C.OPENSSL_sk_pop_free + _M.OPENSSL_sk_num = C.OPENSSL_sk_num + _M.OPENSSL_sk_value = C.OPENSSL_sk_value + _M.OPENSSL_sk_dup = C.OPENSSL_sk_dup + _M.OPENSSL_sk_delete = C.OPENSSL_sk_delete + _M.OPENSSL_sk_free = C.OPENSSL_sk_free + _M.OPENSSL_sk_deep_copy = C.OPENSSL_sk_deep_copy +elseif OPENSSL_10 or BORINGSSL then + ffi.cdef [[ + typedef struct stack_st _STACK; + // i made this up + typedef struct stack_st OPENSSL_STACK; + + _STACK *sk_new_null(void); + void sk_pop_free(_STACK *st, void (*func) (void *)); + _STACK *sk_dup(_STACK *st); + void sk_free(_STACK *st); + + _STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *)); + ]] + + if BORINGSSL then -- indices are using size_t instead of int + ffi.cdef [[ + size_t sk_push(_STACK *st, void *data); + size_t sk_num(const _STACK *); + void *sk_value(const _STACK *, size_t); + void *sk_delete(_STACK *st, size_t loc); + ]] + else -- normal OpenSSL 1.0 + ffi.cdef [[ + int sk_push(_STACK *st, void *data); + int sk_num(const _STACK *); + void *sk_value(const _STACK *, int); + void *sk_delete(_STACK *st, int loc); + ]] + end + + _M.OPENSSL_sk_pop_free = C.sk_pop_free + + _M.OPENSSL_sk_new_null = C.sk_new_null + _M.OPENSSL_sk_push = function(...) return tonumber(C.sk_push(...)) end + _M.OPENSSL_sk_pop_free = C.sk_pop_free + _M.OPENSSL_sk_num = function(...) return tonumber(C.sk_num(...)) end + _M.OPENSSL_sk_value = C.sk_value + _M.OPENSSL_sk_delete = C.sk_delete + _M.OPENSSL_sk_dup = C.sk_dup + _M.OPENSSL_sk_free = C.sk_free + _M.OPENSSL_sk_deep_copy = C.sk_deep_copy +end + +return _M diff --git a/server/resty/openssl/include/x509/altname.lua b/server/resty/openssl/include/x509/altname.lua new file mode 100644 index 0000000..ce1db67 --- /dev/null +++ b/server/resty/openssl/include/x509/altname.lua @@ -0,0 +1,49 @@ +local GEN_OTHERNAME = 0 +local GEN_EMAIL = 1 +local GEN_DNS = 2 +local GEN_X400 = 3 +local GEN_DIRNAME = 4 +local GEN_EDIPARTY = 5 +local GEN_URI = 6 +local GEN_IPADD = 7 +local GEN_RID = 8 + +local default_types = { + OtherName = GEN_OTHERNAME, -- otherName + RFC822Name = GEN_EMAIL, -- email + RFC822 = GEN_EMAIL, + Email = GEN_EMAIL, + DNSName = GEN_DNS, -- dns + DNS = GEN_DNS, + X400 = GEN_X400, -- x400 + DirName = GEN_DIRNAME, -- dirName + EdiParty = GEN_EDIPARTY, -- EdiParty + UniformResourceIdentifier = GEN_URI, -- uri + URI = GEN_URI, + IPAddress = GEN_IPADD, -- ipaddr + IP = GEN_IPADD, + RID = GEN_RID, -- rid +} + +local literals = { + [GEN_OTHERNAME] = "OtherName", + [GEN_EMAIL] = "email", + [GEN_DNS] = "DNS", + [GEN_X400] = "X400", + [GEN_DIRNAME] = "DirName", + [GEN_EDIPARTY] = "EdiParty", + [GEN_URI] = "URI", + [GEN_IPADD] = "IP", + [GEN_RID] = "RID", +} + +local types = {} +for t, gid in pairs(default_types) do + types[t:lower()] = gid + types[t] = gid +end + +return { + types = types, + literals = literals, +}
\ No newline at end of file diff --git a/server/resty/openssl/include/x509/crl.lua b/server/resty/openssl/include/x509/crl.lua new file mode 100644 index 0000000..7870cd3 --- /dev/null +++ b/server/resty/openssl/include/x509/crl.lua @@ -0,0 +1,86 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.evp" +require "resty.openssl.include.objects" +require "resty.openssl.include.x509" +require "resty.openssl.include.stack" + +local asn1_macro = require "resty.openssl.include.asn1" + +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110 + +asn1_macro.declare_asn1_functions("X509_CRL", asn1_macro.has_new_ex) + +ffi.cdef [[ + X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); + int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); + int X509_CRL_set_version(X509_CRL *x, long version); + + int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); + X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); + int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos); + void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx); + + int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); + int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); + + int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); + X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); + int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); + + int X509_CRL_print(BIO *bio, X509_CRL *crl); + + int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); + int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + + //STACK_OF(X509_REVOKED) + OPENSSL_STACK *X509_CRL_get_REVOKED(X509_CRL *crl); + + int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +]] + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); + int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); + /*const*/ ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); + /*const*/ ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); + long X509_CRL_get_version(const X509_CRL *crl); + + X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); + + int X509_CRL_get_signature_nid(const X509_CRL *crl); + ]] +end +if OPENSSL_10 or BORINGSSL_110 then + -- in openssl 1.0.x some getters are direct accessor to struct members (defiend by macros) + ffi.cdef [[ + typedef struct X509_crl_info_st { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + // STACK_OF(X509_REVOKED) + OPENSSL_STACK *revoked; + // STACK_OF(X509_EXTENSION) + OPENSSL_STACK /* [0] */ *extensions; + ASN1_ENCODING enc; + } X509_CRL_INFO; + + // Note: this struct is trimmed + struct X509_crl_st { + /* actual signature */ + X509_CRL_INFO *crl; + // trimmed + } /* X509_CRL */ ; + + int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); + int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); + ]] +end diff --git a/server/resty/openssl/include/x509/csr.lua b/server/resty/openssl/include/x509/csr.lua new file mode 100644 index 0000000..44c4801 --- /dev/null +++ b/server/resty/openssl/include/x509/csr.lua @@ -0,0 +1,88 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.evp" +require "resty.openssl.include.objects" +require "resty.openssl.include.x509" +require "resty.openssl.include.stack" + +local asn1_macro = require "resty.openssl.include.asn1" + +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110 + +asn1_macro.declare_asn1_functions("X509_REQ", asn1_macro.has_new_ex) + +ffi.cdef [[ + int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); + + EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); + int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); + + int X509_REQ_set_version(X509_REQ *x, long version); + + int X509_REQ_get_attr_count(const X509_REQ *req); + + int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); + X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); + int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos); + + int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); + void X509_ATTRIBUTE_free(X509_ATTRIBUTE *a); + int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); + X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); + + int *X509_REQ_get_extension_nids(void); + + int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); + int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); + + int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); + X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); + + // STACK_OF(X509_EXTENSION) + OPENSSL_STACK *X509_REQ_get_extensions(X509_REQ *req); + // STACK_OF(X509_EXTENSION) + int X509_REQ_add_extensions(X509_REQ *req, OPENSSL_STACK *exts); + + int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k); +]] + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); + long X509_REQ_get_version(const X509_REQ *req); + + int X509_REQ_get_signature_nid(const X509_REQ *crl); + ]] +end +if OPENSSL_10 or BORINGSSL_110 then + ffi.cdef [[ + typedef struct X509_req_info_st { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + /*X509_PUBKEY*/ void *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + /*STACK_OF(X509_ATTRIBUTE)*/ OPENSSL_STACK *attributes; /* [ 0 ] */ + } X509_REQ_INFO; + + // Note: this struct is trimmed + typedef struct X509_req_st { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + // trimmed + //ASN1_BIT_STRING *signature; + //int references; + } X509_REQ; + ]] +end + +if OPENSSL_3X then + ffi.cdef [[ + int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *propq); + ]] +end diff --git a/server/resty/openssl/include/x509/extension.lua b/server/resty/openssl/include/x509/extension.lua new file mode 100644 index 0000000..14b231e --- /dev/null +++ b/server/resty/openssl/include/x509/extension.lua @@ -0,0 +1,44 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.x509v3" +require "resty.openssl.include.x509" +local asn1_macro = require "resty.openssl.include.asn1" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X + +asn1_macro.declare_asn1_functions("X509_EXTENSION") + +if OPENSSL_3X then + ffi.cdef [[ + struct v3_ext_ctx { + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + /*X509V3_CONF_METHOD*/ void *db_meth; + void *db; + EVP_PKEY *issuer_pkey; + }; + + int X509V3_set_issuer_pkey(X509V3_CTX *ctx, EVP_PKEY *pkey); + ]] + +else + ffi.cdef [[ + struct v3_ext_ctx { + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + /*X509V3_CONF_METHOD*/ void *db_meth; + void *db; + }; + ]] +end + +ffi.cdef [[ + int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); + int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj); +]]
\ No newline at end of file diff --git a/server/resty/openssl/include/x509/init.lua b/server/resty/openssl/include/x509/init.lua new file mode 100644 index 0000000..ec104ef --- /dev/null +++ b/server/resty/openssl/include/x509/init.lua @@ -0,0 +1,138 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.bio" +require "resty.openssl.include.pem" +require "resty.openssl.include.stack" +local asn1_macro = require "resty.openssl.include.asn1" + +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110 + +asn1_macro.declare_asn1_functions("X509", asn1_macro.has_new_ex) + +ffi.cdef [[ + int i2d_X509_bio(BIO *bp, X509 *x509); + X509 *d2i_X509_bio(BIO *bp, X509 **x509); + + // STACK_OF(X509) + OPENSSL_STACK *X509_chain_up_ref(OPENSSL_STACK *chain); + + int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); + int X509_verify(X509 *a, EVP_PKEY *r); + + ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + + int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); + X509_EXTENSION *X509_get_ext(const X509 *x, int loc); + int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); + void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); + + int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); + int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); + ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); + X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); + X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); + + // needed by pkey + EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); + EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); + int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); + + EVP_PKEY *X509_get_pubkey(X509 *x); + int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); + int X509_set_version(X509 *x, long version); + int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); + + X509_NAME *X509_get_subject_name(const X509 *a); + int X509_set_subject_name(X509 *x, X509_NAME *name); + X509_NAME *X509_get_issuer_name(const X509 *a); + int X509_set_issuer_name(X509 *x, X509_NAME *name); + + int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); + int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); + + const char *X509_verify_cert_error_string(long n); + int X509_verify_cert(X509_STORE_CTX *ctx); + + int X509_get_signature_nid(const X509 *x); + + unsigned char *X509_alias_get0(X509 *x, int *len); + unsigned char *X509_keyid_get0(X509 *x, int *len); + int X509_check_private_key(X509 *x, EVP_PKEY *k); +]] + +if OPENSSL_11_OR_LATER then + ffi.cdef [[ + int X509_up_ref(X509 *a); + + int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); + int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); + /*const*/ ASN1_TIME *X509_get0_notBefore(const X509 *x); + /*const*/ ASN1_TIME *X509_get0_notAfter(const X509 *x); + long X509_get_version(const X509 *x); + const ASN1_INTEGER *X509_get0_serialNumber(X509 *x); + + X509_EXTENSION *X509_delete_ext(X509 *x, int loc); + ]] +elseif OPENSSL_10 then + ffi.cdef [[ + // STACK_OF(X509_EXTENSION) + X509_EXTENSION *X509v3_delete_ext(OPENSSL_STACK *x, int loc); + ]] +end + +if OPENSSL_10 or BORINGSSL_110 then + -- in openssl 1.0.x some getters are direct accessor to struct members (defiend by macros) + ffi.cdef [[ + // crypto/x509/x509.h + typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; + } X509_VAL; + + typedef struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; + } X509_ALGOR; + + // Note: this struct is trimmed + typedef struct x509_cinf_st { + /*ASN1_INTEGER*/ void *version; + /*ASN1_INTEGER*/ void *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + /*X509_PUBKEY*/ void *key; + /*ASN1_BIT_STRING*/ void *issuerUID; /* [ 1 ] optional in v2 */ + /*ASN1_BIT_STRING*/ void *subjectUID; /* [ 2 ] optional in v2 */ + /*STACK_OF(X509_EXTENSION)*/ OPENSSL_STACK *extensions; /* [ 3 ] optional in v3 */ + // trimmed + // ASN1_ENCODING enc; + } X509_CINF; + // Note: this struct is trimmed + struct x509_st { + X509_CINF *cert_info; + // trimmed + } X509; + + int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); + int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); + ASN1_INTEGER *X509_get_serialNumber(X509 *x); + ]] +end + +if BORINGSSL_110 then + ffi.cdef [[ + ASN1_TIME *X509_get_notBefore(const X509 *x); + ASN1_TIME *X509_get_notAfter(const X509 *x); + ]] +end diff --git a/server/resty/openssl/include/x509/name.lua b/server/resty/openssl/include/x509/name.lua new file mode 100644 index 0000000..2f933ae --- /dev/null +++ b/server/resty/openssl/include/x509/name.lua @@ -0,0 +1,21 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.asn1" +require "resty.openssl.include.objects" +local asn1_macro = require "resty.openssl.include.asn1" + +asn1_macro.declare_asn1_functions("X509_NAME") + +ffi.cdef [[ + int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, + int set); + + int X509_NAME_entry_count(const X509_NAME *name); + X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); + ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); + ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); + int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +]]
\ No newline at end of file diff --git a/server/resty/openssl/include/x509/revoked.lua b/server/resty/openssl/include/x509/revoked.lua new file mode 100644 index 0000000..c6539c9 --- /dev/null +++ b/server/resty/openssl/include/x509/revoked.lua @@ -0,0 +1,17 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.asn1" +require "resty.openssl.include.objects" +local asn1_macro = require "resty.openssl.include.asn1" + +asn1_macro.declare_asn1_functions("X509_REVOKED") + +ffi.cdef [[ + int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); + int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); + + const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *r); + const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *r); +]]
\ No newline at end of file diff --git a/server/resty/openssl/include/x509_vfy.lua b/server/resty/openssl/include/x509_vfy.lua new file mode 100644 index 0000000..d783d19 --- /dev/null +++ b/server/resty/openssl/include/x509_vfy.lua @@ -0,0 +1,108 @@ +local ffi = require "ffi" +local C = ffi.C + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.stack" +local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110 + +ffi.cdef [[ + X509_STORE *X509_STORE_new(void); + void X509_STORE_free(X509_STORE *v); + /* int X509_STORE_lock(X509_STORE *ctx); + int X509_STORE_unlock(X509_STORE *ctx); + int X509_STORE_up_ref(X509_STORE *v); + // STACK_OF(X509_OBJECT) + OPENSSL_STACK *X509_STORE_get0_objects(X509_STORE *v);*/ + + int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); + int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); + int X509_STORE_set_default_paths(X509_STORE *ctx); + int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); + int X509_STORE_set_depth(X509_STORE *store, int depth); + int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); + + X509_STORE_CTX *X509_STORE_CTX_new(void); + void X509_STORE_CTX_free(X509_STORE_CTX *ctx); + // STACK_OF(X509) + int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, OPENSSL_STACK *chain); + + int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); + + int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + + int X509_PURPOSE_get_by_sname(char *sname); + X509_PURPOSE *X509_PURPOSE_get0(int idx); + int X509_PURPOSE_get_id(const X509_PURPOSE *xp); +]] + +local _M = { + verify_flags = { + X509_V_FLAG_CB_ISSUER_CHECK = 0x0, -- Deprecated + X509_V_FLAG_USE_CHECK_TIME = 0x2, + X509_V_FLAG_CRL_CHECK = 0x4, + X509_V_FLAG_CRL_CHECK_ALL = 0x8, + X509_V_FLAG_IGNORE_CRITICAL = 0x10, + X509_V_FLAG_X509_STRICT = 0x20, + X509_V_FLAG_ALLOW_PROXY_CERTS = 0x40, + X509_V_FLAG_POLICY_CHECK = 0x80, + X509_V_FLAG_EXPLICIT_POLICY = 0x100, + X509_V_FLAG_INHIBIT_ANY = 0x200, + X509_V_FLAG_INHIBIT_MAP = 0x400, + X509_V_FLAG_NOTIFY_POLICY = 0x800, + X509_V_FLAG_EXTENDED_CRL_SUPPORT = 0x1000, + X509_V_FLAG_USE_DELTAS = 0x2000, + X509_V_FLAG_CHECK_SS_SIGNATURE = 0x4000, + X509_V_FLAG_TRUSTED_FIRST = 0x8000, + X509_V_FLAG_SUITEB_128_LOS_ONLY = 0x10000, + X509_V_FLAG_SUITEB_192_LOS = 0x20000, + X509_V_FLAG_SUITEB_128_LOS = 0x30000, + X509_V_FLAG_PARTIAL_CHAIN = 0x80000, + X509_V_FLAG_NO_ALT_CHAINS = 0x100000, + X509_V_FLAG_NO_CHECK_TIME = 0x200000, + }, +} + +if OPENSSL_10 or BORINGSSL_110 then + ffi.cdef [[ + // STACK_OF(X509) + OPENSSL_STACK *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); + ]]; + _M.X509_STORE_CTX_get0_chain = C.X509_STORE_CTX_get_chain +elseif OPENSSL_11_OR_LATER then + ffi.cdef [[ + // STACK_OF(X509) + OPENSSL_STACK *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); + ]]; + _M.X509_STORE_CTX_get0_chain = C.X509_STORE_CTX_get0_chain +end + +if OPENSSL_3X then + ffi.cdef [[ + X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); + + int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, + const char *propq); + /* int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, + OSSL_LIB_CTX *libctx, const char *propq); + int X509_STORE_load_store_ex(X509_STORE *ctx, const char *uri, + OSSL_LIB_CTX *libctx, const char *propq); */ + int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, + const char *dir, OSSL_LIB_CTX *libctx, + const char *propq); + ]] + _M.X509_STORE_set_default_paths = function(...) return C.X509_STORE_set_default_paths_ex(...) end + _M.X509_STORE_load_locations = function(...) return C.X509_STORE_load_locations_ex(...) end +else + _M.X509_STORE_set_default_paths = function(s) return C.X509_STORE_set_default_paths(s) end + _M.X509_STORE_load_locations = function(s, file, dir) return C.X509_STORE_load_locations(s, file, dir) end +end + + +return _M + diff --git a/server/resty/openssl/include/x509v3.lua b/server/resty/openssl/include/x509v3.lua new file mode 100644 index 0000000..6882c6e --- /dev/null +++ b/server/resty/openssl/include/x509v3.lua @@ -0,0 +1,108 @@ +local ffi = require "ffi" + +require "resty.openssl.include.ossl_typ" +require "resty.openssl.include.stack" +local asn1_macro = require "resty.openssl.include.asn1" + +ffi.cdef [[ + // STACK_OF(OPENSSL_STRING) + OPENSSL_STACK *X509_get1_ocsp(X509 *x); + void X509_email_free(OPENSSL_STACK *sk); + void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); + + typedef struct EDIPartyName_st EDIPARTYNAME; + + typedef struct otherName_st OTHERNAME; + + typedef struct GENERAL_NAME_st { + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; + } GENERAL_NAME; + + // STACK_OF(GENERAL_NAME) + typedef struct stack_st GENERAL_NAMES; + + // STACK_OF(X509_EXTENSION) + int X509V3_add1_i2d(OPENSSL_STACK **x, int nid, void *value, + int crit, unsigned long flags); + void *X509V3_EXT_d2i(X509_EXTENSION *ext); + X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); + int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); + + int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + // although the struct has plural form, it's not a stack + typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; + } BASIC_CONSTRAINTS; + + void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + + X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); + X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); + int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); + + void *X509V3_get_d2i(const OPENSSL_STACK *x, int nid, int *crit, int *idx); + + int X509v3_get_ext_by_NID(const OPENSSL_STACK *x, + int nid, int lastpos); + + X509_EXTENSION *X509v3_get_ext(const OPENSSL_STACK *x, int loc); + + // STACK_OF(ACCESS_DESCRIPTION) + typedef struct stack_st AUTHORITY_INFO_ACCESS; + + typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; + } ACCESS_DESCRIPTION; + + typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + // STACK_OF(X509_NAME_ENTRY) + OPENSSL_STACK *relativename; + } name; + /* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; + } DIST_POINT_NAME; + + typedef struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; + } DIST_POINT; + +]] + +asn1_macro.declare_asn1_functions("GENERAL_NAME") +asn1_macro.declare_asn1_functions("BASIC_CONSTRAINTS") +asn1_macro.declare_asn1_functions("AUTHORITY_INFO_ACCESS") -- OCSP responder and CA +asn1_macro.declare_asn1_functions("ACCESS_DESCRIPTION") +asn1_macro.declare_asn1_functions("DIST_POINT") -- CRL distribution points |