2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
9 * The GNUTLS library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_record.h>
31 /* I18n of error codes. */
33 #define _(String) dgettext (PACKAGE, String)
34 #define N_(String) gettext_noop (String)
38 gnutls_alert_description_t alert
;
42 static const gnutls_alert_entry sup_alerts
[] = {
43 {GNUTLS_A_CLOSE_NOTIFY
, N_("Close notify")},
44 {GNUTLS_A_UNEXPECTED_MESSAGE
, N_("Unexpected message")},
45 {GNUTLS_A_BAD_RECORD_MAC
, N_("Bad record MAC")},
46 {GNUTLS_A_DECRYPTION_FAILED
, N_("Decryption failed")},
47 {GNUTLS_A_RECORD_OVERFLOW
, N_("Record overflow")},
48 {GNUTLS_A_DECOMPRESSION_FAILURE
, N_("Decompression failed")},
49 {GNUTLS_A_HANDSHAKE_FAILURE
, N_("Handshake failed")},
50 {GNUTLS_A_BAD_CERTIFICATE
, N_("Certificate is bad")},
51 {GNUTLS_A_UNSUPPORTED_CERTIFICATE
, N_("Certificate is not supported")},
52 {GNUTLS_A_CERTIFICATE_REVOKED
, N_("Certificate was revoked")},
53 {GNUTLS_A_CERTIFICATE_EXPIRED
, N_("Certificate is expired")},
54 {GNUTLS_A_CERTIFICATE_UNKNOWN
, N_("Unknown certificate")},
55 {GNUTLS_A_ILLEGAL_PARAMETER
, N_("Illegal parameter")},
56 {GNUTLS_A_UNKNOWN_CA
, N_("CA is unknown")},
57 {GNUTLS_A_ACCESS_DENIED
, N_("Access was denied")},
58 {GNUTLS_A_DECODE_ERROR
, N_("Decode error")},
59 {GNUTLS_A_DECRYPT_ERROR
, N_("Decrypt error")},
60 {GNUTLS_A_EXPORT_RESTRICTION
, N_("Export restriction")},
61 {GNUTLS_A_PROTOCOL_VERSION
, N_("Error in protocol version")},
62 {GNUTLS_A_INSUFFICIENT_SECURITY
, N_("Insufficient security")},
63 {GNUTLS_A_USER_CANCELED
, N_("User canceled")},
64 {GNUTLS_A_INTERNAL_ERROR
, N_("Internal error")},
65 {GNUTLS_A_NO_RENEGOTIATION
, N_("No renegotiation is allowed")},
66 {GNUTLS_A_CERTIFICATE_UNOBTAINABLE
,
67 N_("Could not retrieve the specified certificate")},
68 {GNUTLS_A_UNSUPPORTED_EXTENSION
, N_("An unsupported extension was sent")},
69 {GNUTLS_A_UNRECOGNIZED_NAME
,
70 N_("The server name sent was not recognized")},
71 {GNUTLS_A_UNKNOWN_PSK_IDENTITY
,
72 N_("The SRP/PSK username is missing or not known")},
73 {GNUTLS_A_INNER_APPLICATION_FAILURE
,
74 N_("Inner application negotiation failed")},
75 {GNUTLS_A_INNER_APPLICATION_VERIFICATION
,
76 N_("Inner application verification failed")},
81 * gnutls_alert_get_name - Returns a string describing the alert number given
82 * @alert: is an alert number #gnutls_session_t structure.
84 * This function will return a string that describes the given alert
85 * number, or %NULL. See gnutls_alert_get().
87 * Returns: string corresponding to #gnutls_alert_description_t value.
90 gnutls_alert_get_name (gnutls_alert_description_t alert
)
92 const gnutls_alert_entry
*p
;
94 for (p
= sup_alerts
; p
->desc
!= NULL
; p
++)
95 if (p
->alert
== alert
)
102 * gnutls_alert_send - send an alert message to the peer
103 * @session: is a #gnutls_session_t structure.
104 * @level: is the level of the alert
105 * @desc: is the alert description
107 * This function will send an alert to the peer in order to inform
108 * him of something important (eg. his Certificate could not be verified).
109 * If the alert level is Fatal then the peer is expected to close the
110 * connection, otherwise he may ignore the alert and continue.
112 * The error code of the underlying record send function will be
113 * returned, so you may also receive %GNUTLS_E_INTERRUPTED or
114 * %GNUTLS_E_AGAIN as well.
116 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
117 * an error code is returned.
120 gnutls_alert_send (gnutls_session_t session
, gnutls_alert_level_t level
,
121 gnutls_alert_description_t desc
)
127 data
[0] = (uint8_t) level
;
128 data
[1] = (uint8_t) desc
;
130 name
= gnutls_alert_get_name ((int) data
[1]);
133 _gnutls_record_log ("REC: Sending Alert[%d|%d] - %s\n", data
[0],
136 if ((ret
= _gnutls_send_int (session
, GNUTLS_ALERT
, -1, data
, 2)) >= 0)
143 * gnutls_error_to_alert - return an alert code based on the given error code
144 * @err: is a negative integer
145 * @level: the alert level will be stored there
147 * Get an alert depending on the error code returned by a gnutls
148 * function. All alerts sent by this function should be considered
149 * fatal. The only exception is when @err is %GNUTLS_E_REHANDSHAKE,
150 * where a warning alert should be sent to the peer indicating that no
151 * renegotiation will be performed.
153 * If there is no mapping to a valid alert the alert to indicate
154 * internal error is returned.
156 * Returns: the alert code to use for a particular error code.
159 gnutls_error_to_alert (int err
, int *level
)
161 int ret
, _level
= -1;
164 { /* send appropriate alert */
165 case GNUTLS_E_DECRYPTION_FAILED
:
166 /* GNUTLS_A_DECRYPTION_FAILED is not sent, because
167 * it is not defined in SSL3. Note that we must
168 * not distinguish Decryption failures from mac
169 * check failures, due to the possibility of some
172 ret
= GNUTLS_A_BAD_RECORD_MAC
;
173 _level
= GNUTLS_AL_FATAL
;
175 case GNUTLS_E_DECOMPRESSION_FAILED
:
176 ret
= GNUTLS_A_DECOMPRESSION_FAILURE
;
177 _level
= GNUTLS_AL_FATAL
;
179 case GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
:
180 case GNUTLS_E_ILLEGAL_SRP_USERNAME
:
181 ret
= GNUTLS_A_ILLEGAL_PARAMETER
;
182 _level
= GNUTLS_AL_FATAL
;
184 case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
:
185 case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND
:
186 case GNUTLS_E_ASN1_DER_ERROR
:
187 case GNUTLS_E_ASN1_VALUE_NOT_FOUND
:
188 case GNUTLS_E_ASN1_GENERIC_ERROR
:
189 case GNUTLS_E_ASN1_VALUE_NOT_VALID
:
190 case GNUTLS_E_ASN1_TAG_ERROR
:
191 case GNUTLS_E_ASN1_TAG_IMPLICIT
:
192 case GNUTLS_E_ASN1_TYPE_ANY_ERROR
:
193 case GNUTLS_E_ASN1_SYNTAX_ERROR
:
194 case GNUTLS_E_ASN1_DER_OVERFLOW
:
195 ret
= GNUTLS_A_BAD_CERTIFICATE
;
196 _level
= GNUTLS_AL_FATAL
;
198 case GNUTLS_E_UNKNOWN_CIPHER_SUITE
:
199 case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM
:
200 case GNUTLS_E_INSUFFICIENT_CREDENTIALS
:
201 case GNUTLS_E_NO_CIPHER_SUITES
:
202 case GNUTLS_E_NO_COMPRESSION_ALGORITHMS
:
203 case GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
:
204 case GNUTLS_E_SAFE_RENEGOTIATION_FAILED
:
205 ret
= GNUTLS_A_HANDSHAKE_FAILURE
;
206 _level
= GNUTLS_AL_FATAL
;
208 case GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION
:
209 ret
= GNUTLS_A_UNSUPPORTED_EXTENSION
;
210 _level
= GNUTLS_AL_FATAL
;
212 case GNUTLS_E_UNEXPECTED_PACKET
:
213 case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
:
214 ret
= GNUTLS_A_UNEXPECTED_MESSAGE
;
215 _level
= GNUTLS_AL_FATAL
;
217 case GNUTLS_E_REHANDSHAKE
:
218 ret
= GNUTLS_A_NO_RENEGOTIATION
;
219 _level
= GNUTLS_AL_WARNING
;
221 case GNUTLS_E_UNSUPPORTED_VERSION_PACKET
:
222 ret
= GNUTLS_A_PROTOCOL_VERSION
;
223 _level
= GNUTLS_AL_FATAL
;
225 case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
:
226 ret
= GNUTLS_A_UNSUPPORTED_CERTIFICATE
;
227 _level
= GNUTLS_AL_FATAL
;
229 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH
:
230 ret
= GNUTLS_A_RECORD_OVERFLOW
;
231 _level
= GNUTLS_AL_FATAL
;
233 case GNUTLS_E_INTERNAL_ERROR
:
234 case GNUTLS_E_NO_TEMPORARY_DH_PARAMS
:
235 case GNUTLS_E_NO_TEMPORARY_RSA_PARAMS
:
236 ret
= GNUTLS_A_INTERNAL_ERROR
;
237 _level
= GNUTLS_AL_FATAL
;
239 case GNUTLS_E_OPENPGP_GETKEY_FAILED
:
240 ret
= GNUTLS_A_CERTIFICATE_UNOBTAINABLE
;
241 _level
= GNUTLS_AL_FATAL
;
243 case GNUTLS_E_DH_PRIME_UNACCEPTABLE
:
244 case GNUTLS_E_NO_CERTIFICATE_FOUND
:
245 ret
= GNUTLS_A_INSUFFICIENT_SECURITY
;
246 _level
= GNUTLS_AL_FATAL
;
249 ret
= GNUTLS_A_INTERNAL_ERROR
;
250 _level
= GNUTLS_AL_FATAL
;
261 * gnutls_alert_send_appropriate - send alert to peer depending on error code
262 * @session: is a #gnutls_session_t structure.
263 * @err: is an integer
265 * Sends an alert to the peer depending on the error code returned by
266 * a gnutls function. This function will call gnutls_error_to_alert()
267 * to determine the appropriate alert to send.
269 * This function may also return %GNUTLS_E_AGAIN, or
270 * %GNUTLS_E_INTERRUPTED.
272 * If the return value is %GNUTLS_E_INVALID_REQUEST, then no alert has
273 * been sent to the peer.
275 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
276 * an error code is returned.
279 gnutls_alert_send_appropriate (gnutls_session_t session
, int err
)
284 alert
= gnutls_error_to_alert (err
, &level
);
290 return gnutls_alert_send (session
, level
, alert
);
294 * gnutls_alert_get - Returns the last alert number received.
295 * @session: is a #gnutls_session_t structure.
297 * This function will return the last alert number received. This
298 * function should be called if %GNUTLS_E_WARNING_ALERT_RECEIVED or
299 * %GNUTLS_E_FATAL_ALERT_RECEIVED has been returned by a gnutls
300 * function. The peer may send alerts if he thinks some things were
301 * not right. Check gnutls.h for the available alert descriptions.
303 * If no alert has been received the returned value is undefined.
305 * Returns: returns the last alert received, a
306 * #gnutls_alert_description_t value.
308 gnutls_alert_description_t
309 gnutls_alert_get (gnutls_session_t session
)
311 return session
->internals
.last_alert
;