Annotation of embedaddon/strongswan/src/libstrongswan/plugins/acert/acert_validator.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2014 Martin Willi
        !             3:  * Copyright (C) 2014 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: #define _GNU_SOURCE
        !            17: #include <library.h>
        !            18: 
        !            19: #include "acert_validator.h"
        !            20: 
        !            21: #include <credentials/certificates/x509.h>
        !            22: #include <credentials/certificates/ac.h>
        !            23: 
        !            24: typedef struct private_acert_validator_t private_acert_validator_t;
        !            25: 
        !            26: /**
        !            27:  * Private data of an acert_validator_t object.
        !            28:  */
        !            29: struct private_acert_validator_t {
        !            30: 
        !            31:        /**
        !            32:         * Public acert_validator_t interface.
        !            33:         */
        !            34:        acert_validator_t public;
        !            35: };
        !            36: 
        !            37: /**
        !            38:  * Check if an AC can be trusted
        !            39:  */
        !            40: static bool verify(private_acert_validator_t *this, certificate_t *ac)
        !            41: {
        !            42:        certificate_t *issuer;
        !            43:        enumerator_t *enumerator;
        !            44:        bool verified = FALSE;
        !            45: 
        !            46:        if (!ac->get_validity(ac, NULL, NULL, NULL))
        !            47:        {
        !            48:                return FALSE;
        !            49:        }
        !            50:        DBG1(DBG_CFG, "verifying attribute certificate issued by \"%Y\"",
        !            51:                 ac->get_issuer(ac));
        !            52:        enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
        !            53:                                                                                                        ac->get_issuer(ac), TRUE);
        !            54:        while (enumerator->enumerate(enumerator, &issuer, NULL))
        !            55:        {
        !            56:                if (issuer->get_validity(issuer, NULL, NULL, NULL))
        !            57:                {
        !            58:                        if (lib->credmgr->issued_by(lib->credmgr, ac, issuer, NULL))
        !            59:                        {
        !            60:                                verified = TRUE;
        !            61:                                break;
        !            62:                        }
        !            63:                }
        !            64:        }
        !            65:        enumerator->destroy(enumerator);
        !            66: 
        !            67:        return verified;
        !            68: }
        !            69: 
        !            70: /**
        !            71:  * Apply AC group membership to auth config
        !            72:  */
        !            73: static void apply(private_acert_validator_t *this, ac_t *ac, auth_cfg_t *auth)
        !            74: {
        !            75:        enumerator_t *enumerator;
        !            76:        ac_group_type_t type;
        !            77:        chunk_t chunk;
        !            78: 
        !            79:        enumerator = ac->create_group_enumerator(ac);
        !            80:        while (enumerator->enumerate(enumerator, &type, &chunk))
        !            81:        {
        !            82:                if (type == AC_GROUP_TYPE_STRING)
        !            83:                {
        !            84:                        auth->add(auth, AUTH_RULE_GROUP,
        !            85:                                          identification_create_from_data(chunk));
        !            86:                }
        !            87:        }
        !            88:        enumerator->destroy(enumerator);
        !            89: }
        !            90: 
        !            91: METHOD(cert_validator_t, validate, bool,
        !            92:        private_acert_validator_t *this, certificate_t *subject,
        !            93:        certificate_t *issuer, bool online, u_int pathlen, bool anchor,
        !            94:        auth_cfg_t *auth)
        !            95: {
        !            96:        /* for X.509 end entity certs only */
        !            97:        if (pathlen == 0 && subject->get_type(subject) == CERT_X509)
        !            98:        {
        !            99:                x509_t *x509 = (x509_t*)subject;
        !           100:                enumerator_t *enumerator;
        !           101:                identification_t *id, *serial;
        !           102:                ac_t *ac;
        !           103: 
        !           104:                /* find attribute certificates by serial and issuer. A lookup by
        !           105:                 * the holder DN would work as well, but RFC 5755 recommends the use
        !           106:                 * of baseCertificateID. */
        !           107:                serial = identification_create_from_encoding(ID_KEY_ID,
        !           108:                                                                                                         x509->get_serial(x509));
        !           109:                enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
        !           110:                                                                                CERT_X509_AC, KEY_ANY, serial, FALSE);
        !           111:                while (enumerator->enumerate(enumerator, &ac))
        !           112:                {
        !           113:                        id = ac->get_holderIssuer(ac);
        !           114:                        if (id && id->equals(id, subject->get_issuer(subject)))
        !           115:                        {
        !           116:                                if (verify(this, &ac->certificate))
        !           117:                                {
        !           118:                                        apply(this, ac, auth);
        !           119:                                }
        !           120:                        }
        !           121:                }
        !           122:                enumerator->destroy(enumerator);
        !           123:                serial->destroy(serial);
        !           124:        }
        !           125:        return TRUE;
        !           126: }
        !           127: 
        !           128: METHOD(acert_validator_t, destroy, void,
        !           129:        private_acert_validator_t *this)
        !           130: {
        !           131:        free(this);
        !           132: }
        !           133: 
        !           134: /**
        !           135:  * See header
        !           136:  */
        !           137: acert_validator_t *acert_validator_create()
        !           138: {
        !           139:        private_acert_validator_t *this;
        !           140: 
        !           141:        INIT(this,
        !           142:                .public = {
        !           143:                        .validator.validate = _validate,
        !           144:                        .destroy = _destroy,
        !           145:                },
        !           146:        );
        !           147: 
        !           148:        return &this->public;
        !           149: }

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