Annotation of embedaddon/strongswan/src/libtls/tls_alert.c, revision 1.1.1.2

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: );
1.1.1.2 ! misho      66: ENUM_NEXT(tls_alert_desc_names, TLS_INAPPROPRIATE_FALLBACK,
        !            67:                TLS_INAPPROPRIATE_FALLBACK, TLS_INTERNAL_ERROR,
        !            68:        "inappropriate fallback",
        !            69: );
1.1       misho      70: ENUM_NEXT(tls_alert_desc_names, TLS_USER_CANCELED, TLS_USER_CANCELED,
1.1.1.2 ! misho      71:                TLS_INAPPROPRIATE_FALLBACK,
1.1       misho      72:        "user canceled",
                     73: );
                     74: ENUM_NEXT(tls_alert_desc_names, TLS_NO_RENEGOTIATION, TLS_NO_RENEGOTIATION,
                     75:                TLS_USER_CANCELED,
                     76:        "no renegotiation",
                     77: );
1.1.1.2 ! misho      78: ENUM_NEXT(tls_alert_desc_names, TLS_MISSING_EXTENSION, TLS_CERTIFICATE_REQUIRED,
1.1       misho      79:                TLS_NO_RENEGOTIATION,
1.1.1.2 ! misho      80:        "missing extensions",
1.1       misho      81:        "unsupported extension",
1.1.1.2 ! misho      82:        "certificate unobtainable",
        !            83:        "recognized name",
        !            84:        "bad certificate status response",
        !            85:        "bad certificate hash value",
        !            86:        "unknown psk identity",
        !            87:        "certificate required",
        !            88: );
        !            89: ENUM_NEXT(tls_alert_desc_names, TLS_NO_APPLICATION_PROTOCOL,
        !            90:                TLS_NO_APPLICATION_PROTOCOL, TLS_CERTIFICATE_REQUIRED,
        !            91:        "no application protocol"
1.1       misho      92: );
1.1.1.2 ! misho      93: ENUM_END(tls_alert_desc_names, TLS_NO_APPLICATION_PROTOCOL);
1.1       misho      94: 
                     95: 
                     96: typedef struct private_tls_alert_t private_tls_alert_t;
                     97: 
                     98: /**
                     99:  * Private data of an tls_alert_t object.
                    100:  */
                    101: struct private_tls_alert_t {
                    102: 
                    103:        /**
                    104:         * Public tls_alert_t interface.
                    105:         */
                    106:        tls_alert_t public;
                    107: 
                    108:        /**
                    109:         * Warning queue
                    110:         */
                    111:        linked_list_t *warnings;
                    112: 
                    113:        /**
                    114:         * Do we have a fatal alert?
                    115:         */
                    116:        bool fatal;
                    117: 
                    118:        /**
                    119:         * Has the fatal alert been consumed?
                    120:         */
                    121:        bool consumed;
                    122: 
                    123:        /**
                    124:         * Fatal alert description
                    125:         */
                    126:        tls_alert_desc_t desc;
                    127: };
                    128: 
                    129: METHOD(tls_alert_t, add, void,
                    130:        private_tls_alert_t *this, tls_alert_level_t level,
                    131:        tls_alert_desc_t desc)
                    132: {
                    133:        if (level == TLS_FATAL)
                    134:        {
                    135:                if (!this->fatal)
                    136:                {
                    137:                        this->desc = desc;
                    138:                        this->fatal = TRUE;
                    139:                }
                    140:        }
                    141:        else
                    142:        {
                    143:                this->warnings->insert_last(this->warnings, (void*)(uintptr_t)desc);
                    144:        }
                    145: }
                    146: 
                    147: METHOD(tls_alert_t, get, bool,
                    148:        private_tls_alert_t *this, tls_alert_level_t *level,
                    149:        tls_alert_desc_t *desc)
                    150: {
                    151:        if (this->fatal && !this->consumed)
                    152:        {
                    153:                this->consumed = TRUE;
                    154:                *level = TLS_FATAL;
                    155:                *desc = this->desc;
                    156:                if (this->desc == TLS_CLOSE_NOTIFY)
                    157:                {
                    158:                        DBG1(DBG_TLS, "sending TLS close notify");
                    159:                }
                    160:                else
                    161:                {
                    162:                        DBG1(DBG_TLS, "sending fatal TLS alert '%N'",
                    163:                                 tls_alert_desc_names, this->desc);
                    164:                }
                    165:                return TRUE;
                    166:        }
                    167:        else
                    168:        {
                    169:                uintptr_t warning;
                    170: 
                    171:                if (this->warnings->remove_first(this->warnings,
                    172:                                                                                 (void**)&warning) == SUCCESS)
                    173:                {
                    174:                        *level = TLS_WARNING;
                    175:                        *desc = warning;
                    176:                        DBG1(DBG_TLS, "sending TLS alert warning '%N'",
                    177:                                 tls_alert_desc_names, warning);
                    178:                        return TRUE;
                    179:                }
                    180:        }
                    181:        return FALSE;
                    182: }
                    183: 
                    184: METHOD(tls_alert_t, fatal, bool,
                    185:        private_tls_alert_t *this)
                    186: {
                    187:        return this->fatal;
                    188: }
                    189: 
                    190: METHOD(tls_alert_t, process, status_t,
                    191:        private_tls_alert_t *this, tls_alert_level_t level,
                    192:        tls_alert_desc_t desc)
                    193: {
                    194:        if (desc == TLS_CLOSE_NOTIFY)
                    195:        {
                    196:                DBG1(DBG_TLS, "received TLS close notify");
                    197:                add(this, TLS_FATAL, TLS_CLOSE_NOTIFY);
                    198:                return NEED_MORE;
                    199:        }
                    200:        switch (level)
                    201:        {
                    202:                case TLS_WARNING:
                    203:                        DBG1(DBG_TLS, "received TLS alert warning '%N'",
                    204:                                 tls_alert_desc_names, desc);
                    205:                        return NEED_MORE;
                    206:                case TLS_FATAL:
                    207:                        DBG1(DBG_TLS, "received fatal TLS alert '%N'",
                    208:                                 tls_alert_desc_names, desc);
                    209:                        return FAILED;
                    210:                default:
                    211:                        DBG1(DBG_TLS, "received unknown TLS alert '%N'",
                    212:                                 tls_alert_desc_names, desc);
                    213:                        return FAILED;
                    214:        }
                    215: }
                    216: 
                    217: METHOD(tls_alert_t, destroy, void,
                    218:        private_tls_alert_t *this)
                    219: {
                    220:        this->warnings->destroy(this->warnings);
                    221:        free(this);
                    222: }
                    223: 
                    224: /**
                    225:  * See header
                    226:  */
                    227: tls_alert_t *tls_alert_create()
                    228: {
                    229:        private_tls_alert_t *this;
                    230: 
                    231:        INIT(this,
                    232:                .public = {
                    233:                        .add = _add,
                    234:                        .get = _get,
                    235:                        .fatal = _fatal,
                    236:                        .process = _process,
                    237:                        .destroy = _destroy,
                    238:                },
                    239:                .warnings = linked_list_create(),
                    240:        );
                    241: 
                    242:        return &this->public;
                    243: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>