*** empty log message ***
[gnutls.git] / lib / gnutls_alert.c
blob1495194e6c73734bab9926145eb19b8209eca79a
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <gnutls_int.h>
23 #include <gnutls_errors.h>
24 #include <gnutls_alert.h>
25 #include <gnutls_record.h>
26 #include <debug.h>
28 typedef struct {
29 AlertDescription alert;
30 char *desc;
31 } gnutls_alert_entry;
33 static const gnutls_alert_entry sup_alerts[] = {
34 { GNUTLS_A_CLOSE_NOTIFY, "Close notify" },
35 { GNUTLS_A_UNEXPECTED_MESSAGE, "Unexpected message" },
36 { GNUTLS_A_BAD_RECORD_MAC, "Bad record MAC" },
37 { GNUTLS_A_DECRYPTION_FAILED, "Decryption failed" },
38 { GNUTLS_A_RECORD_OVERFLOW, "Record overflow" },
39 { GNUTLS_A_DECOMPRESSION_FAILURE, "Decompression failed" },
40 { GNUTLS_A_HANDSHAKE_FAILURE, "Handshake failed" },
41 { GNUTLS_A_BAD_CERTIFICATE, "Certificate is bad" },
42 { GNUTLS_A_UNSUPPORTED_CERTIFICATE, "Certificate is not supported" },
43 { GNUTLS_A_CERTIFICATE_REVOKED, "Certificate was revoked" },
44 { GNUTLS_A_CERTIFICATE_EXPIRED, "Certificate is expired" },
45 { GNUTLS_A_CERTIFICATE_UNKNOWN, "Unknown certificate" },
46 { GNUTLS_A_ILLEGAL_PARAMETER, "Illegal parameter" },
47 { GNUTLS_A_UNKNOWN_CA, "CA is unknown" },
48 { GNUTLS_A_ACCESS_DENIED, "Access was denied" },
49 { GNUTLS_A_DECODE_ERROR, "Decode error" },
50 { GNUTLS_A_DECRYPT_ERROR, "Decrypt error" },
51 { GNUTLS_A_EXPORT_RESTRICTION, "Export restriction" },
52 { GNUTLS_A_PROTOCOL_VERSION, "Error in protocol version" },
53 { GNUTLS_A_INSUFFICIENT_SECURITY,"Insufficient security" },
54 { GNUTLS_A_USER_CANCELED, "User canceled" },
55 { GNUTLS_A_NO_RENEGOTIATION, "No renegotiation is allowed" },
56 {0, NULL}
59 #define GNUTLS_ALERT_LOOP(b) \
60 const gnutls_alert_entry *p; \
61 for(p = sup_alerts; p->desc != NULL; p++) { b ; }
63 #define GNUTLS_ALERT_ID_LOOP(a) \
64 GNUTLS_ALERT_LOOP( if(p->alert == alert) { a; break; })
68 /**
69 * gnutls_alert_send - This function sends an alert message to the peer
70 * @state: is a &GNUTLS_STATE structure.
71 * @level: is the level of the alert
72 * @desc: is the alert description
74 * This function will send an alert to the peer in order to inform
75 * him of something important (eg. his Certificate could not be verified).
76 * If the alert level is Fatal then the peer is expected to close the
77 * connection, otherwise he may ignore the alert and continue.
78 * Returns 0 on success.
80 **/
81 int gnutls_alert_send( GNUTLS_STATE state, GNUTLS_AlertLevel level, GNUTLS_AlertDescription desc)
83 uint8 data[2];
84 int ret;
86 data[0] = (uint8) level;
87 data[1] = (uint8) desc;
89 _gnutls_record_log( "REC: Sending Alert[%d|%d] - %s\n", data[0], data[1], _gnutls_alert_get_name((int)data[1]));
91 if ( (ret = gnutls_send_int( state, GNUTLS_ALERT, -1, data, 2)) >= 0)
92 return 0;
93 else
94 return ret;
97 /* Sends the appropriate alert, depending
98 * on the error message.
101 * gnutls_alert_send_appropriate - This function sends an alert to the peer depending on the error code
102 * @state: is a &GNUTLS_STATE structure.
103 * @err: is an integer
105 * Sends an alert to the peer depending on the error code returned by a gnutls
106 * function. All alerts sent by this function are fatal, so connection should
107 * be considered terminated after calling this function. The only exception
108 * is when err == GNUTLS_E_REHANDSHAKE, then a warning alert is sent to
109 * the peer indicating the no renegotiation will be performed.
111 * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.
113 * If the return value is GNUTLS_E_UNIMPLEMENTED_FEATURE, then no alert has
114 * been sent to the peer.
117 int gnutls_alert_send_appropriate( GNUTLS_STATE state, int err) {
118 int ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
119 switch (err) { /* send appropriate alert */
120 case GNUTLS_E_DECRYPTION_FAILED:
121 /* GNUTLS_A_DECRYPTION_FAILED is not sent, because
122 * it is not defined in SSL3.
124 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_BAD_RECORD_MAC);
125 break;
126 case GNUTLS_E_DECOMPRESSION_FAILED:
127 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_DECOMPRESSION_FAILURE);
128 break;
129 case GNUTLS_E_ILLEGAL_PARAMETER:
130 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_ILLEGAL_PARAMETER);
131 break;
132 case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND:
133 case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND:
134 case GNUTLS_E_ASN1_DER_ERROR:
135 case GNUTLS_E_ASN1_VALUE_NOT_FOUND:
136 case GNUTLS_E_ASN1_GENERIC_ERROR:
137 case GNUTLS_E_ASN1_VALUE_NOT_VALID:
138 case GNUTLS_E_ASN1_TAG_ERROR:
139 case GNUTLS_E_ASN1_TAG_IMPLICIT:
140 case GNUTLS_E_ASN1_TYPE_ANY_ERROR:
141 case GNUTLS_E_ASN1_SYNTAX_ERROR:
142 case GNUTLS_E_ASN1_DER_OVERFLOW:
143 case GNUTLS_E_NO_CERTIFICATE_FOUND:
144 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
145 break;
146 case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
147 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_HANDSHAKE_FAILURE);
148 break;
149 case GNUTLS_E_UNEXPECTED_PACKET:
150 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_UNEXPECTED_MESSAGE);
151 break;
152 case GNUTLS_E_REHANDSHAKE:
153 ret = gnutls_alert_send( state, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION);
154 break;
155 case GNUTLS_E_UNSUPPORTED_VERSION_PACKET:
156 ret = gnutls_alert_send( state, GNUTLS_AL_WARNING, GNUTLS_A_PROTOCOL_VERSION);
157 break;
158 case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE:
159 ret = gnutls_alert_send( state, GNUTLS_AL_WARNING, GNUTLS_A_UNSUPPORTED_CERTIFICATE);
160 break;
161 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
162 ret = gnutls_alert_send( state, GNUTLS_AL_FATAL, GNUTLS_A_RECORD_OVERFLOW);
163 break;
165 return ret;
169 * gnutls_alert_get - Returns the last alert number received.
170 * @state: is a &GNUTLS_STATE structure.
172 * Returns the last alert number received. This function
173 * should be called if GNUTLS_E_WARNING_ALERT_RECEIVED or
174 * GNUTLS_E_FATAL_ALERT_RECEIVED has been returned by a gnutls function.
175 * The peer may send alerts if he thinks some things were not
176 * right. Check gnutls.h for the available alert descriptions.
178 GNUTLS_AlertDescription gnutls_alert_get( GNUTLS_STATE state) {
179 return state->gnutls_internals.last_alert;
183 * gnutls_alert_get_name - Returns a string describing the alert number given
184 * @alert: is an alert number &GNUTLS_STATE structure.
186 * Returns a string that describes the given alert number.
187 * See. gnutls_alert_get().
190 const char* gnutls_alert_get_name( int alert) {
191 char* ret = NULL;
193 GNUTLS_ALERT_ID_LOOP( ret = p->desc);
195 return ret;