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>