Sun, 03 Jul 2011 13:13:36 -0700
context: Support ECDH cipher suites, where applicable
0 | 1 | /*-------------------------------------------------------------------------- |
2 | * LuaSec 0.4 | |
3 | * Copyright (C) 2006-2009 Bruno Silvestre | |
4 | * | |
5 | *--------------------------------------------------------------------------*/ | |
6 | ||
7 | #include <string.h> | |
8 | #include <openssl/ssl.h> | |
9 | #include <openssl/err.h> | |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
10 | #include <openssl/x509.h> |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
11 | #include <openssl/x509v3.h> |
0 | 12 | |
13 | #include <lua.h> | |
14 | #include <lauxlib.h> | |
15 | ||
16 | #include "context.h" | |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
17 | #include "ssl.h" |
0 | 18 | |
19 | struct ssl_option_s { | |
20 | const char *name; | |
21 | unsigned long code; | |
22 | }; | |
23 | typedef struct ssl_option_s ssl_option_t; | |
24 | ||
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
25 | /* index into the SSL storage where the context is. |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
26 | * see SSL_CTX_get_ex_data(). |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
27 | */ |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
28 | static int luasec_sslctx_idx = -1; |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
29 | |
28
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
30 | /* The export DH key */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
31 | static DH *dh_512 = NULL; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
32 | /* The larger key (builtin is 2048, caller may specify larger) */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
33 | static DH *dh_larger = NULL; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
34 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
35 | /* Generated via "openssl dhparam -2 -noout -C 512 2>/dev/null" */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
36 | static unsigned char dh512_p[] = { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
37 | 0xE4,0x3F,0x75,0x82,0xAD,0x0B,0x28,0xC7,0xEF,0xCE,0xBC,0x3B, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
38 | 0x14,0xBB,0xA6,0xF4,0xA2,0xE9,0xA6,0x59,0xCF,0x97,0x1C,0x86, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
39 | 0x43,0x3B,0x92,0x4A,0x6B,0x15,0x4B,0x0C,0xAC,0x8F,0xFA,0x43, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
40 | 0xE2,0xA8,0xC3,0x3B,0x7B,0x51,0x1B,0x46,0x21,0xBF,0x8C,0x06, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
41 | 0x6C,0xB1,0x49,0x75,0xC7,0xAC,0x47,0x1D,0x9D,0x64,0xD5,0x99, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
42 | 0x33,0x86,0xAD,0xEB, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
43 | }; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
44 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
45 | /* Generated via "openssl dhparam -2 -noout -C 2048 2>/dev/null" */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
46 | static unsigned char dh2048_p[] = { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
47 | 0x9B,0xF4,0xC5,0x57,0x81,0x8F,0xCF,0x31,0x78,0x95,0x04,0xCD, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
48 | 0xEA,0xCC,0x30,0xEA,0xF7,0xCA,0x76,0xC8,0x8F,0x91,0xEA,0x0E, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
49 | 0x44,0x8D,0xE2,0x63,0x19,0x3B,0x4D,0x04,0xC8,0x7D,0x0D,0xFF, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
50 | 0x3D,0x52,0x76,0x02,0xF3,0xCA,0x1C,0x44,0xAF,0x0E,0xA9,0x59, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
51 | 0x02,0x40,0x75,0xD6,0xED,0x35,0x4D,0x11,0x5B,0x2B,0x73,0x23, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
52 | 0xE5,0x53,0x0B,0x1F,0xB0,0x47,0xC4,0x7F,0x95,0x5D,0xB0,0xD5, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
53 | 0xF3,0xD3,0xAB,0x5F,0x28,0x2B,0xEC,0x2C,0x15,0x0B,0x1B,0x0C, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
54 | 0xD4,0xBE,0x24,0x2F,0xC5,0x07,0x3C,0xE4,0xC5,0xE6,0x16,0x42, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
55 | 0x4C,0x31,0x04,0xBB,0x80,0x96,0xFF,0x64,0x50,0xA4,0xA5,0xB5, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
56 | 0xF5,0x3A,0xBA,0x57,0xE4,0xE6,0xC2,0x23,0x0A,0xB6,0x27,0xC4, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
57 | 0x06,0x01,0x1E,0x98,0x20,0x09,0xC8,0xB7,0x90,0x09,0x86,0x06, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
58 | 0xAA,0x85,0xE7,0x02,0xC8,0xC6,0xD9,0x1D,0xAB,0x17,0xEE,0x78, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
59 | 0x73,0x78,0x88,0x7F,0xA7,0xF2,0x34,0xA7,0xDD,0x02,0x16,0x36, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
60 | 0x0D,0x77,0x16,0x3E,0x95,0xAE,0x02,0xEE,0x36,0x37,0xD5,0x61, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
61 | 0x5D,0xFE,0xC6,0x0B,0xDF,0xCE,0xB9,0x26,0x31,0x6F,0x34,0x92, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
62 | 0xBB,0xBB,0x91,0x29,0x77,0x62,0x1D,0x75,0xA0,0x51,0x8D,0x31, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
63 | 0x4C,0x64,0x4E,0xBF,0xDC,0xE8,0x67,0x17,0x90,0x6A,0x80,0xE9, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
64 | 0xD7,0xD8,0x56,0x4E,0x85,0x21,0x9C,0xFB,0xE6,0x1B,0xD8,0x05, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
65 | 0xFD,0x13,0x77,0x00,0x96,0x2D,0x0C,0x2A,0x95,0x1A,0x08,0x82, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
66 | 0x2E,0xB3,0xE2,0xFC,0xE8,0xA6,0xF1,0x16,0x37,0x57,0x82,0xD6, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
67 | 0xF5,0xAB,0xA9,0x43,0x8F,0x33,0xB0,0x57,0x38,0x6E,0x61,0xD4, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
68 | 0xDD,0xE0,0x1C,0xCB, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
69 | }; |
0 | 70 | |
71 | static ssl_option_t ssl_options[] = { | |
72 | /* OpenSSL 0.9.7 and 0.9.8 */ | |
73 | {"all", SSL_OP_ALL}, | |
74 | {"cipher_server_preference", SSL_OP_CIPHER_SERVER_PREFERENCE}, | |
75 | {"dont_insert_empty_fragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS}, | |
76 | {"ephemeral_rsa", SSL_OP_EPHEMERAL_RSA}, | |
77 | {"netscape_ca_dn_bug", SSL_OP_NETSCAPE_CA_DN_BUG}, | |
78 | {"netscape_challenge_bug", SSL_OP_NETSCAPE_CHALLENGE_BUG}, | |
79 | {"microsoft_big_sslv3_buffer", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER}, | |
80 | {"microsoft_sess_id_bug", SSL_OP_MICROSOFT_SESS_ID_BUG}, | |
81 | {"msie_sslv2_rsa_padding", SSL_OP_MSIE_SSLV2_RSA_PADDING}, | |
82 | {"netscape_demo_cipher_change_bug", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG}, | |
83 | {"netscape_reuse_cipher_change_bug", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG}, | |
84 | {"no_session_resumption_on_renegotiation", | |
85 | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION}, | |
86 | {"no_sslv2", SSL_OP_NO_SSLv2}, | |
87 | {"no_sslv3", SSL_OP_NO_SSLv3}, | |
88 | {"no_tlsv1", SSL_OP_NO_TLSv1}, | |
89 | {"pkcs1_check_1", SSL_OP_PKCS1_CHECK_1}, | |
90 | {"pkcs1_check_2", SSL_OP_PKCS1_CHECK_2}, | |
91 | {"single_dh_use", SSL_OP_SINGLE_DH_USE}, | |
92 | {"ssleay_080_client_dh_bug", SSL_OP_SSLEAY_080_CLIENT_DH_BUG}, | |
93 | {"sslref2_reuse_cert_type_bug", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG}, | |
94 | {"tls_block_padding_bug", SSL_OP_TLS_BLOCK_PADDING_BUG}, | |
95 | {"tls_d5_bug", SSL_OP_TLS_D5_BUG}, | |
96 | {"tls_rollback_bug", SSL_OP_TLS_ROLLBACK_BUG}, | |
97 | /* OpenSSL 0.9.8 only */ | |
98 | #if OPENSSL_VERSION_NUMBER > 0x00908000L | |
99 | {"cookie_exchange", SSL_OP_COOKIE_EXCHANGE}, | |
100 | {"no_query_mtu", SSL_OP_NO_QUERY_MTU}, | |
101 | {"single_ecdh_use", SSL_OP_SINGLE_ECDH_USE}, | |
102 | #endif | |
103 | /* OpenSSL 0.9.8f and above */ | |
104 | #if defined(SSL_OP_NO_TICKET) | |
105 | {"no_ticket", SSL_OP_NO_TICKET}, | |
106 | #endif | |
1
5f89e535765a
context.c: Add no_compression option for when supported
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
107 | #if defined(SSL_OP_NO_COMPRESSION) |
5f89e535765a
context.c: Add no_compression option for when supported
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
108 | {"no_compression", SSL_OP_NO_COMPRESSION}, |
5f89e535765a
context.c: Add no_compression option for when supported
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
109 | #endif |
0 | 110 | {NULL, 0L} |
111 | }; | |
112 | ||
113 | /*--------------------------- Auxiliary Functions ----------------------------*/ | |
114 | ||
115 | /** | |
116 | * Return the context. | |
117 | */ | |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
118 | p_context checkctx(lua_State *L, int idx) |
0 | 119 | { |
120 | return (p_context)luaL_checkudata(L, idx, "SSL:Context"); | |
121 | } | |
122 | ||
123 | /** | |
124 | * Prepare the SSL options flag. | |
125 | */ | |
126 | static int set_option_flag(const char *opt, unsigned long *flag) | |
127 | { | |
128 | ssl_option_t *p; | |
129 | for (p = ssl_options; p->name; p++) { | |
130 | if (!strcmp(opt, p->name)) { | |
131 | *flag |= p->code; | |
132 | return 1; | |
133 | } | |
134 | } | |
135 | return 0; | |
136 | } | |
137 | ||
138 | /** | |
139 | * Find the protocol. | |
140 | */ | |
141 | static SSL_METHOD* str2method(const char *method) | |
142 | { | |
143 | if (!strcmp(method, "sslv3")) return SSLv3_method(); | |
144 | if (!strcmp(method, "tlsv1")) return TLSv1_method(); | |
145 | if (!strcmp(method, "sslv23")) return SSLv23_method(); | |
146 | return NULL; | |
147 | } | |
148 | ||
149 | /** | |
150 | * Prepare the SSL handshake verify flag. | |
151 | */ | |
152 | static int set_verify_flag(const char *str, int *flag) | |
153 | { | |
154 | if (!strcmp(str, "none")) { | |
155 | *flag |= SSL_VERIFY_NONE; | |
156 | return 1; | |
157 | } | |
158 | if (!strcmp(str, "peer")) { | |
159 | *flag |= SSL_VERIFY_PEER; | |
160 | return 1; | |
161 | } | |
162 | if (!strcmp(str, "client_once")) { | |
163 | *flag |= SSL_VERIFY_CLIENT_ONCE; | |
164 | return 1; | |
165 | } | |
166 | if (!strcmp(str, "fail_if_no_peer_cert")) { | |
167 | *flag |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; | |
168 | return 1; | |
169 | } | |
170 | return 0; | |
171 | } | |
172 | ||
173 | /** | |
174 | * Password callback for reading the private key. | |
175 | */ | |
176 | static int passwd_cb(char *buf, int size, int flag, void *udata) | |
177 | { | |
178 | lua_State *L = (lua_State*)udata; | |
179 | switch (lua_type(L, 3)) { | |
180 | case LUA_TFUNCTION: | |
181 | lua_pushvalue(L, 3); | |
182 | lua_call(L, 0, 1); | |
183 | if (lua_type(L, -1) != LUA_TSTRING) | |
184 | return 0; | |
185 | /* fallback */ | |
186 | case LUA_TSTRING: | |
187 | strncpy(buf, lua_tostring(L, -1), size); | |
188 | buf[size-1] = '\0'; | |
189 | return (int)strlen(buf); | |
190 | } | |
191 | return 0; | |
192 | } | |
193 | ||
28
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
194 | static DH *get_dh(const unsigned char *p, int len) |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
195 | { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
196 | DH *dh = NULL; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
197 | static unsigned char g[] = { 0x02 }; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
198 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
199 | if ((dh = DH_new()) == NULL) return NULL; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
200 | dh->p = BN_bin2bn(p, len, NULL); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
201 | dh->g = BN_bin2bn(g, sizeof(g), NULL); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
202 | if (dh->p == NULL || dh->g == NULL) { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
203 | DH_free(dh); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
204 | return NULL; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
205 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
206 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
207 | return dh; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
208 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
209 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
210 | /** |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
211 | * DH parameter callback |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
212 | */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
213 | static DH *dh_param_cb(SSL *ssl, int is_export, int keylength) |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
214 | { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
215 | /* Logic in postfix and dovecot, but we're using a 2048-bit group... */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
216 | if (is_export && keylength == 512) { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
217 | if (dh_512 == NULL) { dh_512 = get_dh(dh512_p, sizeof(dh512_p)); } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
218 | return dh_512; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
219 | } else { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
220 | if (dh_larger == NULL) { dh_larger = get_dh(dh2048_p, sizeof(dh2048_p)); } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
221 | return dh_larger; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
222 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
223 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
224 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
225 | |
0 | 226 | /*------------------------------ Lua Functions -------------------------------*/ |
227 | ||
228 | /** | |
229 | * Create a SSL context. | |
230 | */ | |
231 | static int create(lua_State *L) | |
232 | { | |
233 | p_context ctx; | |
234 | SSL_METHOD *method; | |
235 | ||
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
236 | if (luasec_sslctx_idx == -1) { |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
237 | luasec_sslctx_idx = SSL_CTX_get_ex_new_index(0, "luasec sslctx context", NULL, NULL, NULL); |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
238 | if (luasec_sslctx_idx == -1) { |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
239 | lua_pushnil(L); |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
240 | lua_pushstring(L, "error creating luasec SSL index"); |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
241 | return 2; |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
242 | } |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
243 | } |
0 | 244 | method = str2method(luaL_checkstring(L, 1)); |
245 | if (!method) { | |
246 | lua_pushnil(L); | |
247 | lua_pushstring(L, "invalid protocol"); | |
248 | return 2; | |
249 | } | |
250 | ctx = (p_context) lua_newuserdata(L, sizeof(t_context)); | |
251 | if (!ctx) { | |
252 | lua_pushnil(L); | |
253 | lua_pushstring(L, "error creating context"); | |
254 | return 2; | |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
255 | } |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
256 | ctx->L = L; |
0 | 257 | ctx->context = SSL_CTX_new(method); |
258 | if (!ctx->context) { | |
259 | lua_pushnil(L); | |
260 | lua_pushstring(L, "error creating context"); | |
261 | return 2; | |
262 | } | |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
263 | ctx->verify_flags = LUASEC_VERIFY_FLAGS_NONE; |
0 | 264 | ctx->mode = MD_CTX_INVALID; |
265 | /* No session support */ | |
266 | SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF); | |
28
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
267 | /* |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
268 | * Support ephemeral diffie-hellman key exchange. This is only needed |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
269 | * for server mode, but clearer to put it here rather than set_mode. |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
270 | */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
271 | SSL_CTX_set_tmp_dh_callback(ctx->context, dh_param_cb); |
42
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
272 | #if defined(SSL_CTX_set_tmp_ecdh) |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
273 | /* |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
274 | * Support ECDH parameters. This uses the 384 bit prime field from |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
275 | * NIST. |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
276 | */ |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
277 | SSL_CTX_set_tmp_ecdh(ctx->context, EC_KEY_new_by_curve_name(NID_secp384r1)); |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
278 | #endif |
b6271d3bae0b
context: Support ECDH cipher suites, where applicable
Paul Aurich <paul@darkrain42.org>
parents:
41
diff
changeset
|
279 | |
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
280 | SSL_CTX_set_ex_data(ctx->context, luasec_sslctx_idx, ctx); |
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
281 | |
0 | 282 | luaL_getmetatable(L, "SSL:Context"); |
283 | lua_setmetatable(L, -2); | |
284 | return 1; | |
285 | } | |
286 | ||
287 | /** | |
288 | * Load the trusting certificates. | |
289 | */ | |
290 | static int load_locations(lua_State *L) | |
291 | { | |
292 | SSL_CTX *ctx = ctx_getcontext(L, 1); | |
293 | const char *cafile = luaL_optstring(L, 2, NULL); | |
294 | const char *capath = luaL_optstring(L, 3, NULL); | |
295 | if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1) { | |
296 | lua_pushboolean(L, 0); | |
297 | lua_pushfstring(L, "error loading CA locations (%s)", | |
298 | ERR_reason_error_string(ERR_get_error())); | |
299 | return 2; | |
300 | } | |
301 | lua_pushboolean(L, 1); | |
302 | return 1; | |
303 | } | |
304 | ||
305 | /** | |
306 | * Load the certificate file. | |
307 | */ | |
308 | static int load_cert(lua_State *L) | |
309 | { | |
310 | SSL_CTX *ctx = ctx_getcontext(L, 1); | |
311 | const char *filename = luaL_checkstring(L, 2); | |
312 | if (SSL_CTX_use_certificate_chain_file(ctx, filename) != 1) { | |
313 | lua_pushboolean(L, 0); | |
314 | lua_pushfstring(L, "error loading certificate (%s)", | |
315 | ERR_reason_error_string(ERR_get_error())); | |
316 | return 2; | |
317 | } | |
318 | lua_pushboolean(L, 1); | |
319 | return 1; | |
320 | } | |
321 | ||
322 | /** | |
323 | * Load the key file -- only in PEM format. | |
324 | */ | |
325 | static int load_key(lua_State *L) | |
326 | { | |
327 | int ret = 1; | |
328 | SSL_CTX *ctx = ctx_getcontext(L, 1); | |
329 | const char *filename = luaL_checkstring(L, 2); | |
330 | switch (lua_type(L, 3)) { | |
331 | case LUA_TSTRING: | |
332 | case LUA_TFUNCTION: | |
333 | SSL_CTX_set_default_passwd_cb(ctx, passwd_cb); | |
334 | SSL_CTX_set_default_passwd_cb_userdata(ctx, L); | |
335 | /* fallback */ | |
336 | case LUA_TNIL: | |
337 | if (SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM) == 1) | |
338 | lua_pushboolean(L, 1); | |
339 | else { | |
340 | ret = 2; | |
341 | lua_pushboolean(L, 0); | |
342 | lua_pushfstring(L, "error loading private key (%s)", | |
343 | ERR_reason_error_string(ERR_get_error())); | |
344 | } | |
345 | SSL_CTX_set_default_passwd_cb(ctx, NULL); | |
346 | SSL_CTX_set_default_passwd_cb_userdata(ctx, NULL); | |
347 | break; | |
348 | default: | |
349 | lua_pushstring(L, "invalid callback value"); | |
350 | lua_error(L); | |
351 | } | |
352 | return ret; | |
353 | } | |
354 | ||
355 | /** | |
28
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
356 | * Load a DH params files. This is a global LuaSec thing. |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
357 | */ |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
358 | static int load_dhparams(lua_State *L) |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
359 | { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
360 | const char *filename = luaL_checkstring(L, 1); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
361 | FILE *paramfile; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
362 | DH *dh; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
363 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
364 | paramfile = fopen(filename, "r"); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
365 | if (!paramfile) { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
366 | lua_pushboolean(L, 0); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
367 | lua_pushfstring(L, "error reading dh param file %s: %s", filename, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
368 | strerror(errno)); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
369 | return 2; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
370 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
371 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
372 | dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
373 | fclose(paramfile); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
374 | if (!dh) { |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
375 | lua_pushboolean(L, 0); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
376 | lua_pushfstring(L, "error loading dh param file %s: %s", filename, |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
377 | ERR_reason_error_string(ERR_get_error())); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
378 | return 2; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
379 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
380 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
381 | if (dh_larger) |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
382 | DH_free(dh_larger); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
383 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
384 | dh_larger = dh; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
385 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
386 | lua_pushboolean(L, 1); |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
387 | return 1; |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
388 | } |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
389 | |
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
390 | /** |
0 | 391 | * Set the cipher list. |
392 | */ | |
393 | static int set_cipher(lua_State *L) | |
394 | { | |
395 | SSL_CTX *ctx = ctx_getcontext(L, 1); | |
396 | const char *list = luaL_checkstring(L, 2); | |
397 | if (SSL_CTX_set_cipher_list(ctx, list) != 1) { | |
398 | lua_pushboolean(L, 0); | |
399 | lua_pushfstring(L, "error setting cipher list (%s)", | |
400 | ERR_reason_error_string(ERR_get_error())); | |
401 | return 2; | |
402 | } | |
403 | lua_pushboolean(L, 1); | |
404 | return 1; | |
405 | } | |
406 | ||
407 | /** | |
408 | * Set the depth for certificate checking. | |
409 | */ | |
410 | static int set_depth(lua_State *L) | |
411 | { | |
412 | SSL_CTX *ctx = ctx_getcontext(L, 1); | |
413 | SSL_CTX_set_verify_depth(ctx, luaL_checkint(L, 2)); | |
414 | lua_pushboolean(L, 1); | |
415 | return 1; | |
416 | } | |
417 | ||
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
418 | static void |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
419 | luasec_push_cert_error(lua_State *L, int ref, int depth, int err) |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
420 | { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
421 | int created = 0; |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
422 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
423 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
424 | lua_rawgeti(L, -1, depth + 1); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
425 | if (!lua_istable(L, -1)) { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
426 | /* If the table doesn't exist, create it */ |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
427 | created = 1; |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
428 | lua_pop(L, 1); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
429 | lua_newtable(L); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
430 | } |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
431 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
432 | lua_pushstring(L, X509_verify_cert_error_string(err)); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
433 | lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
434 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
435 | if (created) { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
436 | lua_rawseti(L, -2, depth + 1); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
437 | lua_pop(L, 1); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
438 | } else |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
439 | lua_pop(L, 2); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
440 | } |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
441 | |
30
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
442 | int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) |
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
443 | { |
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
444 | SSL_CTX *context; |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
445 | SSL *ssl; |
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
446 | p_context l_ctx; |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
447 | p_ssl l_ssl; |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
448 | int err, depth; |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
449 | |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
450 | /* Short-circuit optimization */ |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
451 | if (preverify_ok) |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
452 | return 1; |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
453 | |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
454 | ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); |
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
455 | context = ssl->ctx; |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
456 | l_ssl = SSL_get_ex_data(ssl, luasec_ssl_idx); |
38
4ecd7b0e67ea
Clean up the ex_data callers
Paul Aurich <paul@darkrain42.org>
parents:
36
diff
changeset
|
457 | l_ctx = SSL_CTX_get_ex_data(context, luasec_sslctx_idx); |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
458 | |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
459 | err = X509_STORE_CTX_get_error(x509_ctx); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
460 | depth = X509_STORE_CTX_get_error_depth(x509_ctx); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
461 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
462 | if (err != X509_V_OK) { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
463 | if (l_ssl->t_cert_errors == LUA_NOREF) { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
464 | lua_newtable(l_ctx->L); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
465 | l_ssl->t_cert_errors = luaL_ref(l_ctx->L, LUA_REGISTRYINDEX); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
466 | } |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
467 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
468 | luasec_push_cert_error(l_ctx->L, l_ssl->t_cert_errors, depth, err); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
469 | } |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
470 | |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
471 | return (l_ctx->verify_flags & LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE ? 1 : preverify_ok); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
472 | } |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
473 | |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
474 | static int luasec_verify(X509_STORE_CTX *x509_ctx, void *ptr) |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
475 | { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
476 | p_context ctx = ptr; |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
477 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
478 | if (ctx->verify_flags & LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE) { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
479 | X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509_ctx); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
480 | if (param) { |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
481 | X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER); |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
482 | X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER); |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
483 | } |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
484 | } |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
485 | |
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
486 | return X509_verify_cert(x509_ctx); |
30
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
487 | } |
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
488 | |
0 | 489 | /** |
490 | * Set the handshake verify options. | |
491 | */ | |
492 | static int set_verify(lua_State *L) | |
493 | { | |
494 | int i; | |
36
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
495 | int flag = 0, vflag = 0; |
30
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
496 | int ignore_errors = 0; |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
497 | p_context ctx = checkctx(L, 1); |
0 | 498 | int max = lua_gettop(L); |
499 | /* any flag? */ | |
500 | if (max > 1) { | |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
501 | ctx->verify_flags = LUASEC_VERIFY_FLAGS_NONE; |
0 | 502 | for (i = 2; i <= max; i++) { |
30
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
503 | const char *s = luaL_checkstring(L, i); |
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
504 | if (!strcmp(s, "continue")) { |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
505 | ctx->verify_flags |= LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE; |
30
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
506 | ignore_errors = 1; |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
507 | } else if (!strcmp(s, "ignore_purpose")) { |
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
508 | ctx->verify_flags |= LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE; |
36
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
509 | } else if (!strcmp(s, "crl_check")) { |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
510 | vflag |= X509_V_FLAG_CRL_CHECK; |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
511 | } else if (!strcmp(s, "crl_check_chain")) { |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
512 | vflag |= X509_V_FLAG_CRL_CHECK_ALL; |
30
36ed99e1ce1e
ssl.core, context: Add ability to verify and continue, retrieve verification result
Paul Aurich <paul@darkrain42.org>
parents:
28
diff
changeset
|
513 | } else if (!set_verify_flag(s, &flag)) { |
0 | 514 | lua_pushboolean(L, 0); |
515 | lua_pushstring(L, "invalid verify option"); | |
516 | return 2; | |
517 | } | |
518 | } | |
34
510432315106
verify: Flag to ignore 'invalid purpose' errors on end cert
Paul Aurich <paul@darkrain42.org>
parents:
30
diff
changeset
|
519 | SSL_CTX_set_verify(ctx->context, flag, ctx->verify_flags ? verify_cb : NULL); |
41
e26f1f91118a
Fix the verification function so it doesn't pass for everyone on invalid purpose errors.
Paul Aurich <paul@darkrain42.org>
parents:
38
diff
changeset
|
520 | SSL_CTX_set_cert_verify_callback(ctx->context, luasec_verify, ctx); |
36
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
521 | if(vflag) |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
522 | { |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
523 | X509_STORE *store = SSL_CTX_get_cert_store(ctx->context); |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
524 | X509_STORE_set_flags(store, vflag); |
96f23601ce7a
context.c: Add crl_check and crl_check_chain verify options
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
525 | } |
0 | 526 | } |
527 | lua_pushboolean(L, 1); | |
528 | return 1; | |
529 | } | |
530 | ||
531 | /** | |
532 | * Set the protocol options. | |
533 | */ | |
534 | static int set_options(lua_State *L) | |
535 | { | |
536 | int i; | |
537 | unsigned long flag = 0L; | |
538 | SSL_CTX *ctx = ctx_getcontext(L, 1); | |
539 | int max = lua_gettop(L); | |
540 | /* any option? */ | |
541 | if (max > 1) { | |
542 | for (i = 2; i <= max; i++) { | |
543 | if (!set_option_flag(luaL_checkstring(L, i), &flag)) { | |
544 | lua_pushboolean(L, 0); | |
545 | lua_pushstring(L, "invalid option"); | |
546 | return 2; | |
547 | } | |
548 | } | |
549 | SSL_CTX_set_options(ctx, flag); | |
550 | } | |
551 | lua_pushboolean(L, 1); | |
552 | return 1; | |
553 | } | |
554 | ||
555 | /** | |
556 | * Set the context mode. | |
557 | */ | |
558 | static int set_mode(lua_State *L) | |
559 | { | |
560 | p_context ctx = checkctx(L, 1); | |
561 | const char *str = luaL_checkstring(L, 2); | |
562 | if (!strcmp("server", str)) { | |
563 | ctx->mode = MD_CTX_SERVER; | |
564 | lua_pushboolean(L, 1); | |
565 | return 1; | |
566 | } | |
567 | if(!strcmp("client", str)) { | |
568 | ctx->mode = MD_CTX_CLIENT; | |
569 | lua_pushboolean(L, 1); | |
570 | return 1; | |
571 | } | |
572 | lua_pushboolean(L, 0); | |
573 | lua_pushstring(L, "invalid mode"); | |
574 | return 1; | |
575 | } | |
576 | ||
577 | /** | |
578 | * Return a pointer to SSL_CTX structure. | |
579 | */ | |
580 | static int raw_ctx(lua_State *L) | |
581 | { | |
582 | p_context ctx = checkctx(L, 1); | |
583 | lua_pushlightuserdata(L, (void*)ctx->context); | |
584 | return 1; | |
585 | } | |
586 | ||
587 | /** | |
588 | * Package functions | |
589 | */ | |
590 | static luaL_Reg funcs[] = { | |
591 | {"create", create}, | |
592 | {"locations", load_locations}, | |
593 | {"loadcert", load_cert}, | |
594 | {"loadkey", load_key}, | |
595 | {"setcipher", set_cipher}, | |
596 | {"setdepth", set_depth}, | |
597 | {"setverify", set_verify}, | |
598 | {"setoptions", set_options}, | |
599 | {"setmode", set_mode}, | |
600 | {"rawcontext", raw_ctx}, | |
28
8c61b29d87ec
context: support for diffie-hellman key exchange
Paul Aurich <paul@darkrain42.org>
parents:
1
diff
changeset
|
601 | {"loaddhparams", load_dhparams}, |
0 | 602 | {NULL, NULL} |
603 | }; | |
604 | ||
605 | /*-------------------------------- Metamethods -------------------------------*/ | |
606 | ||
607 | /** | |
608 | * Collect SSL context -- GC metamethod. | |
609 | */ | |
610 | static int meth_destroy(lua_State *L) | |
611 | { | |
612 | p_context ctx = checkctx(L, 1); | |
613 | if (ctx->context) { | |
614 | SSL_CTX_free(ctx->context); | |
615 | ctx->context = NULL; | |
616 | } | |
617 | return 0; | |
618 | } | |
619 | ||
620 | /** | |
621 | * Object information -- tostring metamethod. | |
622 | */ | |
623 | static int meth_tostring(lua_State *L) | |
624 | { | |
625 | p_context ctx = checkctx(L, 1); | |
626 | lua_pushfstring(L, "SSL context: %p", ctx); | |
627 | return 1; | |
628 | } | |
629 | ||
630 | /** | |
631 | * Context metamethods. | |
632 | */ | |
633 | static luaL_Reg meta[] = { | |
634 | {"__gc", meth_destroy}, | |
635 | {"__tostring", meth_tostring}, | |
636 | {NULL, NULL} | |
637 | }; | |
638 | ||
639 | ||
640 | /*----------------------------- Public Functions ---------------------------*/ | |
641 | ||
642 | /** | |
643 | * Retrieve the SSL context from the Lua stack. | |
644 | */ | |
645 | SSL_CTX* ctx_getcontext(lua_State *L, int idx) | |
646 | { | |
647 | p_context ctx = checkctx(L, idx); | |
648 | return ctx->context; | |
649 | } | |
650 | ||
651 | /** | |
652 | * Retrieve the mode from the context in the Lua stack. | |
653 | */ | |
654 | char ctx_getmode(lua_State *L, int idx) | |
655 | { | |
656 | p_context ctx = checkctx(L, idx); | |
657 | return ctx->mode; | |
658 | } | |
659 | ||
660 | /*------------------------------ Initialization ------------------------------*/ | |
661 | ||
662 | /** | |
663 | * Registre the module. | |
664 | */ | |
665 | int luaopen_ssl_context(lua_State *L) | |
666 | { | |
667 | luaL_newmetatable(L, "SSL:Context"); | |
668 | luaL_register(L, NULL, meta); | |
669 | luaL_register(L, "ssl.context", funcs); | |
670 | return 1; | |
671 | } |