Annotation of embedaddon/strongswan/src/libtls/tls_alert.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2010 Martin Willi
3: * Copyright (C) 2010 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "tls_alert.h"
17:
18: #include <utils/debug.h>
19: #include <collections/linked_list.h>
20:
21: ENUM_BEGIN(tls_alert_desc_names, TLS_CLOSE_NOTIFY, TLS_CLOSE_NOTIFY,
22: "close notify",
23: );
24: ENUM_NEXT(tls_alert_desc_names, TLS_UNEXPECTED_MESSAGE, TLS_UNEXPECTED_MESSAGE,
25: TLS_CLOSE_NOTIFY,
26: "unexpected message",
27: );
28: ENUM_NEXT(tls_alert_desc_names, TLS_BAD_RECORD_MAC, TLS_RECORD_OVERFLOW,
29: TLS_UNEXPECTED_MESSAGE,
30: "bad record mac",
31: "decryption failed",
32: "record overflow",
33: );
34: ENUM_NEXT(tls_alert_desc_names, TLS_DECOMPRESSION_FAILURE, TLS_DECOMPRESSION_FAILURE,
35: TLS_RECORD_OVERFLOW,
36: "decompression_failure",
37: );
38: ENUM_NEXT(tls_alert_desc_names, TLS_HANDSHAKE_FAILURE, TLS_DECRYPT_ERROR,
39: TLS_DECOMPRESSION_FAILURE,
40: "handshake failure",
41: "no certificate",
42: "bad certificate",
43: "unsupported certificate",
44: "certificate revoked",
45: "certificate expired",
46: "certificate unknown",
47: "illegal parameter",
48: "unknown ca",
49: "access denied",
50: "decode error",
51: "decrypt error",
52: );
53: ENUM_NEXT(tls_alert_desc_names, TLS_EXPORT_RESTRICTION, TLS_EXPORT_RESTRICTION,
54: TLS_DECRYPT_ERROR,
55: "export restriction",
56: );
57: ENUM_NEXT(tls_alert_desc_names, TLS_PROTOCOL_VERSION, TLS_INSUFFICIENT_SECURITY,
58: TLS_EXPORT_RESTRICTION,
59: "protocol version",
60: "insufficient security",
61: );
62: ENUM_NEXT(tls_alert_desc_names, TLS_INTERNAL_ERROR, TLS_INTERNAL_ERROR,
63: TLS_INSUFFICIENT_SECURITY,
64: "internal error",
65: );
66: ENUM_NEXT(tls_alert_desc_names, TLS_USER_CANCELED, TLS_USER_CANCELED,
67: TLS_INTERNAL_ERROR,
68: "user canceled",
69: );
70: ENUM_NEXT(tls_alert_desc_names, TLS_NO_RENEGOTIATION, TLS_NO_RENEGOTIATION,
71: TLS_USER_CANCELED,
72: "no renegotiation",
73: );
74: ENUM_NEXT(tls_alert_desc_names, TLS_UNSUPPORTED_EXTENSION, TLS_UNSUPPORTED_EXTENSION,
75: TLS_NO_RENEGOTIATION,
76: "unsupported extension",
77: );
78: ENUM_END(tls_alert_desc_names, TLS_UNSUPPORTED_EXTENSION);
79:
80:
81: typedef struct private_tls_alert_t private_tls_alert_t;
82:
83: /**
84: * Private data of an tls_alert_t object.
85: */
86: struct private_tls_alert_t {
87:
88: /**
89: * Public tls_alert_t interface.
90: */
91: tls_alert_t public;
92:
93: /**
94: * Warning queue
95: */
96: linked_list_t *warnings;
97:
98: /**
99: * Do we have a fatal alert?
100: */
101: bool fatal;
102:
103: /**
104: * Has the fatal alert been consumed?
105: */
106: bool consumed;
107:
108: /**
109: * Fatal alert description
110: */
111: tls_alert_desc_t desc;
112: };
113:
114: METHOD(tls_alert_t, add, void,
115: private_tls_alert_t *this, tls_alert_level_t level,
116: tls_alert_desc_t desc)
117: {
118: if (level == TLS_FATAL)
119: {
120: if (!this->fatal)
121: {
122: this->desc = desc;
123: this->fatal = TRUE;
124: }
125: }
126: else
127: {
128: this->warnings->insert_last(this->warnings, (void*)(uintptr_t)desc);
129: }
130: }
131:
132: METHOD(tls_alert_t, get, bool,
133: private_tls_alert_t *this, tls_alert_level_t *level,
134: tls_alert_desc_t *desc)
135: {
136: if (this->fatal && !this->consumed)
137: {
138: this->consumed = TRUE;
139: *level = TLS_FATAL;
140: *desc = this->desc;
141: if (this->desc == TLS_CLOSE_NOTIFY)
142: {
143: DBG1(DBG_TLS, "sending TLS close notify");
144: }
145: else
146: {
147: DBG1(DBG_TLS, "sending fatal TLS alert '%N'",
148: tls_alert_desc_names, this->desc);
149: }
150: return TRUE;
151: }
152: else
153: {
154: uintptr_t warning;
155:
156: if (this->warnings->remove_first(this->warnings,
157: (void**)&warning) == SUCCESS)
158: {
159: *level = TLS_WARNING;
160: *desc = warning;
161: DBG1(DBG_TLS, "sending TLS alert warning '%N'",
162: tls_alert_desc_names, warning);
163: return TRUE;
164: }
165: }
166: return FALSE;
167: }
168:
169: METHOD(tls_alert_t, fatal, bool,
170: private_tls_alert_t *this)
171: {
172: return this->fatal;
173: }
174:
175: METHOD(tls_alert_t, process, status_t,
176: private_tls_alert_t *this, tls_alert_level_t level,
177: tls_alert_desc_t desc)
178: {
179: if (desc == TLS_CLOSE_NOTIFY)
180: {
181: DBG1(DBG_TLS, "received TLS close notify");
182: add(this, TLS_FATAL, TLS_CLOSE_NOTIFY);
183: return NEED_MORE;
184: }
185: switch (level)
186: {
187: case TLS_WARNING:
188: DBG1(DBG_TLS, "received TLS alert warning '%N'",
189: tls_alert_desc_names, desc);
190: return NEED_MORE;
191: case TLS_FATAL:
192: DBG1(DBG_TLS, "received fatal TLS alert '%N'",
193: tls_alert_desc_names, desc);
194: return FAILED;
195: default:
196: DBG1(DBG_TLS, "received unknown TLS alert '%N'",
197: tls_alert_desc_names, desc);
198: return FAILED;
199: }
200: }
201:
202: METHOD(tls_alert_t, destroy, void,
203: private_tls_alert_t *this)
204: {
205: this->warnings->destroy(this->warnings);
206: free(this);
207: }
208:
209: /**
210: * See header
211: */
212: tls_alert_t *tls_alert_create()
213: {
214: private_tls_alert_t *this;
215:
216: INIT(this,
217: .public = {
218: .add = _add,
219: .get = _get,
220: .fatal = _fatal,
221: .process = _process,
222: .destroy = _destroy,
223: },
224: .warnings = linked_list_create(),
225: );
226:
227: return &this->public;
228: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>