gnutls_alert.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2000, 2001, 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 #include <gnutls_int.h>
00026 #include <gnutls_errors.h>
00027 #include <gnutls_record.h>
00028 #include <debug.h>
00029 
00030 typedef struct
00031 {
00032   MHD_gnutls_alert_description_t alert;
00033   const char *desc;
00034 } MHD_gnutls_alert_entry;
00035 
00036 static const MHD_gnutls_alert_entry MHD_gtls_sup_alerts[] = {
00037   {GNUTLS_A_CLOSE_NOTIFY, "Close notify"},
00038   {GNUTLS_A_UNEXPECTED_MESSAGE, "Unexpected message"},
00039   {GNUTLS_A_BAD_RECORD_MAC, "Bad record MAC"},
00040   {GNUTLS_A_DECRYPTION_FAILED, "Decryption failed"},
00041   {GNUTLS_A_RECORD_OVERFLOW, "Record overflow"},
00042   {GNUTLS_A_DECOMPRESSION_FAILURE, "Decompression failed"},
00043   {GNUTLS_A_HANDSHAKE_FAILURE, "Handshake failed"},
00044   {GNUTLS_A_BAD_CERTIFICATE, "Certificate is bad"},
00045   {GNUTLS_A_UNSUPPORTED_CERTIFICATE, "Certificate is not supported"},
00046   {GNUTLS_A_CERTIFICATE_REVOKED, "Certificate was revoked"},
00047   {GNUTLS_A_CERTIFICATE_EXPIRED, "Certificate is expired"},
00048   {GNUTLS_A_CERTIFICATE_UNKNOWN, "Unknown certificate"},
00049   {GNUTLS_A_ILLEGAL_PARAMETER, "Illegal parameter"},
00050   {GNUTLS_A_UNKNOWN_CA, "CA is unknown"},
00051   {GNUTLS_A_ACCESS_DENIED, "Access was denied"},
00052   {GNUTLS_A_DECODE_ERROR, "Decode error"},
00053   {GNUTLS_A_DECRYPT_ERROR, "Decrypt error"},
00054   {GNUTLS_A_EXPORT_RESTRICTION, "Export restriction"},
00055   {GNUTLS_A_PROTOCOL_VERSION, "Error in protocol version"},
00056   {GNUTLS_A_INSUFFICIENT_SECURITY, "Insufficient security"},
00057   {GNUTLS_A_USER_CANCELED, "User canceled"},
00058   {GNUTLS_A_INTERNAL_ERROR, "Internal error"},
00059   {GNUTLS_A_NO_RENEGOTIATION, "No renegotiation is allowed"},
00060   {GNUTLS_A_CERTIFICATE_UNOBTAINABLE,
00061    "Could not retrieve the specified certificate"},
00062   {GNUTLS_A_UNSUPPORTED_EXTENSION, "An unsupported extension was sent"},
00063   {GNUTLS_A_UNRECOGNIZED_NAME,
00064    "The server name sent was not recognized"},
00065   {GNUTLS_A_UNKNOWN_PSK_IDENTITY,
00066    "The SRP/PSK username is missing or not known"},
00067 };
00068 
00069 #define GNUTLS_ALERT_LOOP(b) \
00070         const MHD_gnutls_alert_entry *p; \
00071                 for(p = MHD_gtls_sup_alerts; p->desc != NULL; p++) { b ; }
00072 
00073 #define GNUTLS_ALERT_ID_LOOP(a) \
00074                         GNUTLS_ALERT_LOOP( if(p->alert == alert) { a; break; })
00075 
00076 
00085 const char *
00086 MHD__gnutls_alert_get_name (MHD_gnutls_alert_description_t alert)
00087 {
00088   const char *ret = NULL;
00089 
00090   GNUTLS_ALERT_ID_LOOP (ret = p->desc);
00091 
00092   return ret;
00093 }
00094 
00112 int
00113 MHD__gnutls_alert_send (MHD_gtls_session_t session,
00114                         MHD_gnutls_alert_level_t level,
00115                         MHD_gnutls_alert_description_t desc)
00116 {
00117   uint8_t data[2];
00118   int ret;
00119   const char *name;
00120 
00121   data[0] = (uint8_t) level;
00122   data[1] = (uint8_t) desc;
00123 
00124   name = MHD__gnutls_alert_get_name ((int) data[1]);
00125   if (name == NULL)
00126     name = "(unknown)";
00127   MHD__gnutls_record_log ("REC: Sending Alert[%d|%d] - %s\n", data[0],
00128                           data[1], name);
00129 
00130   if ((ret = MHD_gtls_send_int (session, GNUTLS_ALERT, -1, data, 2)) >= 0)
00131     return 0;
00132   else
00133     return ret;
00134 }
00135 
00151 int
00152 MHD_gtls_error_to_alert (int err, int *level)
00153 {
00154   int ret, _level = -1;
00155 
00156   switch (err)
00157     {                           /* send appropriate alert */
00158     case GNUTLS_E_DECRYPTION_FAILED:
00159       /* GNUTLS_A_DECRYPTION_FAILED is not sent, because
00160        * it is not defined in SSL3. Note that we must
00161        * not distinguish Decryption failures from mac
00162        * check failures, due to the possibility of some
00163        * attacks.
00164        */
00165       ret = GNUTLS_A_BAD_RECORD_MAC;
00166       _level = GNUTLS_AL_FATAL;
00167       break;
00168     case GNUTLS_E_DECOMPRESSION_FAILED:
00169       ret = GNUTLS_A_DECOMPRESSION_FAILURE;
00170       _level = GNUTLS_AL_FATAL;
00171       break;
00172     case GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER:
00173     case GNUTLS_E_ILLEGAL_SRP_USERNAME:
00174       ret = GNUTLS_A_ILLEGAL_PARAMETER;
00175       _level = GNUTLS_AL_FATAL;
00176       break;
00177     case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND:
00178     case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND:
00179     case GNUTLS_E_ASN1_DER_ERROR:
00180     case GNUTLS_E_ASN1_VALUE_NOT_FOUND:
00181     case GNUTLS_E_ASN1_GENERIC_ERROR:
00182     case GNUTLS_E_ASN1_VALUE_NOT_VALID:
00183     case GNUTLS_E_ASN1_TAG_ERROR:
00184     case GNUTLS_E_ASN1_TAG_IMPLICIT:
00185     case GNUTLS_E_ASN1_TYPE_ANY_ERROR:
00186     case GNUTLS_E_ASN1_SYNTAX_ERROR:
00187     case GNUTLS_E_ASN1_DER_OVERFLOW:
00188       ret = GNUTLS_A_BAD_CERTIFICATE;
00189       _level = GNUTLS_AL_FATAL;
00190       break;
00191     case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
00192     case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM:
00193     case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
00194     case GNUTLS_E_NO_CIPHER_SUITES:
00195     case GNUTLS_E_NO_COMPRESSION_ALGORITHMS:
00196       ret = GNUTLS_A_HANDSHAKE_FAILURE;
00197       _level = GNUTLS_AL_FATAL;
00198       break;
00199     case GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION:
00200       ret = GNUTLS_A_UNSUPPORTED_EXTENSION;
00201       _level = GNUTLS_AL_FATAL;
00202       break;
00203     case GNUTLS_E_UNEXPECTED_PACKET:
00204     case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET:
00205       ret = GNUTLS_A_UNEXPECTED_MESSAGE;
00206       _level = GNUTLS_AL_FATAL;
00207       break;
00208     case GNUTLS_E_REHANDSHAKE:
00209       ret = GNUTLS_A_NO_RENEGOTIATION;
00210       _level = GNUTLS_AL_WARNING;
00211       break;
00212     case GNUTLS_E_UNSUPPORTED_VERSION_PACKET:
00213       ret = GNUTLS_A_PROTOCOL_VERSION;
00214       _level = GNUTLS_AL_FATAL;
00215       break;
00216     case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE:
00217       ret = GNUTLS_A_UNSUPPORTED_CERTIFICATE;
00218       _level = GNUTLS_AL_FATAL;
00219       break;
00220     case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
00221       ret = GNUTLS_A_RECORD_OVERFLOW;
00222       _level = GNUTLS_AL_FATAL;
00223       break;
00224     case GNUTLS_E_INTERNAL_ERROR:
00225     case GNUTLS_E_NO_TEMPORARY_DH_PARAMS:
00226     case GNUTLS_E_NO_TEMPORARY_RSA_PARAMS:
00227       ret = GNUTLS_A_INTERNAL_ERROR;
00228       _level = GNUTLS_AL_FATAL;
00229       break;
00230     case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
00231     case GNUTLS_E_NO_CERTIFICATE_FOUND:
00232       ret = GNUTLS_A_INSUFFICIENT_SECURITY;
00233       _level = GNUTLS_AL_FATAL;
00234       break;
00235     default:
00236       ret = GNUTLS_A_INTERNAL_ERROR;
00237       _level = GNUTLS_AL_FATAL;
00238       break;
00239     }
00240 
00241   if (level != NULL)
00242     *level = _level;
00243 
00244   return ret;
00245 }
00246 
00247 
00264 int
00265 MHD__gnutls_alert_send_appropriate (MHD_gtls_session_t session, int err)
00266 {
00267   int alert;
00268   int level;
00269 
00270   alert = MHD_gtls_error_to_alert (err, &level);
00271   if (alert < 0)
00272     {
00273       return alert;
00274     }
00275 
00276   return MHD__gnutls_alert_send (session, level, alert);
00277 }
00278 
00292 MHD_gnutls_alert_description_t
00293 MHD_gnutls_alert_get (MHD_gtls_session_t session)
00294 {
00295   return session->internals.last_alert;
00296 }
Generated by  doxygen 1.6.2-20100208