comparison src/event/ngx_event_openssl.c @ 220:559bc7ec214e NGINX_0_3_57

nginx 0.3.57 *) 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 <http://sysoev.ru>
date Wed, 09 Aug 2006 00:00:00 +0400
parents 8759b346e431
children 29a6403156b0
comparison
equal deleted inserted replaced
219:8045828c3706 220:559bc7ec214e
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