gnutls_kx.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2000, 2001, 2004, 2005, 2006  Free Software Foundation
00003  *
00004  * Author: Nikos Mavrogiannopoulos
00005  *
00006  * This file is part of GNUTLS.
00007  *
00008  * The GNUTLS library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021  * USA
00022  *
00023  */
00024 
00025 /* This file contains functions which are wrappers for the key exchange
00026  * part of TLS. They are called by the handshake functions (MHD__gnutls_handshake)
00027  */
00028 
00029 #include "gnutls_int.h"
00030 #include "gnutls_handshake.h"
00031 #include "gnutls_kx.h"
00032 #include "gnutls_dh.h"
00033 #include "gnutls_errors.h"
00034 #include "gnutls_algorithms.h"
00035 #include "debug.h"
00036 #include "gnutls_mpi.h"
00037 #include <gnutls_state.h>
00038 #include <gnutls_datum.h>
00039 #include <gnutls_rsa_export.h>
00040 
00041 /* This file contains important thing for the TLS handshake procedure.
00042  */
00043 
00044 #define MASTER_SECRET "master secret"
00045 static int generate_normal_master (MHD_gtls_session_t session, int);
00046 
00047 int
00048 MHD_gtls_generate_master (MHD_gtls_session_t session, int keep_premaster)
00049 {
00050   if (session->internals.resumed == RESUME_FALSE)
00051     return generate_normal_master (session, keep_premaster);
00052   return 0;
00053 }
00054 
00055 /* here we generate the TLS Master secret.
00056  */
00057 #define PREMASTER session->key->key
00058 static int
00059 generate_normal_master (MHD_gtls_session_t session, int keep_premaster)
00060 {
00061   int ret = 0;
00062   char buf[512];
00063 
00064   MHD__gnutls_hard_log ("INT: PREMASTER SECRET[%d]: %s\n", PREMASTER.size,
00065                         MHD_gtls_bin2hex (PREMASTER.data, PREMASTER.size, buf,
00066                                           sizeof (buf)));
00067   MHD__gnutls_hard_log ("INT: CLIENT RANDOM[%d]: %s\n", 32,
00068                         MHD_gtls_bin2hex (session->security_parameters.
00069                                           client_random, 32, buf,
00070                                           sizeof (buf)));
00071   MHD__gnutls_hard_log ("INT: SERVER RANDOM[%d]: %s\n", 32,
00072                         MHD_gtls_bin2hex (session->security_parameters.
00073                                           server_random, 32, buf,
00074                                           sizeof (buf)));
00075 
00076   if (MHD__gnutls_protocol_get_version (session) == MHD_GNUTLS_PROTOCOL_SSL3)
00077     {
00078       opaque rnd[2 * TLS_RANDOM_SIZE + 1];
00079 
00080       memcpy (rnd, session->security_parameters.client_random,
00081               TLS_RANDOM_SIZE);
00082       memcpy (&rnd[TLS_RANDOM_SIZE],
00083               session->security_parameters.server_random, TLS_RANDOM_SIZE);
00084 
00085       ret =
00086         MHD_gnutls_ssl3_generate_random (PREMASTER.data, PREMASTER.size,
00087                                          rnd, 2 * TLS_RANDOM_SIZE,
00088                                          TLS_MASTER_SIZE,
00089                                          session->security_parameters.
00090                                          master_secret);
00091 
00092     }
00093   else
00094     {
00095       opaque rnd[2 * TLS_RANDOM_SIZE + 1];
00096 
00097       memcpy (rnd, session->security_parameters.client_random,
00098               TLS_RANDOM_SIZE);
00099       memcpy (&rnd[TLS_RANDOM_SIZE],
00100               session->security_parameters.server_random, TLS_RANDOM_SIZE);
00101 
00102       ret =
00103         MHD_gtls_PRF (session, PREMASTER.data, PREMASTER.size,
00104                       MASTER_SECRET, strlen (MASTER_SECRET),
00105                       rnd, 2 * TLS_RANDOM_SIZE, TLS_MASTER_SIZE,
00106                       session->security_parameters.master_secret);
00107     }
00108 
00109   /* TLS/IA inner secret is derived from the master secret. */
00110   memcpy (session->security_parameters.inner_secret,
00111           session->security_parameters.master_secret, TLS_MASTER_SIZE);
00112 
00113   if (!keep_premaster)
00114     MHD__gnutls_free_datum (&PREMASTER);
00115 
00116   if (ret < 0)
00117     return ret;
00118 
00119   MHD__gnutls_hard_log ("INT: MASTER SECRET: %s\n",
00120                         MHD_gtls_bin2hex (session->security_parameters.
00121                                           master_secret, TLS_MASTER_SIZE, buf,
00122                                           sizeof (buf)));
00123 
00124   return ret;
00125 }
00126 
00127 
00128 /* This is called when we want to receive the key exchange message of the
00129  * server. It does nothing if this type of message is not required
00130  * by the selected ciphersuite.
00131  */
00132 int
00133 MHD_gtls_send_server_kx_message (MHD_gtls_session_t session, int again)
00134 {
00135   uint8_t *data = NULL;
00136   int data_size = 0;
00137   int ret = 0;
00138 
00139   if (session->internals.auth_struct->MHD_gtls_gen_server_kx == NULL)
00140     return 0;
00141 
00142   data = NULL;
00143   data_size = 0;
00144 
00145   if (again == 0)
00146     {
00147       data_size =
00148         session->internals.auth_struct->MHD_gtls_gen_server_kx (session,
00149                                                                 &data);
00150 
00151       if (data_size == GNUTLS_E_INT_RET_0)
00152         {
00153           MHD_gnutls_assert ();
00154           return 0;
00155         }
00156 
00157       if (data_size < 0)
00158         {
00159           MHD_gnutls_assert ();
00160           return data_size;
00161         }
00162     }
00163 
00164   ret =
00165     MHD_gtls_send_handshake (session, data, data_size,
00166                              GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
00167   MHD_gnutls_free (data);
00168 
00169   if (ret < 0)
00170     {
00171       MHD_gnutls_assert ();
00172       return ret;
00173     }
00174   return data_size;
00175 }
00176 
00177 /* This function sends a certificate request message to the
00178  * client.
00179  */
00180 int
00181 MHD_gtls_send_server_certificate_request (MHD_gtls_session_t session,
00182                                           int again)
00183 {
00184   uint8_t *data = NULL;
00185   int data_size = 0;
00186   int ret = 0;
00187 
00188   if (session->internals.auth_struct->
00189       MHD_gtls_gen_server_certificate_request == NULL)
00190     return 0;
00191 
00192   if (session->internals.send_cert_req <= 0)
00193     return 0;
00194 
00195   data = NULL;
00196   data_size = 0;
00197 
00198   if (again == 0)
00199     {
00200       data_size =
00201         session->internals.auth_struct->
00202         MHD_gtls_gen_server_certificate_request (session, &data);
00203 
00204       if (data_size < 0)
00205         {
00206           MHD_gnutls_assert ();
00207           return data_size;
00208         }
00209     }
00210   ret =
00211     MHD_gtls_send_handshake (session, data, data_size,
00212                              GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
00213   MHD_gnutls_free (data);
00214 
00215   if (ret < 0)
00216     {
00217       MHD_gnutls_assert ();
00218       return ret;
00219     }
00220   return data_size;
00221 }
00222 
00223 
00224 /* This is the function for the client to send the key
00225  * exchange message
00226  */
00227 int
00228 MHD_gtls_send_client_kx_message (MHD_gtls_session_t session, int again)
00229 {
00230   uint8_t *data;
00231   int data_size;
00232   int ret = 0;
00233 
00234   if (session->internals.auth_struct->MHD_gtls_gen_client_kx == NULL)
00235     return 0;
00236 
00237 
00238   data = NULL;
00239   data_size = 0;
00240 
00241   if (again == 0)
00242     {
00243       data_size =
00244         session->internals.auth_struct->MHD_gtls_gen_client_kx (session,
00245                                                                 &data);
00246       if (data_size < 0)
00247         {
00248           MHD_gnutls_assert ();
00249           return data_size;
00250         }
00251     }
00252   ret =
00253     MHD_gtls_send_handshake (session, data, data_size,
00254                              GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
00255   MHD_gnutls_free (data);
00256 
00257   if (ret < 0)
00258     {
00259       MHD_gnutls_assert ();
00260       return ret;
00261     }
00262 
00263   return ret;
00264 }
00265 
00266 
00267 /* This is the function for the client to send the certificate
00268  * verify message
00269  */
00270 int
00271 MHD_gtls_send_client_certificate_verify (MHD_gtls_session_t session,
00272                                          int again)
00273 {
00274   uint8_t *data;
00275   int ret = 0;
00276   int data_size;
00277 
00278   /* This is a packet that is only sent by the client
00279    */
00280   if (session->security_parameters.entity == GNUTLS_SERVER)
00281     return 0;
00282 
00283   /* if certificate verify is not needed just exit
00284    */
00285   if (session->key->certificate_requested == 0)
00286     return 0;
00287 
00288   if (session->internals.auth_struct->MHD_gtls_gen_client_cert_vrfy == NULL)
00289     {
00290       MHD_gnutls_assert ();
00291       return 0;                 /* this algorithm does not support cli_cert_vrfy
00292                                  */
00293     }
00294 
00295   data = NULL;
00296   data_size = 0;
00297 
00298   if (again == 0)
00299     {
00300       data_size =
00301         session->internals.auth_struct->
00302         MHD_gtls_gen_client_cert_vrfy (session, &data);
00303       if (data_size < 0)
00304         {
00305           MHD_gnutls_assert ();
00306           return data_size;
00307         }
00308       if (data_size == 0)
00309         return 0;
00310 
00311     }
00312   ret =
00313     MHD_gtls_send_handshake (session, data,
00314                              data_size, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
00315   MHD_gnutls_free (data);
00316 
00317   return ret;
00318 }
00319 
00320 
00321 int
00322 MHD_gtls_recv_server_kx_message (MHD_gtls_session_t session)
00323 {
00324   uint8_t *data = NULL;
00325   int datasize;
00326   int ret = 0;
00327 
00328   if (session->internals.auth_struct->MHD_gtls_process_server_kx != NULL)
00329     {
00330 
00331       /* EXCEPTION FOR RSA_EXPORT cipher suite
00332        */
00333       if (MHD_gtls_session_is_export (session) != 0 &&
00334           MHD__gnutls_peers_cert_less_512 (session) != 0)
00335         {
00336           MHD_gnutls_assert ();
00337           return 0;
00338         }
00339 
00340       ret =
00341         MHD_gtls_recv_handshake (session, &data,
00342                                  &datasize,
00343                                  GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
00344                                  MANDATORY_PACKET);
00345       if (ret < 0)
00346         {
00347           MHD_gnutls_assert ();
00348           return ret;
00349         }
00350 
00351       ret =
00352         session->internals.auth_struct->MHD_gtls_process_server_kx (session,
00353                                                                     data,
00354                                                                     datasize);
00355       MHD_gnutls_free (data);
00356 
00357       if (ret < 0)
00358         {
00359           MHD_gnutls_assert ();
00360           return ret;
00361         }
00362 
00363     }
00364   return ret;
00365 }
00366 
00367 int
00368 MHD_gtls_recv_server_certificate_request (MHD_gtls_session_t session)
00369 {
00370   uint8_t *data;
00371   int datasize;
00372   int ret = 0;
00373 
00374   if (session->internals.auth_struct->
00375       MHD_gtls_process_server_certificate_request != NULL)
00376     {
00377 
00378       ret =
00379         MHD_gtls_recv_handshake (session, &data,
00380                                  &datasize,
00381                                  GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
00382                                  OPTIONAL_PACKET);
00383       if (ret < 0)
00384         return ret;
00385 
00386       if (ret == 0 && datasize == 0)
00387         return 0;               /* ignored */
00388 
00389       ret =
00390         session->internals.auth_struct->
00391         MHD_gtls_process_server_certificate_request (session, data, datasize);
00392       MHD_gnutls_free (data);
00393       if (ret < 0)
00394         return ret;
00395 
00396     }
00397   return ret;
00398 }
00399 
00400 int
00401 MHD_gtls_recv_client_kx_message (MHD_gtls_session_t session)
00402 {
00403   uint8_t *data;
00404   int datasize;
00405   int ret = 0;
00406 
00407 
00408   /* Do key exchange only if the algorithm permits it */
00409   if (session->internals.auth_struct->MHD_gtls_process_client_kx != NULL)
00410     {
00411 
00412       ret =
00413         MHD_gtls_recv_handshake (session, &data,
00414                                  &datasize,
00415                                  GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
00416                                  MANDATORY_PACKET);
00417       if (ret < 0)
00418         return ret;
00419 
00420       ret =
00421         session->internals.auth_struct->MHD_gtls_process_client_kx (session,
00422                                                                     data,
00423                                                                     datasize);
00424       MHD_gnutls_free (data);
00425       if (ret < 0)
00426         return ret;
00427 
00428     }
00429 
00430   return ret;
00431 }
00432 
00433 
00434 /* This is called when we want send our certificate
00435  */
00436 int
00437 MHD_gtls_send_client_certificate (MHD_gtls_session_t session, int again)
00438 {
00439   uint8_t *data = NULL;
00440   int data_size = 0;
00441   int ret = 0;
00442 
00443 
00444   if (session->key->certificate_requested == 0)
00445     return 0;
00446 
00447   if (session->internals.auth_struct->MHD_gtls_gen_client_certificate == NULL)
00448     return 0;
00449 
00450   data = NULL;
00451   data_size = 0;
00452 
00453   if (again == 0)
00454     {
00455       if (MHD__gnutls_protocol_get_version (session) !=
00456           MHD_GNUTLS_PROTOCOL_SSL3
00457           || session->internals.selected_cert_list_length > 0)
00458         {
00459           /* TLS 1.0 or SSL 3.0 with a valid certificate
00460            */
00461           data_size =
00462             session->internals.auth_struct->
00463             MHD_gtls_gen_client_certificate (session, &data);
00464 
00465           if (data_size < 0)
00466             {
00467               MHD_gnutls_assert ();
00468               return data_size;
00469             }
00470         }
00471     }
00472 
00473   /* In the SSL 3.0 protocol we need to send a
00474    * no certificate alert instead of an
00475    * empty certificate.
00476    */
00477   if (MHD__gnutls_protocol_get_version (session) == MHD_GNUTLS_PROTOCOL_SSL3
00478       && session->internals.selected_cert_list_length == 0)
00479     {
00480       ret =
00481         MHD__gnutls_alert_send (session, GNUTLS_AL_WARNING,
00482                                 GNUTLS_A_SSL3_NO_CERTIFICATE);
00483 
00484     }
00485   else
00486     {                           /* TLS 1.0 or SSL 3.0 with a valid certificate
00487                                  */
00488       ret =
00489         MHD_gtls_send_handshake (session, data, data_size,
00490                                  GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
00491       MHD_gnutls_free (data);
00492     }
00493 
00494   if (ret < 0)
00495     {
00496       MHD_gnutls_assert ();
00497       return ret;
00498     }
00499 
00500   return data_size;
00501 }
00502 
00503 
00504 /* This is called when we want send our certificate
00505  */
00506 int
00507 MHD_gtls_send_server_certificate (MHD_gtls_session_t session, int again)
00508 {
00509   uint8_t *data = NULL;
00510   int data_size = 0;
00511   int ret = 0;
00512 
00513 
00514   if (session->internals.auth_struct->MHD_gtls_gen_server_certificate == NULL)
00515     return 0;
00516 
00517   data = NULL;
00518   data_size = 0;
00519 
00520   if (again == 0)
00521     {
00522       data_size =
00523         session->internals.auth_struct->
00524         MHD_gtls_gen_server_certificate (session, &data);
00525 
00526       if (data_size < 0)
00527         {
00528           MHD_gnutls_assert ();
00529           return data_size;
00530         }
00531     }
00532   ret =
00533     MHD_gtls_send_handshake (session, data, data_size,
00534                              GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
00535   MHD_gnutls_free (data);
00536 
00537   if (ret < 0)
00538     {
00539       MHD_gnutls_assert ();
00540       return ret;
00541     }
00542 
00543   return data_size;
00544 }
00545 
00546 
00547 int
00548 MHD_gtls_recv_client_certificate (MHD_gtls_session_t session)
00549 {
00550   int datasize;
00551   opaque *data;
00552   int ret = 0;
00553   int optional;
00554 
00555   if (session->internals.auth_struct->MHD_gtls_process_client_certificate !=
00556       NULL)
00557     {
00558 
00559       /* if we have not requested a certificate then just return
00560        */
00561       if (session->internals.send_cert_req == 0)
00562         {
00563           return 0;
00564         }
00565 
00566       if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
00567         optional = MANDATORY_PACKET;
00568       else
00569         optional = OPTIONAL_PACKET;
00570 
00571       ret =
00572         MHD_gtls_recv_handshake (session, &data,
00573                                  &datasize,
00574                                  GNUTLS_HANDSHAKE_CERTIFICATE_PKT, optional);
00575 
00576       if (ret < 0)
00577         {
00578           /* Handle the case of old SSL3 clients who send
00579            * a warning alert instead of an empty certificate to indicate
00580            * no certificate.
00581            */
00582           if (optional == OPTIONAL_PACKET &&
00583               ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
00584               MHD__gnutls_protocol_get_version (session) ==
00585               MHD_GNUTLS_PROTOCOL_SSL3
00586               && MHD_gnutls_alert_get (session) ==
00587               GNUTLS_A_SSL3_NO_CERTIFICATE)
00588             {
00589 
00590               /* SSL3 does not send an empty certificate,
00591                * but this alert. So we just ignore it.
00592                */
00593               MHD_gnutls_assert ();
00594               return 0;
00595             }
00596 
00597           /* certificate was required
00598            */
00599           if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
00600                || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
00601               && optional == MANDATORY_PACKET)
00602             {
00603               MHD_gnutls_assert ();
00604               return GNUTLS_E_NO_CERTIFICATE_FOUND;
00605             }
00606 
00607           return ret;
00608         }
00609 
00610       if (ret == 0 && datasize == 0 && optional == OPTIONAL_PACKET)
00611         {
00612           /* Client has not sent the certificate message.
00613            * well I'm not sure we should accept this
00614            * behaviour.
00615            */
00616           MHD_gnutls_assert ();
00617           return 0;
00618         }
00619       ret =
00620         session->internals.auth_struct->
00621         MHD_gtls_process_client_certificate (session, data, datasize);
00622 
00623       MHD_gnutls_free (data);
00624       if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND)
00625         {
00626           MHD_gnutls_assert ();
00627           return ret;
00628         }
00629 
00630       /* ok we should expect a certificate verify message now
00631        */
00632       if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional == OPTIONAL_PACKET)
00633         ret = 0;
00634       else
00635         session->key->certificate_requested = 1;
00636 
00637     }
00638 
00639   return ret;
00640 }
00641 
00642 int
00643 MHD_gtls_recv_server_certificate (MHD_gtls_session_t session)
00644 {
00645   int datasize;
00646   opaque *data;
00647   int ret = 0;
00648 
00649   if (session->internals.auth_struct->MHD_gtls_process_server_certificate !=
00650       NULL)
00651     {
00652 
00653       ret =
00654         MHD_gtls_recv_handshake (session, &data,
00655                                  &datasize,
00656                                  GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
00657                                  MANDATORY_PACKET);
00658       if (ret < 0)
00659         {
00660           MHD_gnutls_assert ();
00661           return ret;
00662         }
00663 
00664       ret =
00665         session->internals.auth_struct->
00666         MHD_gtls_process_server_certificate (session, data, datasize);
00667       MHD_gnutls_free (data);
00668       if (ret < 0)
00669         {
00670           MHD_gnutls_assert ();
00671           return ret;
00672         }
00673     }
00674 
00675   return ret;
00676 }
00677 
00678 
00679 /* Recv the client certificate verify. This packet may not
00680  * arrive if the peer did not send us a certificate.
00681  */
00682 int
00683 MHD_gtls_recv_client_certificate_verify_message (MHD_gtls_session_t session)
00684 {
00685   uint8_t *data;
00686   int datasize;
00687   int ret = 0;
00688 
00689 
00690   if (session->internals.auth_struct->MHD_gtls_process_client_cert_vrfy !=
00691       NULL)
00692     {
00693 
00694       if (session->internals.send_cert_req == 0 ||
00695           session->key->certificate_requested == 0)
00696         {
00697           return 0;
00698         }
00699 
00700       ret =
00701         MHD_gtls_recv_handshake (session, &data,
00702                                  &datasize,
00703                                  GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
00704                                  OPTIONAL_PACKET);
00705       if (ret < 0)
00706         return ret;
00707 
00708       if (ret == 0 && datasize == 0
00709           && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
00710         {
00711           /* certificate was required */
00712           MHD_gnutls_assert ();
00713           return GNUTLS_E_NO_CERTIFICATE_FOUND;
00714         }
00715 
00716       ret =
00717         session->internals.auth_struct->
00718         MHD_gtls_process_client_cert_vrfy (session, data, datasize);
00719       MHD_gnutls_free (data);
00720       if (ret < 0)
00721         return ret;
00722 
00723     }
00724 
00725   return ret;
00726 }

Generated on Fri Feb 27 18:31:22 2009 for GNU libmicrohttpd by  doxygen 1.5.7.1