2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
25 #include <gnutls_record.h>
28 /* I18n of error codes. */
30 #define _(String) dgettext (PACKAGE, String)
31 #define N_(String) gettext_noop (String)
35 gnutls_alert_description_t alert
;
40 #define ALERT_ENTRY(x,y) \
43 static const gnutls_alert_entry sup_alerts
[] = {
44 ALERT_ENTRY(GNUTLS_A_CLOSE_NOTIFY
, N_("Close notify")),
45 ALERT_ENTRY(GNUTLS_A_UNEXPECTED_MESSAGE
, N_("Unexpected message")),
46 ALERT_ENTRY(GNUTLS_A_BAD_RECORD_MAC
, N_("Bad record MAC")),
47 ALERT_ENTRY(GNUTLS_A_DECRYPTION_FAILED
, N_("Decryption failed")),
48 ALERT_ENTRY(GNUTLS_A_RECORD_OVERFLOW
, N_("Record overflow")),
49 ALERT_ENTRY(GNUTLS_A_DECOMPRESSION_FAILURE
, N_("Decompression failed")),
50 ALERT_ENTRY(GNUTLS_A_HANDSHAKE_FAILURE
, N_("Handshake failed")),
51 ALERT_ENTRY(GNUTLS_A_BAD_CERTIFICATE
, N_("Certificate is bad")),
52 ALERT_ENTRY(GNUTLS_A_UNSUPPORTED_CERTIFICATE
, N_("Certificate is not supported")),
53 ALERT_ENTRY(GNUTLS_A_CERTIFICATE_REVOKED
, N_("Certificate was revoked")),
54 ALERT_ENTRY(GNUTLS_A_CERTIFICATE_EXPIRED
, N_("Certificate is expired")),
55 ALERT_ENTRY(GNUTLS_A_CERTIFICATE_UNKNOWN
, N_("Unknown certificate")),
56 ALERT_ENTRY(GNUTLS_A_ILLEGAL_PARAMETER
, N_("Illegal parameter")),
57 ALERT_ENTRY(GNUTLS_A_UNKNOWN_CA
, N_("CA is unknown")),
58 ALERT_ENTRY(GNUTLS_A_ACCESS_DENIED
, N_("Access was denied")),
59 ALERT_ENTRY(GNUTLS_A_DECODE_ERROR
, N_("Decode error")),
60 ALERT_ENTRY(GNUTLS_A_DECRYPT_ERROR
, N_("Decrypt error")),
61 ALERT_ENTRY(GNUTLS_A_EXPORT_RESTRICTION
, N_("Export restriction")),
62 ALERT_ENTRY(GNUTLS_A_PROTOCOL_VERSION
, N_("Error in protocol version")),
63 ALERT_ENTRY(GNUTLS_A_INSUFFICIENT_SECURITY
, N_("Insufficient security")),
64 ALERT_ENTRY(GNUTLS_A_USER_CANCELED
, N_("User canceled")),
65 ALERT_ENTRY(GNUTLS_A_SSL3_NO_CERTIFICATE
, N_("No certificate (SSL 3.0)")),
66 ALERT_ENTRY(GNUTLS_A_INTERNAL_ERROR
, N_("Internal error")),
67 ALERT_ENTRY(GNUTLS_A_NO_RENEGOTIATION
, N_("No renegotiation is allowed")),
68 ALERT_ENTRY(GNUTLS_A_CERTIFICATE_UNOBTAINABLE
,
69 N_("Could not retrieve the specified certificate")),
70 ALERT_ENTRY(GNUTLS_A_UNSUPPORTED_EXTENSION
, N_("An unsupported extension was sent")),
71 ALERT_ENTRY(GNUTLS_A_UNRECOGNIZED_NAME
,
72 N_("The server name sent was not recognized")),
73 ALERT_ENTRY(GNUTLS_A_UNKNOWN_PSK_IDENTITY
,
74 N_("The SRP/PSK username is missing or not known")),
79 * gnutls_alert_get_name:
80 * @alert: is an alert number.
82 * This function will return a string that describes the given alert
83 * number, or %NULL. See gnutls_alert_get().
85 * Returns: string corresponding to #gnutls_alert_description_t value.
88 gnutls_alert_get_name (gnutls_alert_description_t alert
)
90 const gnutls_alert_entry
*p
;
92 for (p
= sup_alerts
; p
->desc
!= NULL
; p
++)
93 if (p
->alert
== alert
)
100 * gnutls_alert_get_strname:
101 * @alert: is an alert number.
103 * This function will return a string of the name of the alert.
105 * Returns: string corresponding to #gnutls_alert_description_t value.
110 gnutls_alert_get_strname (gnutls_alert_description_t alert
)
112 const gnutls_alert_entry
*p
;
114 for (p
= sup_alerts
; p
->name
!= NULL
; p
++)
115 if (p
->alert
== alert
)
123 * @session: is a #gnutls_session_t structure.
124 * @level: is the level of the alert
125 * @desc: is the alert description
127 * This function will send an alert to the peer in order to inform
128 * him of something important (eg. his Certificate could not be verified).
129 * If the alert level is Fatal then the peer is expected to close the
130 * connection, otherwise he may ignore the alert and continue.
132 * The error code of the underlying record send function will be
133 * returned, so you may also receive %GNUTLS_E_INTERRUPTED or
134 * %GNUTLS_E_AGAIN as well.
136 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
137 * an error code is returned.
140 gnutls_alert_send (gnutls_session_t session
, gnutls_alert_level_t level
,
141 gnutls_alert_description_t desc
)
147 data
[0] = (uint8_t) level
;
148 data
[1] = (uint8_t) desc
;
150 name
= gnutls_alert_get_name ((int) data
[1]);
153 _gnutls_record_log ("REC: Sending Alert[%d|%d] - %s\n", data
[0],
157 _gnutls_send_int (session
, GNUTLS_ALERT
, -1, EPOCH_WRITE_CURRENT
, data
,
158 2, MBUFFER_FLUSH
)) >= 0)
165 * gnutls_error_to_alert:
166 * @err: is a negative integer
167 * @level: the alert level will be stored there
169 * Get an alert depending on the error code returned by a gnutls
170 * function. All alerts sent by this function should be considered
171 * fatal. The only exception is when @err is %GNUTLS_E_REHANDSHAKE,
172 * where a warning alert should be sent to the peer indicating that no
173 * renegotiation will be performed.
175 * If there is no mapping to a valid alert the alert to indicate
176 * internal error is returned.
178 * Returns: the alert code to use for a particular error code.
181 gnutls_error_to_alert (int err
, int *level
)
183 int ret
, _level
= -1;
186 { /* send appropriate alert */
187 case GNUTLS_E_DECRYPTION_FAILED
:
188 /* GNUTLS_A_DECRYPTION_FAILED is not sent, because
189 * it is not defined in SSL3. Note that we must
190 * not distinguish Decryption failures from mac
191 * check failures, due to the possibility of some
194 ret
= GNUTLS_A_BAD_RECORD_MAC
;
195 _level
= GNUTLS_AL_FATAL
;
197 case GNUTLS_E_DECOMPRESSION_FAILED
:
198 ret
= GNUTLS_A_DECOMPRESSION_FAILURE
;
199 _level
= GNUTLS_AL_FATAL
;
201 case GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
:
202 case GNUTLS_E_ILLEGAL_SRP_USERNAME
:
203 ret
= GNUTLS_A_ILLEGAL_PARAMETER
;
204 _level
= GNUTLS_AL_FATAL
;
206 case GNUTLS_E_UNKNOWN_SRP_USERNAME
:
207 ret
= GNUTLS_A_UNKNOWN_PSK_IDENTITY
;
208 _level
= GNUTLS_AL_FATAL
;
210 case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
:
211 case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND
:
212 case GNUTLS_E_ASN1_DER_ERROR
:
213 case GNUTLS_E_ASN1_VALUE_NOT_FOUND
:
214 case GNUTLS_E_ASN1_GENERIC_ERROR
:
215 case GNUTLS_E_ASN1_VALUE_NOT_VALID
:
216 case GNUTLS_E_ASN1_TAG_ERROR
:
217 case GNUTLS_E_ASN1_TAG_IMPLICIT
:
218 case GNUTLS_E_ASN1_TYPE_ANY_ERROR
:
219 case GNUTLS_E_ASN1_SYNTAX_ERROR
:
220 case GNUTLS_E_ASN1_DER_OVERFLOW
:
221 case GNUTLS_E_CERTIFICATE_ERROR
:
222 ret
= GNUTLS_A_BAD_CERTIFICATE
;
223 _level
= GNUTLS_AL_FATAL
;
225 case GNUTLS_E_UNKNOWN_CIPHER_SUITE
:
226 case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
:
227 case GNUTLS_E_INSUFFICIENT_CREDENTIALS
:
228 case GNUTLS_E_NO_CIPHER_SUITES
:
229 case GNUTLS_E_NO_COMPRESSION_ALGORITHMS
:
230 case GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
:
231 case GNUTLS_E_SAFE_RENEGOTIATION_FAILED
:
232 case GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL
:
233 ret
= GNUTLS_A_HANDSHAKE_FAILURE
;
234 _level
= GNUTLS_AL_FATAL
;
236 case GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION
:
237 ret
= GNUTLS_A_UNSUPPORTED_EXTENSION
;
238 _level
= GNUTLS_AL_FATAL
;
240 case GNUTLS_E_USER_ERROR
:
241 ret
= GNUTLS_A_USER_CANCELED
;
242 _level
= GNUTLS_AL_FATAL
;
244 case GNUTLS_E_UNEXPECTED_PACKET
:
245 case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
:
246 case GNUTLS_E_PREMATURE_TERMINATION
:
247 ret
= GNUTLS_A_UNEXPECTED_MESSAGE
;
248 _level
= GNUTLS_AL_FATAL
;
250 case GNUTLS_E_REHANDSHAKE
:
251 case GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED
:
252 ret
= GNUTLS_A_NO_RENEGOTIATION
;
253 _level
= GNUTLS_AL_WARNING
;
255 case GNUTLS_E_UNSUPPORTED_VERSION_PACKET
:
256 ret
= GNUTLS_A_PROTOCOL_VERSION
;
257 _level
= GNUTLS_AL_FATAL
;
259 case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
:
260 ret
= GNUTLS_A_UNSUPPORTED_CERTIFICATE
;
261 _level
= GNUTLS_AL_FATAL
;
263 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH
:
264 ret
= GNUTLS_A_RECORD_OVERFLOW
;
265 _level
= GNUTLS_AL_FATAL
;
267 case GNUTLS_E_INTERNAL_ERROR
:
268 case GNUTLS_E_NO_TEMPORARY_DH_PARAMS
:
269 case GNUTLS_E_NO_TEMPORARY_RSA_PARAMS
:
270 ret
= GNUTLS_A_INTERNAL_ERROR
;
271 _level
= GNUTLS_AL_FATAL
;
273 case GNUTLS_E_OPENPGP_GETKEY_FAILED
:
274 ret
= GNUTLS_A_CERTIFICATE_UNOBTAINABLE
;
275 _level
= GNUTLS_AL_FATAL
;
277 case GNUTLS_E_DH_PRIME_UNACCEPTABLE
:
278 case GNUTLS_E_NO_CERTIFICATE_FOUND
:
279 ret
= GNUTLS_A_INSUFFICIENT_SECURITY
;
280 _level
= GNUTLS_AL_FATAL
;
283 ret
= GNUTLS_A_INTERNAL_ERROR
;
284 _level
= GNUTLS_AL_FATAL
;
295 * gnutls_alert_send_appropriate:
296 * @session: is a #gnutls_session_t structure.
297 * @err: is an integer
299 * Sends an alert to the peer depending on the error code returned by
300 * a gnutls function. This function will call gnutls_error_to_alert()
301 * to determine the appropriate alert to send.
303 * This function may also return %GNUTLS_E_AGAIN, or
304 * %GNUTLS_E_INTERRUPTED.
306 * If the return value is %GNUTLS_E_INVALID_REQUEST, then no alert has
307 * been sent to the peer.
309 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
310 * an error code is returned.
313 gnutls_alert_send_appropriate (gnutls_session_t session
, int err
)
318 alert
= gnutls_error_to_alert (err
, &level
);
324 return gnutls_alert_send (session
, level
, alert
);
329 * @session: is a #gnutls_session_t structure.
331 * This function will return the last alert number received. This
332 * function should be called when %GNUTLS_E_WARNING_ALERT_RECEIVED or
333 * %GNUTLS_E_FATAL_ALERT_RECEIVED errors are returned by a gnutls
334 * function. The peer may send alerts if he encounters an error.
335 * If no alert has been received the returned value is undefined.
337 * Returns: the last alert received, a
338 * #gnutls_alert_description_t value.
340 gnutls_alert_description_t
341 gnutls_alert_get (gnutls_session_t session
)
343 return session
->internals
.last_alert
;