diff options
-rw-r--r-- | doc/luaossl.pdf | bin | 288460 -> 289161 bytes | |||
-rw-r--r-- | doc/luaossl.tex | 4 | ||||
-rw-r--r-- | src/openssl.c | 60 | ||||
-rw-r--r-- | src/openssl.ssl.context.lua | 13 |
4 files changed, 69 insertions, 8 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf index 0823b81..dccba97 100644 --- a/doc/luaossl.pdf +++ b/doc/luaossl.pdf | |||
Binary files differ | |||
diff --git a/doc/luaossl.tex b/doc/luaossl.tex index de461ba..433dd03 100644 --- a/doc/luaossl.tex +++ b/doc/luaossl.tex | |||
@@ -871,9 +871,9 @@ Sets the X.509 certificate \module{openssl.x509} object $crt$ to send during SSL | |||
871 | 871 | ||
872 | Sets the private key \module{openssl.pkey} object $key$ for use during SSL connection instance handshakes. | 872 | Sets the private key \module{openssl.pkey} object $key$ for use during SSL connection instance handshakes. |
873 | 873 | ||
874 | \subsubsection[\fn{context:setCipherList}]{\fn{context:setCipherList($string$)}} | 874 | \subsubsection[\fn{context:setCipherList}]{\fn{context:setCipherList($string$ [, ...])}} |
875 | 875 | ||
876 | Sets the allowed public key and private key algorithms. The string format is documented in the \href{http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT}{OpenSSL ciphers(1) utility documentation}. | 876 | Sets the allowed public key and private key algorithm(s). The string format is documented in the \href{http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT}{OpenSSL ciphers(1) utility documentation}. |
877 | 877 | ||
878 | \subsubsection[\fn{context:setEphemeralKey}]{\fn{context:setEphemeralKey($key$)}} | 878 | \subsubsection[\fn{context:setEphemeralKey}]{\fn{context:setEphemeralKey($key$)}} |
879 | 879 | ||
diff --git a/src/openssl.c b/src/openssl.c index 82483af..c3f8bbb 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -1763,6 +1763,20 @@ static BN_CTX *getctx(lua_State *L) { | |||
1763 | } /* getctx() */ | 1763 | } /* getctx() */ |
1764 | 1764 | ||
1765 | 1765 | ||
1766 | static int bn_tobin(lua_State *L) { | ||
1767 | BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); | ||
1768 | size_t len; | ||
1769 | void *dst; | ||
1770 | |||
1771 | len = BN_num_bytes(bn); | ||
1772 | dst = lua_newuserdata(L, len); | ||
1773 | BN_bn2bin(bn, dst); | ||
1774 | lua_pushlstring(L, dst, len); | ||
1775 | |||
1776 | return 1; | ||
1777 | } /* bn_tobin() */ | ||
1778 | |||
1779 | |||
1766 | static int bn__add(lua_State *L) { | 1780 | static int bn__add(lua_State *L) { |
1767 | BIGNUM *r, *a, *b; | 1781 | BIGNUM *r, *a, *b; |
1768 | 1782 | ||
@@ -1819,6 +1833,12 @@ static int bn__mod(lua_State *L) { | |||
1819 | if (!BN_mod(r, a, b, getctx(L))) | 1833 | if (!BN_mod(r, a, b, getctx(L))) |
1820 | return auxL_error(L, auxL_EOPENSSL, "bignum:__mod"); | 1834 | return auxL_error(L, auxL_EOPENSSL, "bignum:__mod"); |
1821 | 1835 | ||
1836 | /* lua has different rounding behaviour for mod than C */ | ||
1837 | if (!BN_is_zero(r) && (BN_is_negative(a) ^ BN_is_negative(b))) { | ||
1838 | if (!BN_add(r, r, b)) | ||
1839 | return auxL_error(L, auxL_EOPENSSL, "bignum:__mod"); | ||
1840 | } | ||
1841 | |||
1822 | return 1; | 1842 | return 1; |
1823 | } /* bn__mod() */ | 1843 | } /* bn__mod() */ |
1824 | 1844 | ||
@@ -1888,21 +1908,40 @@ static int bn__gc(lua_State *L) { | |||
1888 | } /* bn__gc() */ | 1908 | } /* bn__gc() */ |
1889 | 1909 | ||
1890 | 1910 | ||
1911 | static BIO *getbio(lua_State *); | ||
1912 | |||
1891 | static int bn__tostring(lua_State *L) { | 1913 | static int bn__tostring(lua_State *L) { |
1892 | BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); | 1914 | BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); |
1893 | char *txt; | 1915 | char *txt = NULL; |
1916 | BIO *bio; | ||
1917 | BUF_MEM *buf; | ||
1894 | 1918 | ||
1895 | if (!(txt = BN_bn2dec(bn))) | 1919 | if (!(txt = BN_bn2dec(bn))) |
1896 | return auxL_error(L, auxL_EOPENSSL, "bignum:__tostring"); | 1920 | goto sslerr; |
1897 | 1921 | ||
1898 | lua_pushstring(L, txt); | 1922 | /* use GC-visible BIO as temporary buffer */ |
1923 | bio = getbio(L); | ||
1924 | |||
1925 | if (BIO_puts(bio, txt) < 0) | ||
1926 | goto sslerr; | ||
1927 | |||
1928 | OPENSSL_free(txt); | ||
1929 | txt = NULL; | ||
1930 | |||
1931 | BIO_get_mem_ptr(bio, &buf); | ||
1932 | lua_pushlstring(L, buf->data, buf->length); | ||
1899 | 1933 | ||
1900 | return 1; | 1934 | return 1; |
1935 | sslerr: | ||
1936 | OPENSSL_free(txt); | ||
1937 | |||
1938 | return auxL_error(L, auxL_EOPENSSL, "bignum:__tostring"); | ||
1901 | } /* bn__tostring() */ | 1939 | } /* bn__tostring() */ |
1902 | 1940 | ||
1903 | 1941 | ||
1904 | static const luaL_Reg bn_methods[] = { | 1942 | static const luaL_Reg bn_methods[] = { |
1905 | { NULL, NULL }, | 1943 | { "tobin", &bn_tobin }, |
1944 | { NULL, NULL }, | ||
1906 | }; | 1945 | }; |
1907 | 1946 | ||
1908 | static const luaL_Reg bn_metatable[] = { | 1947 | static const luaL_Reg bn_metatable[] = { |
@@ -2391,8 +2430,8 @@ static int pk_toPEM(lua_State *L) { | |||
2391 | 2430 | ||
2392 | len = BIO_get_mem_data(bio, &pem); | 2431 | len = BIO_get_mem_data(bio, &pem); |
2393 | lua_pushlstring(L, pem, len); | 2432 | lua_pushlstring(L, pem, len); |
2394 | |||
2395 | BIO_reset(bio); | 2433 | BIO_reset(bio); |
2434 | |||
2396 | break; | 2435 | break; |
2397 | case 2: case 3: /* private, PrivateKey */ | 2436 | case 2: case 3: /* private, PrivateKey */ |
2398 | if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0)) | 2437 | if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0)) |
@@ -2400,6 +2439,7 @@ static int pk_toPEM(lua_State *L) { | |||
2400 | 2439 | ||
2401 | len = BIO_get_mem_data(bio, &pem); | 2440 | len = BIO_get_mem_data(bio, &pem); |
2402 | lua_pushlstring(L, pem, len); | 2441 | lua_pushlstring(L, pem, len); |
2442 | BIO_reset(bio); | ||
2403 | 2443 | ||
2404 | break; | 2444 | break; |
2405 | #if 0 | 2445 | #if 0 |
@@ -5539,9 +5579,11 @@ static int sx_new(lua_State *L) { | |||
5539 | method = (srv)? &SSLv2_server_method : &SSLv2_client_method; | 5579 | method = (srv)? &SSLv2_server_method : &SSLv2_client_method; |
5540 | break; | 5580 | break; |
5541 | #endif | 5581 | #endif |
5582 | #ifndef OPENSSL_NO_SSL3 | ||
5542 | case 3: /* SSLv3 */ | 5583 | case 3: /* SSLv3 */ |
5543 | method = (srv)? &SSLv3_server_method : &SSLv3_client_method; | 5584 | method = (srv)? &SSLv3_server_method : &SSLv3_client_method; |
5544 | break; | 5585 | break; |
5586 | #endif | ||
5545 | case 4: /* SSLv23 */ | 5587 | case 4: /* SSLv23 */ |
5546 | method = (srv)? &SSLv23_server_method : &SSLv23_client_method; | 5588 | method = (srv)? &SSLv23_server_method : &SSLv23_client_method; |
5547 | break; | 5589 | break; |
@@ -6525,13 +6567,19 @@ static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) { | |||
6525 | static int cipher_new(lua_State *L) { | 6567 | static int cipher_new(lua_State *L) { |
6526 | const EVP_CIPHER *type; | 6568 | const EVP_CIPHER *type; |
6527 | EVP_CIPHER_CTX *ctx; | 6569 | EVP_CIPHER_CTX *ctx; |
6570 | unsigned char key[EVP_MAX_KEY_LENGTH] = { 0 }; | ||
6528 | 6571 | ||
6529 | type = cipher_checktype(L, 1); | 6572 | type = cipher_checktype(L, 1); |
6530 | 6573 | ||
6531 | ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL); | 6574 | ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL); |
6532 | EVP_CIPHER_CTX_init(ctx); | 6575 | EVP_CIPHER_CTX_init(ctx); |
6533 | 6576 | ||
6534 | if (!EVP_CipherInit_ex(ctx, type, NULL, NULL, NULL, -1)) | 6577 | /* |
6578 | * NOTE: For some ciphers like AES calling :update or :final without | ||
6579 | * setting a key causes a SEGV. Set a dummy key here. Same solution | ||
6580 | * as used by Ruby OSSL. | ||
6581 | */ | ||
6582 | if (!EVP_CipherInit_ex(ctx, type, NULL, key, NULL, -1)) | ||
6535 | return auxL_error(L, auxL_EOPENSSL, "cipher.new"); | 6583 | return auxL_error(L, auxL_EOPENSSL, "cipher.new"); |
6536 | 6584 | ||
6537 | return 1; | 6585 | return 1; |
diff --git a/src/openssl.ssl.context.lua b/src/openssl.ssl.context.lua index 44a9163..2098b54 100644 --- a/src/openssl.ssl.context.lua +++ b/src/openssl.ssl.context.lua | |||
@@ -1,3 +1,16 @@ | |||
1 | local ctx = require"_openssl.ssl.context" | 1 | local ctx = require"_openssl.ssl.context" |
2 | 2 | ||
3 | local pack = table.pack or function(...) return { n = select("#", ...); ... } end | ||
4 | |||
5 | -- Allow passing a vararg of ciphers, or an array | ||
6 | local setCipherList; setCipherList = ctx.interpose("setCipherList", function (self, ciphers, ...) | ||
7 | if (...) then | ||
8 | local ciphers_t = pack(ciphers, ...) | ||
9 | ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n) | ||
10 | elseif type(ciphers) == "table" then | ||
11 | ciphers = table.concat(ciphers, ":") | ||
12 | end | ||
13 | return setCipherList(self, ciphers) | ||
14 | end) | ||
15 | |||
3 | return ctx | 16 | return ctx |