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>