Mercurial > hg > nginx-quic
comparison src/event/ngx_event_openssl.c @ 671:cec32b3753ac release-0.3.57
nginx-0.3.57-RELEASE import
*) Feature: the $ssl_client_serial variable.
*) Bugfix: in the "!-e" operator of the "if" directive.
Thanks to Andrian Budanstov.
*) Bugfix: while a client certificate verification nginx did not send
to a client the required certificates information.
*) Bugfix: the $document_root variable did not support the variables in
the "root" directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 09 Aug 2006 19:59:45 +0000 |
parents | 95d7da23ea53 |
children | 1b60ecc8cdb7 |
comparison
equal
deleted
inserted
replaced
670:ba43c68592d0 | 671:cec32b3753ac |
---|---|
12 typedef struct { | 12 typedef struct { |
13 ngx_str_t engine; | 13 ngx_str_t engine; |
14 } ngx_openssl_conf_t; | 14 } ngx_openssl_conf_t; |
15 | 15 |
16 | 16 |
17 static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); | |
17 static void ngx_ssl_handshake_handler(ngx_event_t *ev); | 18 static void ngx_ssl_handshake_handler(ngx_event_t *ev); |
18 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); | 19 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); |
19 static void ngx_ssl_write_handler(ngx_event_t *wev); | 20 static void ngx_ssl_write_handler(ngx_event_t *wev); |
20 static void ngx_ssl_read_handler(ngx_event_t *rev); | 21 static void ngx_ssl_read_handler(ngx_event_t *rev); |
21 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); | 22 static void ngx_ssl_shutdown_handler(ngx_event_t *ev); |
81 SSL_OP_NO_SSLv2, | 82 SSL_OP_NO_SSLv2, |
82 0, | 83 0, |
83 }; | 84 }; |
84 | 85 |
85 | 86 |
87 int ngx_connection_index; | |
88 | |
89 | |
86 ngx_int_t | 90 ngx_int_t |
87 ngx_ssl_init(ngx_log_t *log) | 91 ngx_ssl_init(ngx_log_t *log) |
88 { | 92 { |
89 SSL_library_init(); | 93 SSL_library_init(); |
90 SSL_load_error_strings(); | 94 SSL_load_error_strings(); |
91 | 95 |
92 #if (NGX_SSL_ENGINE) | 96 #if (NGX_SSL_ENGINE) |
93 ENGINE_load_builtin_engines(); | 97 ENGINE_load_builtin_engines(); |
94 #endif | 98 #endif |
99 | |
100 ngx_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); | |
101 | |
102 if (ngx_connection_index == -1) { | |
103 ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed"); | |
104 return NGX_ERROR; | |
105 } | |
95 | 106 |
96 return NGX_OK; | 107 return NGX_OK; |
97 } | 108 } |
98 | 109 |
99 | 110 |
175 return NGX_OK; | 186 return NGX_OK; |
176 } | 187 } |
177 | 188 |
178 | 189 |
179 ngx_int_t | 190 ngx_int_t |
180 ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert) | 191 ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, |
181 { | 192 ngx_int_t depth) |
193 { | |
194 STACK_OF(X509_NAME) *list; | |
195 | |
196 SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_http_ssl_verify_callback); | |
197 | |
198 SSL_CTX_set_verify_depth(ssl->ctx, depth); | |
199 | |
200 if (cert->len == 0) { | |
201 return NGX_OK; | |
202 } | |
203 | |
182 if (ngx_conf_full_name(cf->cycle, cert) == NGX_ERROR) { | 204 if (ngx_conf_full_name(cf->cycle, cert) == NGX_ERROR) { |
183 return NGX_ERROR; | 205 return NGX_ERROR; |
184 } | 206 } |
185 | 207 |
186 if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) | 208 if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) |
190 "SSL_CTX_load_verify_locations(\"%s\") failed", | 212 "SSL_CTX_load_verify_locations(\"%s\") failed", |
191 cert->data); | 213 cert->data); |
192 return NGX_ERROR; | 214 return NGX_ERROR; |
193 } | 215 } |
194 | 216 |
217 list = SSL_load_client_CA_file((char *) cert->data); | |
218 | |
219 if (list == NULL) { | |
220 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
221 "SSL_load_client_CA_file(\"%s\") failed", cert->data); | |
222 return NGX_ERROR; | |
223 } | |
224 | |
225 /* | |
226 * before 0.9.7h and 0.9.8 SSL_load_client_CA_file() | |
227 * always leaved an error in the error queue | |
228 */ | |
229 | |
230 ERR_clear_error(); | |
231 | |
232 SSL_CTX_set_client_CA_list(ssl->ctx, list); | |
233 | |
195 return NGX_OK; | 234 return NGX_OK; |
235 } | |
236 | |
237 | |
238 static int | |
239 ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store) | |
240 { | |
241 char *subject, *issuer; | |
242 int err, depth; | |
243 X509 *cert; | |
244 X509_NAME *name; | |
245 ngx_connection_t *c; | |
246 ngx_ssl_conn_t *ssl_conn; | |
247 | |
248 ssl_conn = X509_STORE_CTX_get_ex_data(x509_store, | |
249 SSL_get_ex_data_X509_STORE_CTX_idx()); | |
250 | |
251 c = ngx_ssl_get_connection(ssl_conn); | |
252 | |
253 cert = X509_STORE_CTX_get_current_cert(x509_store); | |
254 err = X509_STORE_CTX_get_error(x509_store); | |
255 depth = X509_STORE_CTX_get_error_depth(x509_store); | |
256 | |
257 name = X509_get_subject_name(cert); | |
258 subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)"; | |
259 | |
260 name = X509_get_issuer_name(cert); | |
261 issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)"; | |
262 | |
263 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
264 "verify:%d, error:%d, depth:%d, " | |
265 "subject:\"%s\",issuer: \"%s\"", | |
266 ok, err, depth, subject, issuer); | |
267 | |
268 return 1; | |
196 } | 269 } |
197 | 270 |
198 | 271 |
199 ngx_int_t | 272 ngx_int_t |
200 ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl) | 273 ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl) |
201 { | 274 { |
275 RSA *key; | |
276 | |
202 if (SSL_CTX_need_tmp_RSA(ssl->ctx) == 0) { | 277 if (SSL_CTX_need_tmp_RSA(ssl->ctx) == 0) { |
203 return NGX_OK; | 278 return NGX_OK; |
204 } | 279 } |
205 | 280 |
206 ssl->rsa512_key = RSA_generate_key(512, RSA_F4, NULL, NULL); | 281 key = RSA_generate_key(512, RSA_F4, NULL, NULL); |
207 | 282 |
208 if (ssl->rsa512_key) { | 283 if (key) { |
209 SSL_CTX_set_tmp_rsa(ssl->ctx, ssl->rsa512_key); | 284 SSL_CTX_set_tmp_rsa(ssl->ctx, key); |
285 | |
286 RSA_free(key); | |
287 | |
210 return NGX_OK; | 288 return NGX_OK; |
211 } | 289 } |
212 | 290 |
213 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "RSA_generate_key(512) failed"); | 291 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "RSA_generate_key(512) failed"); |
214 | 292 |
250 if (flags & NGX_SSL_CLIENT) { | 328 if (flags & NGX_SSL_CLIENT) { |
251 SSL_set_connect_state(sc->connection); | 329 SSL_set_connect_state(sc->connection); |
252 | 330 |
253 } else { | 331 } else { |
254 SSL_set_accept_state(sc->connection); | 332 SSL_set_accept_state(sc->connection); |
333 } | |
334 | |
335 if (SSL_set_ex_data(sc->connection, ngx_connection_index, c) == 0) { | |
336 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed"); | |
337 return NGX_ERROR; | |
255 } | 338 } |
256 | 339 |
257 c->ssl = sc; | 340 c->ssl = sc; |
258 | 341 |
259 return NGX_OK; | 342 return NGX_OK; |
1020 void | 1103 void |
1021 ngx_ssl_cleanup_ctx(void *data) | 1104 ngx_ssl_cleanup_ctx(void *data) |
1022 { | 1105 { |
1023 ngx_ssl_t *ssl = data; | 1106 ngx_ssl_t *ssl = data; |
1024 | 1107 |
1025 if (ssl->rsa512_key) { | |
1026 RSA_free(ssl->rsa512_key); | |
1027 } | |
1028 | |
1029 SSL_CTX_free(ssl->ctx); | 1108 SSL_CTX_free(ssl->ctx); |
1030 } | 1109 } |
1031 | 1110 |
1032 | 1111 |
1033 u_char * | 1112 ngx_int_t |
1034 ngx_ssl_get_protocol(ngx_connection_t *c) | 1113 ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) |
1035 { | 1114 { |
1036 return (u_char *) SSL_get_version(c->ssl->connection); | 1115 s->data = (u_char *) SSL_get_version(c->ssl->connection); |
1037 } | 1116 return NGX_OK; |
1038 | 1117 } |
1039 | 1118 |
1040 u_char * | 1119 |
1041 ngx_ssl_get_cipher_name(ngx_connection_t *c) | 1120 ngx_int_t |
1042 { | 1121 ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) |
1043 return (u_char *) SSL_get_cipher_name(c->ssl->connection); | 1122 { |
1123 s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection); | |
1124 return NGX_OK; | |
1044 } | 1125 } |
1045 | 1126 |
1046 | 1127 |
1047 ngx_int_t | 1128 ngx_int_t |
1048 ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) | 1129 ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) |
1053 X509_NAME *name; | 1134 X509_NAME *name; |
1054 | 1135 |
1055 s->len = 0; | 1136 s->len = 0; |
1056 | 1137 |
1057 cert = SSL_get_peer_certificate(c->ssl->connection); | 1138 cert = SSL_get_peer_certificate(c->ssl->connection); |
1058 | |
1059 if (cert == NULL) { | 1139 if (cert == NULL) { |
1060 return NGX_OK; | 1140 return NGX_OK; |
1061 } | 1141 } |
1062 | 1142 |
1063 name = X509_get_subject_name(cert); | 1143 name = X509_get_subject_name(cert); |
1064 | |
1065 if (name == NULL) { | 1144 if (name == NULL) { |
1066 return NGX_ERROR; | 1145 return NGX_ERROR; |
1067 } | 1146 } |
1068 | 1147 |
1069 p = X509_NAME_oneline(name, NULL, 0); | 1148 p = X509_NAME_oneline(name, NULL, 0); |
1094 X509_NAME *name; | 1173 X509_NAME *name; |
1095 | 1174 |
1096 s->len = 0; | 1175 s->len = 0; |
1097 | 1176 |
1098 cert = SSL_get_peer_certificate(c->ssl->connection); | 1177 cert = SSL_get_peer_certificate(c->ssl->connection); |
1099 | |
1100 if (cert == NULL) { | 1178 if (cert == NULL) { |
1101 return NGX_OK; | 1179 return NGX_OK; |
1102 } | 1180 } |
1103 | 1181 |
1104 name = X509_get_issuer_name(cert); | 1182 name = X509_get_issuer_name(cert); |
1105 | |
1106 if (name == NULL) { | 1183 if (name == NULL) { |
1107 return NGX_ERROR; | 1184 return NGX_ERROR; |
1108 } | 1185 } |
1109 | 1186 |
1110 p = X509_NAME_oneline(name, NULL, 0); | 1187 p = X509_NAME_oneline(name, NULL, 0); |
1119 } | 1196 } |
1120 | 1197 |
1121 ngx_memcpy(s->data, p, len); | 1198 ngx_memcpy(s->data, p, len); |
1122 | 1199 |
1123 OPENSSL_free(p); | 1200 OPENSSL_free(p); |
1201 | |
1202 return NGX_OK; | |
1203 } | |
1204 | |
1205 | |
1206 ngx_int_t | |
1207 ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) | |
1208 { | |
1209 size_t len; | |
1210 X509 *cert; | |
1211 BIO *bio; | |
1212 | |
1213 s->len = 0; | |
1214 | |
1215 cert = SSL_get_peer_certificate(c->ssl->connection); | |
1216 if (cert == NULL) { | |
1217 return NGX_OK; | |
1218 } | |
1219 | |
1220 bio = BIO_new(BIO_s_mem()); | |
1221 if (bio == NULL) { | |
1222 return NGX_ERROR; | |
1223 } | |
1224 | |
1225 i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)); | |
1226 len = BIO_pending(bio); | |
1227 | |
1228 s->len = len; | |
1229 s->data = ngx_palloc(pool, len); | |
1230 if (s->data == NULL) { | |
1231 BIO_free(bio); | |
1232 return NGX_ERROR; | |
1233 } | |
1234 | |
1235 BIO_read(bio, s->data, len); | |
1236 BIO_free(bio); | |
1124 | 1237 |
1125 return NGX_OK; | 1238 return NGX_OK; |
1126 } | 1239 } |
1127 | 1240 |
1128 | 1241 |