Annotation of embedaddon/strongswan/src/pki/commands/issue.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2009 Martin Willi
                      3:  * Copyright (C) 2015-2019 Andreas Steffen
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include <time.h>
                     18: #include <errno.h>
                     19: 
                     20: #include "pki.h"
                     21: 
                     22: #include <utils/debug.h>
                     23: #include <asn1/asn1.h>
                     24: #include <collections/linked_list.h>
                     25: #include <credentials/certificates/certificate.h>
                     26: #include <credentials/certificates/x509.h>
                     27: #include <credentials/certificates/pkcs10.h>
                     28: 
                     29: /**
                     30:  * Free cert policy with OID
                     31:  */
                     32: static void destroy_cert_policy(x509_cert_policy_t *policy)
                     33: {
                     34:        free(policy->oid.ptr);
                     35:        free(policy);
                     36: }
                     37: 
                     38: /**
                     39:  * Free policy mapping
                     40:  */
                     41: static void destroy_policy_mapping(x509_policy_mapping_t *mapping)
                     42: {
                     43:        free(mapping->issuer.ptr);
                     44:        free(mapping->subject.ptr);
                     45:        free(mapping);
                     46: }
                     47: 
                     48: /**
                     49:  * Free a CRL DistributionPoint
                     50:  */
                     51: static void destroy_cdp(x509_cdp_t *this)
                     52: {
                     53:        DESTROY_IF(this->issuer);
                     54:        free(this);
                     55: }
                     56: 
                     57: /**
                     58:  * Issue a certificate using a CA certificate and key
                     59:  */
                     60: static int issue()
                     61: {
                     62:        cred_encoding_type_t form = CERT_ASN1_DER;
                     63:        hash_algorithm_t digest = HASH_UNKNOWN;
                     64:        signature_params_t *scheme = NULL;
                     65:        certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL;
                     66:        private_key_t *private = NULL;
                     67:        public_key_t *public = NULL;
                     68:        credential_type_t type = CRED_PUBLIC_KEY;
                     69:        key_type_t subtype = KEY_ANY;
                     70:        bool pkcs10 = FALSE;
                     71:        char *file = NULL, *dn = NULL, *hex = NULL, *cacert = NULL, *cakey = NULL;
                     72:        char *error = NULL, *keyid = NULL;
                     73:        identification_t *id = NULL;
                     74:        linked_list_t *san, *cdps, *ocsp, *permitted, *excluded, *policies, *mappings;
                     75:        linked_list_t *addrblocks;
                     76:        int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
                     77:        int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
                     78:        chunk_t serial = chunk_empty;
                     79:        chunk_t encoding = chunk_empty;
                     80:        chunk_t critical_extension_oid = chunk_empty;
                     81:        time_t not_before, not_after, lifetime = 1095 * 24 * 60 * 60;
                     82:        char *datenb = NULL, *datena = NULL, *dateform = NULL;
                     83:        x509_flag_t flags = 0;
                     84:        x509_t *x509;
                     85:        x509_cdp_t *cdp = NULL;
                     86:        x509_cert_policy_t *policy = NULL;
                     87:        traffic_selector_t *ts;
                     88:        char *arg;
                     89:        bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
                     90:                                                                           lib->ns);
                     91: 
                     92:        san = linked_list_create();
                     93:        cdps = linked_list_create();
                     94:        ocsp = linked_list_create();
                     95:        permitted = linked_list_create();
                     96:        excluded = linked_list_create();
                     97:        policies = linked_list_create();
                     98:        mappings = linked_list_create();
                     99:        addrblocks = linked_list_create();
                    100: 
                    101:        while (TRUE)
                    102:        {
                    103:                switch (command_getopt(&arg))
                    104:                {
                    105:                        case 'h':
                    106:                                goto usage;
                    107:                        case 't':
                    108:                                if (streq(arg, "pkcs10"))
                    109:                                {
                    110:                                        pkcs10 = TRUE;
                    111:                                }
                    112:                                else if (streq(arg, "rsa"))
                    113:                                {
                    114:                                        type = CRED_PRIVATE_KEY;
                    115:                                        subtype = KEY_RSA;
                    116:                                }
                    117:                                else if (streq(arg, "ecdsa"))
                    118:                                {
                    119:                                        type = CRED_PRIVATE_KEY;
                    120:                                        subtype = KEY_ECDSA;
                    121:                                }
                    122:                                else if (streq(arg, "ed25519"))
                    123:                                {
                    124:                                        type = CRED_PRIVATE_KEY;
                    125:                                        subtype = KEY_ED25519;
                    126:                                }
                    127:                                else if (streq(arg, "ed448"))
                    128:                                {
                    129:                                        type = CRED_PRIVATE_KEY;
                    130:                                        subtype = KEY_ED448;
                    131:                                }
                    132:                                else if (streq(arg, "bliss"))
                    133:                                {
                    134:                                        type = CRED_PRIVATE_KEY;
                    135:                                        subtype = KEY_BLISS;
                    136:                                }
                    137:                                else if (streq(arg, "priv"))
                    138:                                {
                    139:                                        type = CRED_PRIVATE_KEY;
                    140:                                        subtype = KEY_ANY;
                    141:                                }
                    142:                                else if (!streq(arg, "pub"))
                    143:                                {
                    144:                                        error = "invalid input type";
                    145:                                        goto usage;
                    146:                                }
                    147:                                continue;
                    148:                        case 'g':
                    149:                                if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
                    150:                                {
                    151:                                        error = "invalid --digest type";
                    152:                                        goto usage;
                    153:                                }
                    154:                                continue;
                    155:                        case 'R':
                    156:                                if (streq(arg, "pss"))
                    157:                                {
                    158:                                        pss = TRUE;
                    159:                                }
                    160:                                else if (!streq(arg, "pkcs1"))
                    161:                                {
                    162:                                        error = "invalid RSA padding";
                    163:                                        goto usage;
                    164:                                }
                    165:                                continue;
                    166:                        case 'i':
                    167:                                file = arg;
                    168:                                continue;
                    169:                        case 'c':
                    170:                                cacert = arg;
                    171:                                continue;
                    172:                        case 'k':
                    173:                                cakey = arg;
                    174:                                continue;
                    175:                        case 'x':
                    176:                                keyid = arg;
                    177:                                continue;
                    178:                        case 'd':
                    179:                                dn = arg;
                    180:                                continue;
                    181:                        case 'a':
                    182:                                san->insert_last(san, identification_create_from_string(arg));
                    183:                                continue;
                    184:                        case 'l':
                    185:                                lifetime = atoi(arg) * 24 * 60 * 60;
                    186:                                if (!lifetime)
                    187:                                {
                    188:                                        error = "invalid --lifetime value";
                    189:                                        goto usage;
                    190:                                }
                    191:                                continue;
                    192:                        case 'D':
                    193:                                dateform = arg;
                    194:                                continue;
                    195:                        case 'F':
                    196:                                datenb = arg;
                    197:                                continue;
                    198:                        case 'T':
                    199:                                datena = arg;
                    200:                                continue;
                    201:                        case 's':
                    202:                                hex = arg;
                    203:                                continue;
                    204:                        case 'b':
                    205:                                flags |= X509_CA;
                    206:                                continue;
                    207:                        case 'p':
                    208:                                pathlen = atoi(arg);
                    209:                                continue;
                    210:                        case 'B':
                    211:                                ts = parse_ts(arg);
                    212:                                if (!ts)
                    213:                                {
                    214:                                        error = "invalid addressBlock";
                    215:                                        goto usage;
                    216:                                }
                    217:                                addrblocks->insert_last(addrblocks, ts);
                    218:                                continue;
                    219:                        case 'n':
                    220:                                permitted->insert_last(permitted,
                    221:                                                                           identification_create_from_string(arg));
                    222:                                continue;
                    223:                        case 'N':
                    224:                                excluded->insert_last(excluded,
                    225:                                                                          identification_create_from_string(arg));
                    226:                                continue;
                    227:                        case 'P':
                    228:                        {
                    229:                                chunk_t oid;
                    230: 
                    231:                                oid = asn1_oid_from_string(arg);
                    232:                                if (!oid.len)
                    233:                                {
                    234:                                        error = "--cert-policy OID invalid";
                    235:                                        goto usage;
                    236:                                }
                    237:                                INIT(policy,
                    238:                                        .oid = oid,
                    239:                                );
                    240:                                policies->insert_last(policies, policy);
                    241:                                continue;
                    242:                        }
                    243:                        case 'C':
                    244:                                if (!policy)
                    245:                                {
                    246:                                        error = "--cps-uri must follow a --cert-policy";
                    247:                                        goto usage;
                    248:                                }
                    249:                                policy->cps_uri = arg;
                    250:                                continue;
                    251:                        case 'U':
                    252:                                if (!policy)
                    253:                                {
                    254:                                        error = "--user-notice must follow a --cert-policy";
                    255:                                        goto usage;
                    256:                                }
                    257:                                policy->unotice_text = arg;
                    258:                                continue;
                    259:                        case 'M':
                    260:                        {
                    261:                                char *pos = strchr(arg, ':');
                    262:                                x509_policy_mapping_t *mapping;
                    263:                                chunk_t subject_oid, issuer_oid;
                    264: 
                    265:                                if (pos)
                    266:                                {
                    267:                                        *pos++ = '\0';
                    268:                                        issuer_oid = asn1_oid_from_string(arg);
                    269:                                        subject_oid = asn1_oid_from_string(pos);
                    270:                                }
                    271:                                if (!pos || !issuer_oid.len || !subject_oid.len)
                    272:                                {
                    273:                                        error = "--policy-map OIDs invalid";
                    274:                                        goto usage;
                    275:                                }
                    276:                                INIT(mapping,
                    277:                                        .issuer = issuer_oid,
                    278:                                        .subject = subject_oid,
                    279:                                );
                    280:                                mappings->insert_last(mappings, mapping);
                    281:                                continue;
                    282:                        }
                    283:                        case 'E':
                    284:                                require_explicit = atoi(arg);
                    285:                                continue;
                    286:                        case 'H':
                    287:                                inhibit_mapping = atoi(arg);
                    288:                                continue;
                    289:                        case 'A':
                    290:                                inhibit_any = atoi(arg);
                    291:                                continue;
                    292:                        case 'e':
                    293:                                if (streq(arg, "serverAuth"))
                    294:                                {
                    295:                                        flags |= X509_SERVER_AUTH;
                    296:                                }
                    297:                                else if (streq(arg, "clientAuth"))
                    298:                                {
                    299:                                        flags |= X509_CLIENT_AUTH;
                    300:                                }
                    301:                                else if (streq(arg, "ikeIntermediate"))
                    302:                                {
                    303:                                        flags |= X509_IKE_INTERMEDIATE;
                    304:                                }
                    305:                                else if (streq(arg, "crlSign"))
                    306:                                {
                    307:                                        flags |= X509_CRL_SIGN;
                    308:                                }
                    309:                                else if (streq(arg, "ocspSigning"))
                    310:                                {
                    311:                                        flags |= X509_OCSP_SIGNER;
                    312:                                }
                    313:                                else if (streq(arg, "msSmartcardLogon"))
                    314:                                {
                    315:                                        flags |= X509_MS_SMARTCARD_LOGON;
                    316:                                }
                    317:                                continue;
                    318:                        case 'f':
                    319:                                if (!get_form(arg, &form, CRED_CERTIFICATE))
                    320:                                {
                    321:                                        error = "invalid output format";
                    322:                                        goto usage;
                    323:                                }
                    324:                                continue;
                    325:                        case 'u':
                    326:                                INIT(cdp,
                    327:                                        .uri = arg,
                    328:                                );
                    329:                                cdps->insert_last(cdps, cdp);
                    330:                                continue;
                    331:                        case 'I':
                    332:                                if (!cdp || cdp->issuer)
                    333:                                {
                    334:                                        error = "--crlissuer must follow a --crl";
                    335:                                        goto usage;
                    336:                                }
                    337:                                cdp->issuer = identification_create_from_string(arg);
                    338:                                continue;
                    339:                        case 'o':
                    340:                                ocsp->insert_last(ocsp, arg);
                    341:                                continue;
                    342:                        case 'X':
                    343:                                chunk_free(&critical_extension_oid);
                    344:                                critical_extension_oid = asn1_oid_from_string(arg);
                    345:                                continue;
                    346:                        case EOF:
                    347:                                break;
                    348:                        default:
                    349:                                error = "invalid --issue option";
                    350:                                goto usage;
                    351:                }
                    352:                break;
                    353:        }
                    354: 
                    355:        if (!cacert)
                    356:        {
                    357:                error = "--cacert is required";
                    358:                goto usage;
                    359:        }
                    360:        if (!cakey && !keyid)
                    361:        {
                    362:                error = "--cakey or --keyid is required";
                    363:                goto usage;
                    364:        }
                    365:        if (!calculate_lifetime(dateform, datenb, datena, lifetime,
                    366:                                                        &not_before, &not_after))
                    367:        {
                    368:                error = "invalid --not-before/after datetime";
                    369:                goto usage;
                    370:        }
                    371:        if (dn && *dn)
                    372:        {
                    373:                id = identification_create_from_string(dn);
                    374:                if (id->get_type(id) != ID_DER_ASN1_DN)
                    375:                {
                    376:                        error = "supplied --dn is not a distinguished name";
                    377:                        goto end;
                    378:                }
                    379:        }
                    380: 
                    381:        DBG2(DBG_LIB, "Reading ca certificate:");
                    382:        ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                    383:                                                        BUILD_FROM_FILE, cacert, BUILD_END);
                    384:        if (!ca)
                    385:        {
                    386:                error = "parsing CA certificate failed";
                    387:                goto end;
                    388:        }
                    389:        x509 = (x509_t*)ca;
                    390:        if (!(x509->get_flags(x509) & X509_CA))
                    391:        {
                    392:                error = "CA certificate misses CA basicConstraint";
                    393:                goto end;
                    394:        }
                    395:        public = ca->get_public_key(ca);
                    396:        if (!public)
                    397:        {
                    398:                error = "extracting CA certificate public key failed";
                    399:                goto end;
                    400:        }
                    401: 
                    402:        DBG2(DBG_LIB, "Reading ca private key:");
                    403:        if (cakey)
                    404:        {
                    405:                private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
                    406:                                                                         public->get_type(public),
                    407:                                                                         BUILD_FROM_FILE, cakey, BUILD_END);
                    408:        }
                    409:        else
                    410:        {
                    411:                chunk_t chunk;
                    412: 
                    413:                chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
                    414:                private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
                    415:                                                                         BUILD_PKCS11_KEYID, chunk, BUILD_END);
                    416:                free(chunk.ptr);
                    417:        }
                    418:        if (!private)
                    419:        {
                    420:                error = "loading CA private key failed";
                    421:                goto end;
                    422:        }
                    423:        if (!private->belongs_to(private, public))
                    424:        {
                    425:                error = "CA private key does not match CA certificate";
                    426:                goto end;
                    427:        }
                    428:        public->destroy(public);
                    429:        public = NULL;
                    430: 
                    431:        if (hex)
                    432:        {
                    433:                serial = chunk_from_hex(chunk_create(hex, strlen(hex)), NULL);
                    434:        }
                    435:        else
                    436:        {
                    437:                rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
                    438: 
                    439:                if (!rng)
                    440:                {
                    441:                        error = "no random number generator found";
                    442:                        goto end;
                    443:                }
                    444:                if (!rng_allocate_bytes_not_zero(rng, 8, &serial, FALSE))
                    445:                {
                    446:                        error = "failed to generate serial number";
                    447:                        rng->destroy(rng);
                    448:                        goto end;
                    449:                }
                    450:                serial.ptr[0] &= 0x7F;
                    451:                rng->destroy(rng);
                    452:        }
                    453: 
                    454:        if (pkcs10)
                    455:        {
                    456:                enumerator_t *enumerator;
                    457:                identification_t *subjectAltName;
                    458:                pkcs10_t *req;
                    459: 
                    460:                DBG2(DBG_LIB, "Reading certificate request");
                    461:                if (file)
                    462:                {
                    463:                        cert_req = lib->creds->create(lib->creds, CRED_CERTIFICATE,
                    464:                                                                                  CERT_PKCS10_REQUEST,
                    465:                                                                                  BUILD_FROM_FILE, file, BUILD_END);
                    466:                }
                    467:                else
                    468:                {
                    469:                        chunk_t chunk;
                    470: 
                    471:                        set_file_mode(stdin, CERT_ASN1_DER);
                    472:                        if (!chunk_from_fd(0, &chunk))
                    473:                        {
                    474:                                fprintf(stderr, "%s: ", strerror(errno));
                    475:                                error = "reading certificate request failed";
                    476:                                goto end;
                    477:                        }
                    478:                        cert_req = lib->creds->create(lib->creds, CRED_CERTIFICATE,
                    479:                                                                                  CERT_PKCS10_REQUEST,
                    480:                                                                                  BUILD_BLOB, chunk, BUILD_END);
                    481:                        free(chunk.ptr);
                    482:                }
                    483:                if (!cert_req)
                    484:                {
                    485:                        error = "parsing certificate request failed";
                    486:                        goto end;
                    487:                }
                    488: 
                    489:                /* If not set yet use subject from PKCS#10 certificate request as DN */
                    490:                if (!id)
                    491:                {
                    492:                        id = cert_req->get_subject(cert_req);
                    493:                        id = id->clone(id);
                    494:                }
                    495: 
                    496:                /* Add subjectAltNames from PKCS#10 certificate request */
                    497:                req = (pkcs10_t*)cert_req;
                    498:                enumerator = req->create_subjectAltName_enumerator(req);
                    499:                while (enumerator->enumerate(enumerator, &subjectAltName))
                    500:                {
                    501:                        san->insert_last(san, subjectAltName->clone(subjectAltName));
                    502:                }
                    503:                enumerator->destroy(enumerator);
                    504: 
                    505:                /* Use public key from PKCS#10 certificate request */
                    506:                public = cert_req->get_public_key(cert_req);
                    507:        }
                    508:        else
                    509:        {
                    510:                DBG2(DBG_LIB, "Reading key:");
                    511:                if (file)
                    512:                {
                    513:                        public = lib->creds->create(lib->creds, type, subtype,
                    514:                                                                                BUILD_FROM_FILE, file, BUILD_END);
                    515:                }
                    516:                else
                    517:                {
                    518:                        chunk_t chunk;
                    519: 
                    520:                        if (!chunk_from_fd(0, &chunk))
                    521:                        {
                    522:                                fprintf(stderr, "%s: ", strerror(errno));
                    523:                                error = "reading key failed";
                    524:                                goto end;
                    525:                        }
                    526:                        public = lib->creds->create(lib->creds, type, subtype,
                    527:                                                                                 BUILD_BLOB, chunk, BUILD_END);
                    528:                        free(chunk.ptr);
                    529:                }
                    530:                if (public && type == CRED_PRIVATE_KEY)
                    531:                {
                    532:                        private_key_t *priv = (private_key_t*)public;
                    533:                        public = priv->get_public_key(priv);
                    534:                        priv->destroy(priv);
                    535:                }
                    536:        }
                    537:        if (!public)
                    538:        {
                    539:                error = "parsing public key failed";
                    540:                goto end;
                    541:        }
                    542: 
                    543:        if (!id)
                    544:        {
                    545:                id = identification_create_from_encoding(ID_DER_ASN1_DN,
                    546:                                                                                chunk_from_chars(ASN1_SEQUENCE, 0));
                    547:        }
                    548:        scheme = get_signature_scheme(private, digest, pss);
                    549:        if (!scheme)
                    550:        {
                    551:                error = "no signature scheme found";
                    552:                goto end;
                    553:        }
                    554: 
                    555:        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                    556:                                        BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca,
                    557:                                        BUILD_PUBLIC_KEY, public, BUILD_SUBJECT, id,
                    558:                                        BUILD_NOT_BEFORE_TIME, not_before,
                    559:                                        BUILD_NOT_AFTER_TIME, not_after, BUILD_SERIAL, serial,
                    560:                                        BUILD_SUBJECT_ALTNAMES, san, BUILD_X509_FLAG, flags,
                    561:                                        BUILD_PATHLEN, pathlen, BUILD_ADDRBLOCKS, addrblocks,
                    562:                                        BUILD_CRL_DISTRIBUTION_POINTS, cdps,
                    563:                                        BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
                    564:                                        BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
                    565:                                        BUILD_EXCLUDED_NAME_CONSTRAINTS, excluded,
                    566:                                        BUILD_CERTIFICATE_POLICIES, policies,
                    567:                                        BUILD_POLICY_MAPPINGS, mappings,
                    568:                                        BUILD_POLICY_REQUIRE_EXPLICIT, require_explicit,
                    569:                                        BUILD_POLICY_INHIBIT_MAPPING, inhibit_mapping,
                    570:                                        BUILD_POLICY_INHIBIT_ANY, inhibit_any,
                    571:                                        BUILD_CRITICAL_EXTENSION, critical_extension_oid,
                    572:                                        BUILD_SIGNATURE_SCHEME, scheme,
                    573:                                        BUILD_END);
                    574:        if (!cert)
                    575:        {
                    576:                error = "generating certificate failed";
                    577:                goto end;
                    578:        }
                    579:        if (!cert->get_encoding(cert, form, &encoding))
                    580:        {
                    581:                error = "encoding certificate failed";
                    582:                goto end;
                    583:        }
                    584:        set_file_mode(stdout, form);
                    585:        if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
                    586:        {
                    587:                error = "writing certificate key failed";
                    588:                goto end;
                    589:        }
                    590: 
                    591: end:
                    592:        DESTROY_IF(id);
                    593:        DESTROY_IF(cert_req);
                    594:        DESTROY_IF(cert);
                    595:        DESTROY_IF(ca);
                    596:        DESTROY_IF(public);
                    597:        DESTROY_IF(private);
                    598:        san->destroy_offset(san, offsetof(identification_t, destroy));
                    599:        permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
                    600:        excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
                    601:        addrblocks->destroy_offset(addrblocks, offsetof(traffic_selector_t, destroy));
                    602:        policies->destroy_function(policies, (void*)destroy_cert_policy);
                    603:        mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
                    604:        cdps->destroy_function(cdps, (void*)destroy_cdp);
                    605:        ocsp->destroy(ocsp);
                    606:        signature_params_destroy(scheme);
                    607:        free(critical_extension_oid.ptr);
                    608:        free(encoding.ptr);
                    609:        free(serial.ptr);
                    610: 
                    611:        if (error)
                    612:        {
                    613:                fprintf(stderr, "%s\n", error);
                    614:                return 1;
                    615:        }
                    616:        return 0;
                    617: 
                    618: usage:
                    619:        san->destroy_offset(san, offsetof(identification_t, destroy));
                    620:        permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
                    621:        excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
                    622:        addrblocks->destroy_offset(addrblocks, offsetof(traffic_selector_t, destroy));
                    623:        policies->destroy_function(policies, (void*)destroy_cert_policy);
                    624:        mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
                    625:        cdps->destroy_function(cdps, (void*)destroy_cdp);
                    626:        ocsp->destroy(ocsp);
                    627:        free(critical_extension_oid.ptr);
                    628:        return command_usage(error);
                    629: }
                    630: 
                    631: /**
                    632:  * Register the command.
                    633:  */
                    634: static void __attribute__ ((constructor))reg()
                    635: {
                    636:        command_register((command_t) {
                    637:                issue, 'i', "issue",
                    638:                "issue a certificate using a CA certificate and key",
                    639:                {"[--in file] [--type pub|pkcs10|priv|rsa|ecdsa|ed25519|ed448|bliss]",
                    640:                 "--cakey file|--cakeyid hex --cacert file [--dn subject-dn]",
                    641:                 "[--san subjectAltName]+ [--lifetime days] [--serial hex]",
                    642:                 "[--ca] [--pathlen len]",
                    643:                 "[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
                    644:                 "[--crl uri [--crlissuer i]]+ [--ocsp uri]+ [--nc-permitted name]",
                    645:                 "[--nc-excluded name] [--policy-mapping issuer-oid:subject-oid]",
                    646:                 "[--policy-explicit len] [--policy-inhibit len] [--policy-any len]",
                    647:                 "[--cert-policy oid [--cps-uri uri] [--user-notice text]]+",
                    648:                 "[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
                    649:                 "[--rsa-padding pkcs1|pss] [--critical oid]",
                    650:                 "[--outform der|pem]"},
                    651:                {
                    652:                        {"help",                        'h', 0, "show usage information"},
                    653:                        {"in",                          'i', 1, "key/request file to issue, default: stdin"},
                    654:                        {"type",                        't', 1, "type of input, default: pub"},
                    655:                        {"cacert",                      'c', 1, "CA certificate file"},
                    656:                        {"cakey",                       'k', 1, "CA private key file"},
                    657:                        {"cakeyid",                     'x', 1, "smartcard or TPM CA private key object handle"},
                    658:                        {"dn",                          'd', 1, "distinguished name to include as subject"},
                    659:                        {"san",                         'a', 1, "subjectAltName to include in certificate"},
                    660:                        {"lifetime",            'l', 1, "days the certificate is valid, default: 1095"},
                    661:                        {"not-before",          'F', 1, "date/time the validity of the cert starts"},
                    662:                        {"not-after",           'T', 1, "date/time the validity of the cert ends"},
                    663:                        {"dateform",            'D', 1, "strptime(3) input format, default: %d.%m.%y %T"},
                    664:                        {"serial",                      's', 1, "serial number in hex, default: random"},
                    665:                        {"ca",                          'b', 0, "include CA basicConstraint, default: no"},
                    666:                        {"pathlen",                     'p', 1, "set path length constraint"},
                    667:                        {"addrblock",           'B', 1, "RFC 3779 addrBlock to include"},
                    668:                        {"nc-permitted",        'n', 1, "add permitted NameConstraint"},
                    669:                        {"nc-excluded",         'N', 1, "add excluded NameConstraint"},
                    670:                        {"cert-policy",         'P', 1, "certificatePolicy OID to include"},
                    671:                        {"cps-uri",                     'C', 1, "Certification Practice statement URI for certificatePolicy"},
                    672:                        {"user-notice",         'U', 1, "user notice for certificatePolicy"},
                    673:                        {"policy-mapping",      'M', 1, "policyMapping from issuer to subject OID"},
                    674:                        {"policy-explicit",     'E', 1, "requireExplicitPolicy constraint"},
                    675:                        {"policy-inhibit",      'H', 1, "inhibitPolicyMapping constraint"},
                    676:                        {"policy-any",          'A', 1, "inhibitAnyPolicy constraint"},
                    677:                        {"flag",                        'e', 1, "include extendedKeyUsage flag"},
                    678:                        {"crl",                         'u', 1, "CRL distribution point URI to include"},
                    679:                        {"crlissuer",           'I', 1, "CRL Issuer for CRL at distribution point"},
                    680:                        {"ocsp",                        'o', 1, "OCSP AuthorityInfoAccess URI to include"},
                    681:                        {"digest",                      'g', 1, "digest for signature creation, default: key-specific"},
                    682:                        {"rsa-padding",         'R', 1, "padding for RSA signatures, default: pkcs1"},
                    683:                        {"critical",            'X', 1, "critical extension OID to include"},
                    684:                        {"outform",                     'f', 1, "encoding of generated cert, default: der"},
                    685:                }
                    686:        });
                    687: }

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