Annotation of embedaddon/strongswan/src/libtls/tls_alert.c, revision 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>