tls_internal.c
Go to the documentation of this file.
00001 /*
00002  * TLS interface functions and an internal TLS implementation
00003  * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  *
00014  * This file interface functions for hostapd/wpa_supplicant to use the
00015  * integrated TLSv1 implementation.
00016  */
00017 
00018 #include "includes.h"
00019 
00020 #include "common.h"
00021 #include "tls.h"
00022 #include "tls/tlsv1_client.h"
00023 #include "tls/tlsv1_server.h"
00024 
00025 
00026 static int tls_ref_count = 0;
00027 
00028 struct tls_global {
00029         int server;
00030         struct tlsv1_credentials *server_cred;
00031         int check_crl;
00032 };
00033 
00034 struct tls_connection {
00035         struct tlsv1_client *client;
00036         struct tlsv1_server *server;
00037 };
00038 
00039 
00040 void * tls_init(const struct tls_config *conf)
00041 {
00042         struct tls_global *global;
00043 
00044         if (tls_ref_count == 0) {
00045 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00046                 if (tlsv1_client_global_init())
00047                         return NULL;
00048 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00049 #ifdef CONFIG_TLS_INTERNAL_SERVER
00050                 if (tlsv1_server_global_init())
00051                         return NULL;
00052 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00053         }
00054         tls_ref_count++;
00055 
00056         global = os_zalloc(sizeof(*global));
00057         if (global == NULL)
00058                 return NULL;
00059 
00060         return global;
00061 }
00062 
00063 void tls_deinit(void *ssl_ctx)
00064 {
00065         struct tls_global *global = ssl_ctx;
00066         tls_ref_count--;
00067         if (tls_ref_count == 0) {
00068 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00069                 tlsv1_client_global_deinit();
00070 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00071 #ifdef CONFIG_TLS_INTERNAL_SERVER
00072                 tlsv1_cred_free(global->server_cred);
00073                 tlsv1_server_global_deinit();
00074 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00075         }
00076         os_free(global);
00077 }
00078 
00079 
00080 int tls_get_errors(void *tls_ctx)
00081 {
00082         return 0;
00083 }
00084 
00085 
00086 struct tls_connection * tls_connection_init(void *tls_ctx)
00087 {
00088         struct tls_connection *conn;
00089         struct tls_global *global = tls_ctx;
00090 
00091         conn = os_zalloc(sizeof(*conn));
00092         if (conn == NULL)
00093                 return NULL;
00094 
00095 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00096         if (!global->server) {
00097                 conn->client = tlsv1_client_init();
00098                 if (conn->client == NULL) {
00099                         os_free(conn);
00100                         return NULL;
00101                 }
00102         }
00103 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00104 #ifdef CONFIG_TLS_INTERNAL_SERVER
00105         if (global->server) {
00106                 conn->server = tlsv1_server_init(global->server_cred);
00107                 if (conn->server == NULL) {
00108                         os_free(conn);
00109                         return NULL;
00110                 }
00111         }
00112 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00113 
00114         return conn;
00115 }
00116 
00117 
00118 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
00119 {
00120         if (conn == NULL)
00121                 return;
00122 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00123         if (conn->client)
00124                 tlsv1_client_deinit(conn->client);
00125 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00126 #ifdef CONFIG_TLS_INTERNAL_SERVER
00127         if (conn->server)
00128                 tlsv1_server_deinit(conn->server);
00129 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00130         os_free(conn);
00131 }
00132 
00133 
00134 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
00135 {
00136 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00137         if (conn->client)
00138                 return tlsv1_client_established(conn->client);
00139 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00140 #ifdef CONFIG_TLS_INTERNAL_SERVER
00141         if (conn->server)
00142                 return tlsv1_server_established(conn->server);
00143 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00144         return 0;
00145 }
00146 
00147 
00148 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
00149 {
00150 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00151         if (conn->client)
00152                 return tlsv1_client_shutdown(conn->client);
00153 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00154 #ifdef CONFIG_TLS_INTERNAL_SERVER
00155         if (conn->server)
00156                 return tlsv1_server_shutdown(conn->server);
00157 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00158         return -1;
00159 }
00160 
00161 
00162 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
00163                               const struct tls_connection_params *params)
00164 {
00165 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00166         struct tlsv1_credentials *cred;
00167 
00168         if (conn->client == NULL)
00169                 return -1;
00170 
00171         cred = tlsv1_cred_alloc();
00172         if (cred == NULL)
00173                 return -1;
00174 
00175         if (tlsv1_set_ca_cert(cred, params->ca_cert,
00176                               params->ca_cert_blob, params->ca_cert_blob_len,
00177                               params->ca_path)) {
00178                 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
00179                            "certificates");
00180                 tlsv1_cred_free(cred);
00181                 return -1;
00182         }
00183 
00184         if (tlsv1_set_cert(cred, params->client_cert,
00185                            params->client_cert_blob,
00186                            params->client_cert_blob_len)) {
00187                 wpa_printf(MSG_INFO, "TLS: Failed to configure client "
00188                            "certificate");
00189                 tlsv1_cred_free(cred);
00190                 return -1;
00191         }
00192 
00193         if (tlsv1_set_private_key(cred, params->private_key,
00194                                   params->private_key_passwd,
00195                                   params->private_key_blob,
00196                                   params->private_key_blob_len)) {
00197                 wpa_printf(MSG_INFO, "TLS: Failed to load private key");
00198                 tlsv1_cred_free(cred);
00199                 return -1;
00200         }
00201 
00202         if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
00203                                params->dh_blob_len)) {
00204                 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
00205                 tlsv1_cred_free(cred);
00206                 return -1;
00207         }
00208 
00209         if (tlsv1_client_set_cred(conn->client, cred) < 0) {
00210                 tlsv1_cred_free(cred);
00211                 return -1;
00212         }
00213 
00214         return 0;
00215 #else /* CONFIG_TLS_INTERNAL_CLIENT */
00216         return -1;
00217 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00218 }
00219 
00220 
00221 int tls_global_set_params(void *tls_ctx,
00222                           const struct tls_connection_params *params)
00223 {
00224 #ifdef CONFIG_TLS_INTERNAL_SERVER
00225         struct tls_global *global = tls_ctx;
00226         struct tlsv1_credentials *cred;
00227 
00228         /* Currently, global parameters are only set when running in server
00229          * mode. */
00230         global->server = 1;
00231         tlsv1_cred_free(global->server_cred);
00232         global->server_cred = cred = tlsv1_cred_alloc();
00233         if (cred == NULL)
00234                 return -1;
00235 
00236         if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob,
00237                               params->ca_cert_blob_len, params->ca_path)) {
00238                 wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
00239                            "certificates");
00240                 return -1;
00241         }
00242 
00243         if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob,
00244                            params->client_cert_blob_len)) {
00245                 wpa_printf(MSG_INFO, "TLS: Failed to configure server "
00246                            "certificate");
00247                 return -1;
00248         }
00249 
00250         if (tlsv1_set_private_key(cred, params->private_key,
00251                                   params->private_key_passwd,
00252                                   params->private_key_blob,
00253                                   params->private_key_blob_len)) {
00254                 wpa_printf(MSG_INFO, "TLS: Failed to load private key");
00255                 return -1;
00256         }
00257 
00258         if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
00259                                params->dh_blob_len)) {
00260                 wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
00261                 return -1;
00262         }
00263 
00264         return 0;
00265 #else /* CONFIG_TLS_INTERNAL_SERVER */
00266         return -1;
00267 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00268 }
00269 
00270 
00271 int tls_global_set_verify(void *tls_ctx, int check_crl)
00272 {
00273         struct tls_global *global = tls_ctx;
00274         global->check_crl = check_crl;
00275         return 0;
00276 }
00277 
00278 
00279 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
00280                               int verify_peer)
00281 {
00282 #ifdef CONFIG_TLS_INTERNAL_SERVER
00283         if (conn->server)
00284                 return tlsv1_server_set_verify(conn->server, verify_peer);
00285 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00286         return -1;
00287 }
00288 
00289 
00290 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
00291                           int tls_ia)
00292 {
00293         return -1;
00294 }
00295 
00296 
00297 int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
00298                             struct tls_keys *keys)
00299 {
00300 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00301         if (conn->client)
00302                 return tlsv1_client_get_keys(conn->client, keys);
00303 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00304 #ifdef CONFIG_TLS_INTERNAL_SERVER
00305         if (conn->server)
00306                 return tlsv1_server_get_keys(conn->server, keys);
00307 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00308         return -1;
00309 }
00310 
00311 
00312 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
00313                        const char *label, int server_random_first,
00314                        u8 *out, size_t out_len)
00315 {
00316 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00317         if (conn->client) {
00318                 return tlsv1_client_prf(conn->client, label,
00319                                         server_random_first,
00320                                         out, out_len);
00321         }
00322 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00323 #ifdef CONFIG_TLS_INTERNAL_SERVER
00324         if (conn->server) {
00325                 return tlsv1_server_prf(conn->server, label,
00326                                         server_random_first,
00327                                         out, out_len);
00328         }
00329 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00330         return -1;
00331 }
00332 
00333 
00334 struct wpabuf * tls_connection_handshake(void *tls_ctx,
00335                                          struct tls_connection *conn,
00336                                          const struct wpabuf *in_data,
00337                                          struct wpabuf **appl_data)
00338 {
00339 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00340         u8 *res, *ad;
00341         size_t res_len, ad_len;
00342         struct wpabuf *out;
00343 
00344         if (conn->client == NULL)
00345                 return NULL;
00346 
00347         ad = NULL;
00348         res = tlsv1_client_handshake(conn->client,
00349                                      in_data ? wpabuf_head(in_data) : NULL,
00350                                      in_data ? wpabuf_len(in_data) : 0,
00351                                      &res_len, &ad, &ad_len);
00352         if (res == NULL)
00353                 return NULL;
00354         out = wpabuf_alloc_ext_data(res, res_len);
00355         if (out == NULL) {
00356                 os_free(res);
00357                 os_free(ad);
00358                 return NULL;
00359         }
00360         if (appl_data) {
00361                 if (ad) {
00362                         *appl_data = wpabuf_alloc_ext_data(ad, ad_len);
00363                         if (*appl_data == NULL)
00364                                 os_free(ad);
00365                 } else
00366                         *appl_data = NULL;
00367         } else
00368                 os_free(ad);
00369 
00370         return out;
00371 #else /* CONFIG_TLS_INTERNAL_CLIENT */
00372         return NULL;
00373 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00374 }
00375 
00376 
00377 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
00378                                                 struct tls_connection *conn,
00379                                                 const struct wpabuf *in_data,
00380                                                 struct wpabuf **appl_data)
00381 {
00382 #ifdef CONFIG_TLS_INTERNAL_SERVER
00383         u8 *res;
00384         size_t res_len;
00385         struct wpabuf *out;
00386 
00387         if (conn->server == NULL)
00388                 return NULL;
00389 
00390         if (appl_data)
00391                 *appl_data = NULL;
00392 
00393         res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data),
00394                                      wpabuf_len(in_data), &res_len);
00395         if (res == NULL && tlsv1_server_established(conn->server))
00396                 return wpabuf_alloc(0);
00397         if (res == NULL)
00398                 return NULL;
00399         out = wpabuf_alloc_ext_data(res, res_len);
00400         if (out == NULL) {
00401                 os_free(res);
00402                 return NULL;
00403         }
00404 
00405         return out;
00406 #else /* CONFIG_TLS_INTERNAL_SERVER */
00407         return NULL;
00408 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00409 }
00410 
00411 
00412 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
00413                                        struct tls_connection *conn,
00414                                        const struct wpabuf *in_data)
00415 {
00416 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00417         if (conn->client) {
00418                 struct wpabuf *buf;
00419                 int res;
00420                 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
00421                 if (buf == NULL)
00422                         return NULL;
00423                 res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data),
00424                                            wpabuf_len(in_data),
00425                                            wpabuf_mhead(buf),
00426                                            wpabuf_size(buf));
00427                 if (res < 0) {
00428                         wpabuf_free(buf);
00429                         return NULL;
00430                 }
00431                 wpabuf_put(buf, res);
00432                 return buf;
00433         }
00434 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00435 #ifdef CONFIG_TLS_INTERNAL_SERVER
00436         if (conn->server) {
00437                 struct wpabuf *buf;
00438                 int res;
00439                 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
00440                 if (buf == NULL)
00441                         return NULL;
00442                 res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data),
00443                                            wpabuf_len(in_data),
00444                                            wpabuf_mhead(buf),
00445                                            wpabuf_size(buf));
00446                 if (res < 0) {
00447                         wpabuf_free(buf);
00448                         return NULL;
00449                 }
00450                 wpabuf_put(buf, res);
00451                 return buf;
00452         }
00453 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00454         return NULL;
00455 }
00456 
00457 
00458 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
00459                                        struct tls_connection *conn,
00460                                        const struct wpabuf *in_data)
00461 {
00462 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00463         if (conn->client) {
00464                 struct wpabuf *buf;
00465                 int res;
00466                 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
00467                 if (buf == NULL)
00468                         return NULL;
00469                 res = tlsv1_client_decrypt(conn->client, wpabuf_head(in_data),
00470                                            wpabuf_len(in_data),
00471                                            wpabuf_mhead(buf),
00472                                            wpabuf_size(buf));
00473                 if (res < 0) {
00474                         wpabuf_free(buf);
00475                         return NULL;
00476                 }
00477                 wpabuf_put(buf, res);
00478                 return buf;
00479         }
00480 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00481 #ifdef CONFIG_TLS_INTERNAL_SERVER
00482         if (conn->server) {
00483                 struct wpabuf *buf;
00484                 int res;
00485                 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
00486                 if (buf == NULL)
00487                         return NULL;
00488                 res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data),
00489                                            wpabuf_len(in_data),
00490                                            wpabuf_mhead(buf),
00491                                            wpabuf_size(buf));
00492                 if (res < 0) {
00493                         wpabuf_free(buf);
00494                         return NULL;
00495                 }
00496                 wpabuf_put(buf, res);
00497                 return buf;
00498         }
00499 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00500         return NULL;
00501 }
00502 
00503 
00504 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
00505 {
00506 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00507         if (conn->client)
00508                 return tlsv1_client_resumed(conn->client);
00509 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00510 #ifdef CONFIG_TLS_INTERNAL_SERVER
00511         if (conn->server)
00512                 return tlsv1_server_resumed(conn->server);
00513 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00514         return -1;
00515 }
00516 
00517 
00518 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
00519                                    u8 *ciphers)
00520 {
00521 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00522         if (conn->client)
00523                 return tlsv1_client_set_cipher_list(conn->client, ciphers);
00524 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00525 #ifdef CONFIG_TLS_INTERNAL_SERVER
00526         if (conn->server)
00527                 return tlsv1_server_set_cipher_list(conn->server, ciphers);
00528 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00529         return -1;
00530 }
00531 
00532 
00533 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
00534                    char *buf, size_t buflen)
00535 {
00536         if (conn == NULL)
00537                 return -1;
00538 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00539         if (conn->client)
00540                 return tlsv1_client_get_cipher(conn->client, buf, buflen);
00541 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00542 #ifdef CONFIG_TLS_INTERNAL_SERVER
00543         if (conn->server)
00544                 return tlsv1_server_get_cipher(conn->server, buf, buflen);
00545 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00546         return -1;
00547 }
00548 
00549 
00550 int tls_connection_enable_workaround(void *tls_ctx,
00551                                      struct tls_connection *conn)
00552 {
00553         return -1;
00554 }
00555 
00556 
00557 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
00558                                     int ext_type, const u8 *data,
00559                                     size_t data_len)
00560 {
00561 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00562         if (conn->client) {
00563                 return tlsv1_client_hello_ext(conn->client, ext_type,
00564                                               data, data_len);
00565         }
00566 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00567         return -1;
00568 }
00569 
00570 
00571 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
00572 {
00573         return 0;
00574 }
00575 
00576 
00577 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
00578 {
00579         return 0;
00580 }
00581 
00582 
00583 int tls_connection_get_write_alerts(void *tls_ctx,
00584                                     struct tls_connection *conn)
00585 {
00586         return 0;
00587 }
00588 
00589 
00590 int tls_connection_get_keyblock_size(void *tls_ctx,
00591                                      struct tls_connection *conn)
00592 {
00593 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00594         if (conn->client)
00595                 return tlsv1_client_get_keyblock_size(conn->client);
00596 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00597 #ifdef CONFIG_TLS_INTERNAL_SERVER
00598         if (conn->server)
00599                 return tlsv1_server_get_keyblock_size(conn->server);
00600 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00601         return -1;
00602 }
00603 
00604 
00605 unsigned int tls_capabilities(void *tls_ctx)
00606 {
00607         return 0;
00608 }
00609 
00610 
00611 struct wpabuf * tls_connection_ia_send_phase_finished(
00612         void *tls_ctx, struct tls_connection *conn, int final)
00613 {
00614         return NULL;
00615 }
00616 
00617 
00618 int tls_connection_ia_final_phase_finished(void *tls_ctx,
00619                                            struct tls_connection *conn)
00620 {
00621         return -1;
00622 }
00623 
00624 
00625 int tls_connection_ia_permute_inner_secret(void *tls_ctx,
00626                                            struct tls_connection *conn,
00627                                            const u8 *key, size_t key_len)
00628 {
00629         return -1;
00630 }
00631 
00632 
00633 int tls_connection_set_session_ticket_cb(void *tls_ctx,
00634                                          struct tls_connection *conn,
00635                                          tls_session_ticket_cb cb,
00636                                          void *ctx)
00637 {
00638 #ifdef CONFIG_TLS_INTERNAL_CLIENT
00639         if (conn->client) {
00640                 tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx);
00641                 return 0;
00642         }
00643 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
00644 #ifdef CONFIG_TLS_INTERNAL_SERVER
00645         if (conn->server) {
00646                 tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx);
00647                 return 0;
00648         }
00649 #endif /* CONFIG_TLS_INTERNAL_SERVER */
00650         return -1;
00651 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36