Annotation of embedaddon/strongswan/src/libstrongswan/plugins/constraints/constraints_validator.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 "constraints_validator.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: #include <asn1/asn1.h>
                     20: #include <collections/linked_list.h>
                     21: #include <credentials/certificates/x509.h>
                     22: 
                     23: typedef struct private_constraints_validator_t private_constraints_validator_t;
                     24: 
                     25: /**
                     26:  * Private data of an constraints_validator_t object.
                     27:  */
                     28: struct private_constraints_validator_t {
                     29: 
                     30:        /**
                     31:         * Public constraints_validator_t interface.
                     32:         */
                     33:        constraints_validator_t public;
                     34: };
                     35: 
                     36: /**
                     37:  * Check pathlen constraint of issuer certificate
                     38:  */
                     39: static bool check_pathlen(x509_t *issuer, int pathlen)
                     40: {
                     41:        u_int pathlen_constraint;
                     42: 
                     43:        pathlen_constraint = issuer->get_constraint(issuer, X509_PATH_LEN);
                     44:        if (pathlen_constraint != X509_NO_CONSTRAINT &&
                     45:                pathlen > pathlen_constraint)
                     46:        {
                     47:                DBG1(DBG_CFG, "path length of %d violates constraint of %d",
                     48:                         pathlen, pathlen_constraint);
                     49:                return FALSE;
                     50:        }
                     51:        return TRUE;
                     52: }
                     53: 
                     54: /**
                     55:  * Check if a FQDN constraint matches
                     56:  */
                     57: static bool fqdn_matches(identification_t *constraint, identification_t *id)
                     58: {
                     59:        chunk_t c, i, diff;
                     60: 
                     61:        c = constraint->get_encoding(constraint);
                     62:        i = id->get_encoding(id);
                     63: 
                     64:        if (!c.len || i.len < c.len)
                     65:        {
                     66:                return FALSE;
                     67:        }
                     68:        diff = chunk_create(i.ptr, i.len - c.len);
                     69:        if (!chunk_equals(c, chunk_skip(i, diff.len)))
                     70:        {
                     71:                return FALSE;
                     72:        }
                     73:        if (!diff.len)
                     74:        {
                     75:                return TRUE;
                     76:        }
                     77:        if (c.ptr[0] == '.' || diff.ptr[diff.len - 1] == '.')
                     78:        {
                     79:                return TRUE;
                     80:        }
                     81:        return FALSE;
                     82: }
                     83: 
                     84: /**
                     85:  * Check if a RFC822 constraint matches
                     86:  */
                     87: static bool email_matches(identification_t *constraint, identification_t *id)
                     88: {
                     89:        chunk_t c, i, diff;
                     90: 
                     91:        c = constraint->get_encoding(constraint);
                     92:        i = id->get_encoding(id);
                     93: 
                     94:        if (!c.len || i.len < c.len)
                     95:        {
                     96:                return FALSE;
                     97:        }
                     98:        if (memchr(c.ptr, '@', c.len))
                     99:        {       /* constraint is a full email address */
                    100:                return chunk_equals(c, i);
                    101:        }
                    102:        diff = chunk_create(i.ptr, i.len - c.len);
                    103:        if (!diff.len || !chunk_equals(c, chunk_skip(i, diff.len)))
                    104:        {
                    105:                return FALSE;
                    106:        }
                    107:        if (c.ptr[0] == '.')
                    108:        {       /* constraint is domain, suffix match */
                    109:                return TRUE;
                    110:        }
                    111:        if (diff.ptr[diff.len - 1] == '@')
                    112:        {       /* constraint is host specific, only username can be appended */
                    113:                return TRUE;
                    114:        }
                    115:        return FALSE;
                    116: }
                    117: 
                    118: /**
                    119:  * Check if a DN constraint matches (RDN prefix match)
                    120:  */
                    121: static bool dn_matches(identification_t *constraint, identification_t *id)
                    122: {
                    123:        enumerator_t *ec, *ei;
                    124:        id_part_t pc, pi;
                    125:        chunk_t cc, ci;
                    126:        bool match = TRUE;
                    127: 
                    128:        ec = constraint->create_part_enumerator(constraint);
                    129:        ei = id->create_part_enumerator(id);
                    130:        while (ec->enumerate(ec, &pc, &cc))
                    131:        {
                    132:                if (!ei->enumerate(ei, &pi, &ci) ||
                    133:                        pi != pc || !chunk_equals(cc, ci))
                    134:                {
                    135:                        match = FALSE;
                    136:                        break;
                    137:                }
                    138:        }
                    139:        ec->destroy(ec);
                    140:        ei->destroy(ei);
                    141: 
                    142:        return match;
                    143: }
                    144: 
                    145: /**
                    146:  * Check if a certificate matches to a NameConstraint
                    147:  */
                    148: static bool name_constraint_matches(identification_t *constraint,
                    149:                                                                        certificate_t *cert, bool permitted)
                    150: {
                    151:        x509_t *x509 = (x509_t*)cert;
                    152:        enumerator_t *enumerator;
                    153:        identification_t *id;
                    154:        id_type_t type;
                    155:        bool matches = permitted;
                    156: 
                    157:        type = constraint->get_type(constraint);
                    158:        if (type == ID_DER_ASN1_DN)
                    159:        {
                    160:                matches = dn_matches(constraint, cert->get_subject(cert));
                    161:                if (matches != permitted)
                    162:                {
                    163:                        return matches;
                    164:                }
                    165:        }
                    166: 
                    167:        enumerator = x509->create_subjectAltName_enumerator(x509);
                    168:        while (enumerator->enumerate(enumerator, &id))
                    169:        {
                    170:                if (id->get_type(id) == type)
                    171:                {
                    172:                        switch (type)
                    173:                        {
                    174:                                case ID_FQDN:
                    175:                                        matches = fqdn_matches(constraint, id);
                    176:                                        break;
                    177:                                case ID_RFC822_ADDR:
                    178:                                        matches = email_matches(constraint, id);
                    179:                                        break;
                    180:                                case ID_DER_ASN1_DN:
                    181:                                        matches = dn_matches(constraint, id);
                    182:                                        break;
                    183:                                default:
                    184:                                        DBG1(DBG_CFG, "%N NameConstraint matching not implemented",
                    185:                                                 id_type_names, type);
                    186:                                        matches = FALSE;
                    187:                                        break;
                    188:                        }
                    189:                }
                    190:                if (matches != permitted)
                    191:                {
                    192:                        break;
                    193:                }
                    194:        }
                    195:        enumerator->destroy(enumerator);
                    196: 
                    197:        return matches;
                    198: }
                    199: 
                    200: /**
                    201:  * Check if a permitted or excluded NameConstraint has been inherited to sub-CA
                    202:  */
                    203: static bool name_constraint_inherited(identification_t *constraint,
                    204:                                                                          x509_t *x509, bool permitted)
                    205: {
                    206:        enumerator_t *enumerator;
                    207:        identification_t *id, *a, *b;
                    208:        bool inherited = FALSE;
                    209:        id_type_t type;
                    210: 
                    211:        if (!(x509->get_flags(x509) & X509_CA))
                    212:        {       /* not a sub-CA, not required */
                    213:                return TRUE;
                    214:        }
                    215: 
                    216:        type = constraint->get_type(constraint);
                    217:        enumerator = x509->create_name_constraint_enumerator(x509, permitted);
                    218:        while (enumerator->enumerate(enumerator, &id))
                    219:        {
                    220:                if (id->get_type(id) == type)
                    221:                {
                    222:                        if (permitted)
                    223:                        {       /* permitted constraint can be narrowed */
                    224:                                a = constraint;
                    225:                                b = id;
                    226:                        }
                    227:                        else
                    228:                        {       /* excluded constraint can be widened */
                    229:                                a = id;
                    230:                                b = constraint;
                    231:                        }
                    232:                        switch (type)
                    233:                        {
                    234:                                case ID_FQDN:
                    235:                                        inherited = fqdn_matches(a, b);
                    236:                                        break;
                    237:                                case ID_RFC822_ADDR:
                    238:                                        inherited = email_matches(a, b);
                    239:                                        break;
                    240:                                case ID_DER_ASN1_DN:
                    241:                                        inherited = dn_matches(a, b);
                    242:                                        break;
                    243:                                default:
                    244:                                        DBG1(DBG_CFG, "%N NameConstraint matching not implemented",
                    245:                                                 id_type_names, type);
                    246:                                        inherited = FALSE;
                    247:                                        break;
                    248:                        }
                    249:                }
                    250:                if (inherited)
                    251:                {
                    252:                        break;
                    253:                }
                    254:        }
                    255:        enumerator->destroy(enumerator);
                    256:        return inherited;
                    257: }
                    258: 
                    259: /**
                    260:  * Check name constraints
                    261:  */
                    262: static bool check_name_constraints(certificate_t *subject, x509_t *issuer)
                    263: {
                    264:        enumerator_t *enumerator;
                    265:        identification_t *constraint;
                    266: 
                    267:        enumerator = issuer->create_name_constraint_enumerator(issuer, TRUE);
                    268:        while (enumerator->enumerate(enumerator, &constraint))
                    269:        {
                    270:                if (!name_constraint_matches(constraint, subject, TRUE))
                    271:                {
                    272:                        DBG1(DBG_CFG, "certificate '%Y' does not match permitted name "
                    273:                                 "constraint '%Y'", subject->get_subject(subject), constraint);
                    274:                        enumerator->destroy(enumerator);
                    275:                        return FALSE;
                    276:                }
                    277:                if (!name_constraint_inherited(constraint, (x509_t*)subject, TRUE))
                    278:                {
                    279:                        DBG1(DBG_CFG, "intermediate CA '%Y' does not inherit permitted name "
                    280:                                 "constraint '%Y'", subject->get_subject(subject), constraint);
                    281:                        enumerator->destroy(enumerator);
                    282:                        return FALSE;
                    283:                }
                    284:        }
                    285:        enumerator->destroy(enumerator);
                    286: 
                    287:        enumerator = issuer->create_name_constraint_enumerator(issuer, FALSE);
                    288:        while (enumerator->enumerate(enumerator, &constraint))
                    289:        {
                    290:                if (name_constraint_matches(constraint, subject, FALSE))
                    291:                {
                    292:                        DBG1(DBG_CFG, "certificate '%Y' matches excluded name "
                    293:                                 "constraint '%Y'", subject->get_subject(subject), constraint);
                    294:                        enumerator->destroy(enumerator);
                    295:                        return FALSE;
                    296:                }
                    297:                if (!name_constraint_inherited(constraint, (x509_t*)subject, FALSE))
                    298:                {
                    299:                        DBG1(DBG_CFG, "intermediate CA '%Y' does not inherit excluded name "
                    300:                                 "constraint '%Y'", subject->get_subject(subject), constraint);
                    301:                        enumerator->destroy(enumerator);
                    302:                        return FALSE;
                    303:                }
                    304:        }
                    305:        enumerator->destroy(enumerator);
                    306:        return TRUE;
                    307: }
                    308: 
                    309: /**
                    310:  * Special OID for anyPolicy
                    311:  */
                    312: static chunk_t any_policy = chunk_from_chars(0x55,0x1d,0x20,0x00);
                    313: 
                    314: /**
                    315:  * Check if an issuer certificate has a given policy OID
                    316:  */
                    317: static bool has_policy(x509_t *issuer, chunk_t oid)
                    318: {
                    319:        x509_policy_mapping_t *mapping;
                    320:        x509_cert_policy_t *policy;
                    321:        enumerator_t *enumerator;
                    322: 
                    323:        enumerator = issuer->create_cert_policy_enumerator(issuer);
                    324:        while (enumerator->enumerate(enumerator, &policy))
                    325:        {
                    326:                if (chunk_equals(oid, policy->oid) ||
                    327:                        chunk_equals(any_policy, policy->oid))
                    328:                {
                    329:                        enumerator->destroy(enumerator);
                    330:                        return TRUE;
                    331:                }
                    332:        }
                    333:        enumerator->destroy(enumerator);
                    334: 
                    335:        /* fall back to a mapped policy */
                    336:        enumerator = issuer->create_policy_mapping_enumerator(issuer);
                    337:        while (enumerator->enumerate(enumerator, &mapping))
                    338:        {
                    339:                if (chunk_equals(mapping->subject, oid))
                    340:                {
                    341:                        enumerator->destroy(enumerator);
                    342:                        return TRUE;
                    343:                }
                    344:        }
                    345:        enumerator->destroy(enumerator);
                    346:        return FALSE;
                    347: }
                    348: 
                    349: /**
                    350:  * Check certificatePolicies.
                    351:  */
                    352: static bool check_policy(x509_t *subject, x509_t *issuer)
                    353: {
                    354:        certificate_t *cert = (certificate_t*)subject;
                    355:        x509_policy_mapping_t *mapping;
                    356:        x509_cert_policy_t *policy;
                    357:        enumerator_t *enumerator;
                    358:        char *oid;
                    359: 
                    360:        /* verify if policyMappings in subject are valid */
                    361:        enumerator = subject->create_policy_mapping_enumerator(subject);
                    362:        while (enumerator->enumerate(enumerator, &mapping))
                    363:        {
                    364:                if (!has_policy(issuer, mapping->issuer))
                    365:                {
                    366:                        oid = asn1_oid_to_string(mapping->issuer);
                    367:                        DBG1(DBG_CFG, "certificate '%Y' maps policy from %s, but issuer "
                    368:                                 "misses it", cert->get_subject(cert), oid);
                    369:                        free(oid);
                    370:                        enumerator->destroy(enumerator);
                    371:                        return FALSE;
                    372:                }
                    373:        }
                    374:        enumerator->destroy(enumerator);
                    375: 
                    376:        enumerator = subject->create_cert_policy_enumerator(subject);
                    377:        while (enumerator->enumerate(enumerator, &policy))
                    378:        {
                    379:                if (!has_policy(issuer, policy->oid))
                    380:                {
                    381:                        oid = asn1_oid_to_string(policy->oid);
                    382:                        DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
                    383:                                 oid, cert->get_issuer(cert));
                    384:                        free(oid);
                    385:                        enumerator->destroy(enumerator);
                    386:                        return FALSE;
                    387:                }
                    388:        }
                    389:        enumerator->destroy(enumerator);
                    390: 
                    391:        return TRUE;
                    392: }
                    393: 
                    394: /**
                    395:  * Check if a given policy is valid under a trustchain
                    396:  */
                    397: static bool is_policy_valid(linked_list_t *chain, chunk_t oid)
                    398: {
                    399:        x509_policy_mapping_t *mapping;
                    400:        x509_cert_policy_t *policy;
                    401:        x509_t *issuer;
                    402:        enumerator_t *issuers, *policies, *mappings;
                    403:        bool found = TRUE;
                    404: 
                    405:        issuers = chain->create_enumerator(chain);
                    406:        while (issuers->enumerate(issuers, &issuer))
                    407:        {
                    408:                int maxmap = 8;
                    409: 
                    410:                while (found)
                    411:                {
                    412:                        found = FALSE;
                    413: 
                    414:                        policies = issuer->create_cert_policy_enumerator(issuer);
                    415:                        while (policies->enumerate(policies, &policy))
                    416:                        {
                    417:                                if (chunk_equals(oid, policy->oid) ||
                    418:                                        chunk_equals(any_policy, policy->oid))
                    419:                                {
                    420:                                        found = TRUE;
                    421:                                        break;
                    422:                                }
                    423:                        }
                    424:                        policies->destroy(policies);
                    425:                        if (found)
                    426:                        {
                    427:                                break;
                    428:                        }
                    429:                        /* fall back to a mapped policy */
                    430:                        mappings = issuer->create_policy_mapping_enumerator(issuer);
                    431:                        while (mappings->enumerate(mappings, &mapping))
                    432:                        {
                    433:                                if (chunk_equals(mapping->subject, oid))
                    434:                                {
                    435:                                        oid = mapping->issuer;
                    436:                                        found = TRUE;
                    437:                                        break;
                    438:                                }
                    439:                        }
                    440:                        mappings->destroy(mappings);
                    441:                        if (--maxmap == 0)
                    442:                        {
                    443:                                found = FALSE;
                    444:                                break;
                    445:                        }
                    446:                }
                    447:                if (!found)
                    448:                {
                    449:                        break;
                    450:                }
                    451:        }
                    452:        issuers->destroy(issuers);
                    453: 
                    454:        return found;
                    455: }
                    456: 
                    457: /**
                    458:  * Check len certificates in trustchain for inherited policies
                    459:  */
                    460: static bool has_policy_chain(linked_list_t *chain, x509_t *subject, int len)
                    461: {
                    462:        enumerator_t *enumerator;
                    463:        x509_t *issuer;
                    464:        bool valid = TRUE;
                    465: 
                    466:        enumerator = chain->create_enumerator(chain);
                    467:        while (len-- > 0 && enumerator->enumerate(enumerator, &issuer))
                    468:        {
                    469:                if (!check_policy(subject, issuer))
                    470:                {
                    471:                        valid = FALSE;
                    472:                        break;
                    473:                }
                    474:                subject = issuer;
                    475:        }
                    476:        enumerator->destroy(enumerator);
                    477:        return valid;
                    478: }
                    479: 
                    480: /**
                    481:  * Check len certificates in trustchain to have no policyMappings
                    482:  */
                    483: static bool has_no_policy_mapping(linked_list_t *chain, int len)
                    484: {
                    485:        enumerator_t *enumerator, *mappings;
                    486:        x509_policy_mapping_t *mapping;
                    487:        certificate_t *cert;
                    488:        x509_t *x509;
                    489:        bool valid = TRUE;
                    490: 
                    491:        enumerator = chain->create_enumerator(chain);
                    492:        while (len-- > 0 && enumerator->enumerate(enumerator, &x509))
                    493:        {
                    494:                mappings = x509->create_policy_mapping_enumerator(x509);
                    495:                valid = !mappings->enumerate(mappings, &mapping);
                    496:                mappings->destroy(mappings);
                    497:                if (!valid)
                    498:                {
                    499:                        cert = (certificate_t*)x509;
                    500:                        DBG1(DBG_CFG, "found policyMapping in certificate '%Y', but "
                    501:                                 "inhibitPolicyMapping in effect", cert->get_subject(cert));
                    502:                        break;
                    503:                }
                    504:        }
                    505:        enumerator->destroy(enumerator);
                    506:        return valid;
                    507: }
                    508: 
                    509: /**
                    510:  * Check len certificates in trustchain to have no anyPolicies
                    511:  */
                    512: static bool has_no_any_policy(linked_list_t *chain, int len)
                    513: {
                    514:        enumerator_t *enumerator, *policies;
                    515:        x509_cert_policy_t *policy;
                    516:        certificate_t *cert;
                    517:        x509_t *x509;
                    518:        bool valid = TRUE;
                    519: 
                    520:        enumerator = chain->create_enumerator(chain);
                    521:        while (len-- > 0 && enumerator->enumerate(enumerator, &x509))
                    522:        {
                    523:                policies = x509->create_cert_policy_enumerator(x509);
                    524:                while (policies->enumerate(policies, &policy))
                    525:                {
                    526:                        if (chunk_equals(policy->oid, any_policy))
                    527:                        {
                    528:                                cert = (certificate_t*)x509;
                    529:                                DBG1(DBG_CFG, "found anyPolicy in certificate '%Y', but "
                    530:                                         "inhibitAnyPolicy in effect", cert->get_subject(cert));
                    531:                                valid = FALSE;
                    532:                                break;
                    533:                        }
                    534:                }
                    535:                policies->destroy(policies);
                    536:        }
                    537:        enumerator->destroy(enumerator);
                    538:        return valid;
                    539: }
                    540: 
                    541: /**
                    542:  * Check requireExplicitPolicy and inhibitPolicyMapping constraints
                    543:  */
                    544: static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
                    545:                                                                         auth_cfg_t *auth)
                    546: {
                    547:        certificate_t *subject;
                    548:        bool valid = TRUE;
                    549: 
                    550:        subject = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
                    551:        if (subject)
                    552:        {
                    553:                if (subject->get_type(subject) == CERT_X509)
                    554:                {
                    555:                        x509_cert_policy_t *policy;
                    556:                        enumerator_t *enumerator;
                    557:                        linked_list_t *chain;
                    558:                        certificate_t *cert;
                    559:                        auth_rule_t rule;
                    560:                        x509_t *x509;
                    561:                        int len = 0;
                    562:                        u_int expl, inh;
                    563:                        char *oid;
                    564: 
                    565:                        /* prepare trustchain to validate */
                    566:                        chain = linked_list_create();
                    567:                        enumerator = auth->create_enumerator(auth);
                    568:                        while (enumerator->enumerate(enumerator, &rule, &cert))
                    569:                        {
                    570:                                if (rule == AUTH_RULE_IM_CERT &&
                    571:                                        cert->get_type(cert) == CERT_X509)
                    572:                                {
                    573:                                        chain->insert_last(chain, cert);
                    574:                                }
                    575:                        }
                    576:                        enumerator->destroy(enumerator);
                    577:                        chain->insert_last(chain, issuer);
                    578: 
                    579:                        /* search for requireExplicitPolicy constraints */
                    580:                        enumerator = chain->create_enumerator(chain);
                    581:                        while (enumerator->enumerate(enumerator, &x509))
                    582:                        {
                    583:                                expl = x509->get_constraint(x509, X509_REQUIRE_EXPLICIT_POLICY);
                    584:                                if (expl != X509_NO_CONSTRAINT)
                    585:                                {
                    586:                                        if (!has_policy_chain(chain, (x509_t*)subject, len - expl))
                    587:                                        {
                    588:                                                valid = FALSE;
                    589:                                                break;
                    590:                                        }
                    591:                                }
                    592:                                len++;
                    593:                        }
                    594:                        enumerator->destroy(enumerator);
                    595: 
                    596:                        /* search for inhibitPolicyMapping/inhibitAnyPolicy constraints */
                    597:                        len = 0;
                    598:                        chain->insert_first(chain, subject);
                    599:                        enumerator = chain->create_enumerator(chain);
                    600:                        while (enumerator->enumerate(enumerator, &x509))
                    601:                        {
                    602:                                inh = x509->get_constraint(x509, X509_INHIBIT_POLICY_MAPPING);
                    603:                                if (inh != X509_NO_CONSTRAINT)
                    604:                                {
                    605:                                        if (!has_no_policy_mapping(chain, len - inh))
                    606:                                        {
                    607:                                                valid = FALSE;
                    608:                                                break;
                    609:                                        }
                    610:                                }
                    611:                                inh = x509->get_constraint(x509, X509_INHIBIT_ANY_POLICY);
                    612:                                if (inh != X509_NO_CONSTRAINT)
                    613:                                {
                    614:                                        if (!has_no_any_policy(chain, len - inh))
                    615:                                        {
                    616:                                                valid = FALSE;
                    617:                                                break;
                    618:                                        }
                    619:                                }
                    620:                                len++;
                    621:                        }
                    622:                        enumerator->destroy(enumerator);
                    623: 
                    624:                        if (valid)
                    625:                        {
                    626:                                x509 = (x509_t*)subject;
                    627: 
                    628:                                enumerator = x509->create_cert_policy_enumerator(x509);
                    629:                                while (enumerator->enumerate(enumerator, &policy))
                    630:                                {
                    631:                                        oid = asn1_oid_to_string(policy->oid);
                    632:                                        if (oid)
                    633:                                        {
                    634:                                                if (is_policy_valid(chain, policy->oid))
                    635:                                                {
                    636:                                                        auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
                    637:                                                }
                    638:                                                else
                    639:                                                {
                    640:                                                        DBG1(DBG_CFG, "certificate policy %s for '%Y' "
                    641:                                                                 "not allowed by trustchain, ignored",
                    642:                                                                 oid, subject->get_subject(subject));
                    643:                                                        free(oid);
                    644:                                                }
                    645:                                        }
                    646:                                }
                    647:                                enumerator->destroy(enumerator);
                    648:                        }
                    649:                        chain->destroy(chain);
                    650:                }
                    651:        }
                    652:        return valid;
                    653: }
                    654: 
                    655: METHOD(cert_validator_t, validate, bool,
                    656:        private_constraints_validator_t *this, certificate_t *subject,
                    657:        certificate_t *issuer, bool online, u_int pathlen, bool anchor,
                    658:        auth_cfg_t *auth)
                    659: {
                    660:        if (issuer->get_type(issuer) == CERT_X509 &&
                    661:                subject->get_type(subject) == CERT_X509)
                    662:        {
                    663:                if (!check_pathlen((x509_t*)issuer, pathlen))
                    664:                {
                    665:                        lib->credmgr->call_hook(lib->credmgr, CRED_HOOK_EXCEEDED_PATH_LEN,
                    666:                                                                        subject);
                    667:                        return FALSE;
                    668:                }
                    669:                if (!check_name_constraints(subject, (x509_t*)issuer))
                    670:                {
                    671:                        lib->credmgr->call_hook(lib->credmgr, CRED_HOOK_POLICY_VIOLATION,
                    672:                                                                        subject);
                    673:                        return FALSE;
                    674:                }
                    675:                if (anchor)
                    676:                {
                    677:                        if (!check_policy_constraints((x509_t*)issuer, pathlen, auth))
                    678:                        {
                    679:                                lib->credmgr->call_hook(lib->credmgr,
                    680:                                                                                CRED_HOOK_POLICY_VIOLATION, issuer);
                    681:                                return FALSE;
                    682:                        }
                    683:                }
                    684:        }
                    685:        return TRUE;
                    686: }
                    687: 
                    688: METHOD(constraints_validator_t, destroy, void,
                    689:        private_constraints_validator_t *this)
                    690: {
                    691:        free(this);
                    692: }
                    693: 
                    694: /**
                    695:  * See header
                    696:  */
                    697: constraints_validator_t *constraints_validator_create()
                    698: {
                    699:        private_constraints_validator_t *this;
                    700: 
                    701:        INIT(this,
                    702:                .public = {
                    703:                        .validator.validate = _validate,
                    704:                        .destroy = _destroy,
                    705:                },
                    706:        );
                    707: 
                    708:        return &this->public;
                    709: }

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