00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 {
00158 case GNUTLS_E_DECRYPTION_FAILED:
00159
00160
00161
00162
00163
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 }