ext_cert_type.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002, 2003, 2004, 2005 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 the code the Certificate Type TLS extension.
00026  * This extension is currently gnutls specific.
00027  */
00028 
00029 #include "gnutls_int.h"
00030 #include "gnutls_errors.h"
00031 #include "gnutls_num.h"
00032 #include "ext_cert_type.h"
00033 #include "gnutls_state.h"
00034 #include "gnutls_num.h"
00035 
00036 inline static int MHD__gnutls_num2cert_type (int num);
00037 inline static int MHD__gnutls_cert_type2num (int record_size);
00038 
00039 /*
00040  * In case of a server: if a CERT_TYPE extension type is received then it stores
00041  * into the session security parameters the new value. The server may use MHD_gnutls_session_certificate_type_get(),
00042  * to access it.
00043  *
00044  * In case of a client: If a cert_types have been specified then we send the extension.
00045  *
00046  */
00047 
00048 int
00049 MHD_gtls_cert_type_recv_params (MHD_gtls_session_t session,
00050                                 const opaque * data, size_t _data_size)
00051 {
00052   int new_type = -1, ret, i;
00053   ssize_t data_size = _data_size;
00054 
00055 #if MHD_DEBUG_TLS
00056   if (session->security_parameters.entity == GNUTLS_CLIENT)
00057     {
00058       if (data_size > 0)
00059         {
00060           if (data_size != 1)
00061             {
00062               MHD_gnutls_assert ();
00063               return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00064             }
00065 
00066           new_type = MHD__gnutls_num2cert_type (data[0]);
00067 
00068           if (new_type < 0)
00069             {
00070               MHD_gnutls_assert ();
00071               return new_type;
00072             }
00073 
00074           /* Check if we support this cert_type */
00075           if ((ret =
00076                MHD_gtls_session_cert_type_supported (session, new_type)) < 0)
00077             {
00078               MHD_gnutls_assert ();
00079               return ret;
00080             }
00081 
00082           MHD__gnutls_session_cert_type_set (session, new_type);
00083         }
00084     }
00085   else
00086 #endif
00087 
00088     {                           /* SERVER SIDE - we must check if the sent cert type is the right one
00089                                  */
00090       if (data_size > 1)
00091         {
00092           uint8_t len;
00093 
00094           len = data[0];
00095           DECR_LEN (data_size, len);
00096 
00097           for (i = 0; i < len; i++)
00098             {
00099               new_type = MHD__gnutls_num2cert_type (data[i + 1]);
00100 
00101               if (new_type < 0)
00102                 continue;
00103 
00104               /* Check if we support this cert_type */
00105               if ((ret =
00106                    MHD_gtls_session_cert_type_supported (session,
00107                                                          new_type)) < 0)
00108                 {
00109                   MHD_gnutls_assert ();
00110                   continue;
00111                 }
00112               else
00113                 break;
00114               /* new_type is ok */
00115             }
00116 
00117           if (new_type < 0)
00118             {
00119               MHD_gnutls_assert ();
00120               return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
00121             }
00122 
00123           if ((ret =
00124                MHD_gtls_session_cert_type_supported (session, new_type)) < 0)
00125             {
00126               MHD_gnutls_assert ();
00127               /* The peer has requested unsupported certificate
00128                * types. Instead of failing, procceed normally.
00129                * (the ciphersuite selection would fail, or a
00130                * non certificate ciphersuite will be selected).
00131                */
00132               return 0;
00133             }
00134 
00135           MHD__gnutls_session_cert_type_set (session, new_type);
00136         }
00137 
00138 
00139     }
00140 
00141   return 0;
00142 }
00143 
00144 /* returns data_size or a negative number on failure
00145  */
00146 int
00147 MHD_gtls_cert_type_send_params (MHD_gtls_session_t session, opaque * data,
00148                                 size_t data_size)
00149 {
00150   unsigned int len;
00151 
00152   /* this function sends the client extension data (dnsname) */
00153 #if MHD_DEBUG_TLS
00154   unsigned int i;
00155   if (session->security_parameters.entity == GNUTLS_CLIENT)
00156     {
00157 
00158       if (session->internals.priorities.cert_type.num_algorithms > 0)
00159         {
00160 
00161           len = session->internals.priorities.cert_type.num_algorithms;
00162 
00163           if (len == 1 &&
00164               session->internals.priorities.cert_type.priority[0] ==
00165               MHD_GNUTLS_CRT_X509)
00166             {
00167               /* We don't use this extension if X.509 certificates
00168                * are used.
00169                */
00170               return 0;
00171             }
00172 
00173           if (data_size < len + 1)
00174             {
00175               MHD_gnutls_assert ();
00176               return GNUTLS_E_SHORT_MEMORY_BUFFER;
00177             }
00178 
00179           /* this is a vector!
00180            */
00181           data[0] = (uint8_t) len;
00182 
00183           for (i = 0; i < len; i++)
00184             {
00185               data[i + 1] =
00186                 MHD__gnutls_cert_type2num (session->internals.
00187                                            priorities.cert_type.priority[i]);
00188             }
00189           return len + 1;
00190         }
00191 
00192     }
00193   else
00194 #endif
00195     {                           /* server side */
00196       if (session->security_parameters.cert_type != DEFAULT_CERT_TYPE)
00197         {
00198           len = 1;
00199           if (data_size < len)
00200             {
00201               MHD_gnutls_assert ();
00202               return GNUTLS_E_SHORT_MEMORY_BUFFER;
00203             }
00204 
00205           data[0] =
00206             MHD__gnutls_cert_type2num (session->
00207                                        security_parameters.cert_type);
00208           return len;
00209         }
00210 
00211 
00212     }
00213 
00214   return 0;
00215 }
00216 
00217 /* Maps numbers to record sizes according to the
00218  * extensions draft.
00219  */
00220 inline static int
00221 MHD__gnutls_num2cert_type (int num)
00222 {
00223   switch (num)
00224     {
00225     case 0:
00226       return MHD_GNUTLS_CRT_X509;
00227     default:
00228       return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
00229     }
00230 }
00231 
00232 /* Maps record size to numbers according to the
00233  * extensions draft.
00234  */
00235 inline static int
00236 MHD__gnutls_cert_type2num (int cert_type)
00237 {
00238   switch (cert_type)
00239     {
00240     case MHD_GNUTLS_CRT_X509:
00241       return 0;
00242     default:
00243       return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
00244     }
00245 
00246 }

Generated by  doxygen 1.6.2