Annotation of embedaddon/strongswan/src/pki/commands/req.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2009 Martin Willi
        !             3:  * Copyright (C) 2009-2017 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 <collections/linked_list.h>
        !            23: #include <credentials/certificates/certificate.h>
        !            24: 
        !            25: /**
        !            26:  * Create a self-signed PKCS#10 certificate request.
        !            27:  */
        !            28: static int req()
        !            29: {
        !            30:        cred_encoding_type_t form = CERT_ASN1_DER;
        !            31:        key_type_t type = KEY_ANY;
        !            32:        hash_algorithm_t digest = HASH_UNKNOWN;
        !            33:        signature_params_t *scheme = NULL;
        !            34:        certificate_t *cert = NULL;
        !            35:        private_key_t *private = NULL;
        !            36:        char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
        !            37:        identification_t *id = NULL;
        !            38:        linked_list_t *san;
        !            39:        chunk_t encoding = chunk_empty;
        !            40:        chunk_t challenge_password = chunk_empty;
        !            41:        char *arg;
        !            42:        bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
        !            43:                                                                           lib->ns);
        !            44: 
        !            45:        san = linked_list_create();
        !            46: 
        !            47:        while (TRUE)
        !            48:        {
        !            49:                switch (command_getopt(&arg))
        !            50:                {
        !            51:                        case 'h':
        !            52:                                goto usage;
        !            53:                        case 't':
        !            54:                                if (streq(arg, "rsa"))
        !            55:                                {
        !            56:                                        type = KEY_RSA;
        !            57:                                }
        !            58:                                else if (streq(arg, "ecdsa"))
        !            59:                                {
        !            60:                                        type = KEY_ECDSA;
        !            61:                                }
        !            62:                                else if (streq(arg, "bliss"))
        !            63:                                {
        !            64:                                        type = KEY_BLISS;
        !            65:                                }
        !            66:                                else if (streq(arg, "priv"))
        !            67:                                {
        !            68:                                        type = KEY_ANY;
        !            69:                                }
        !            70:                                else
        !            71:                                {
        !            72:                                        error = "invalid input type";
        !            73:                                        goto usage;
        !            74:                                }
        !            75:                                continue;
        !            76:                        case 'g':
        !            77:                                if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
        !            78:                                {
        !            79:                                        error = "invalid --digest type";
        !            80:                                        goto usage;
        !            81:                                }
        !            82:                                continue;
        !            83:                        case 'R':
        !            84:                                if (streq(arg, "pss"))
        !            85:                                {
        !            86:                                        pss = TRUE;
        !            87:                                }
        !            88:                                else if (!streq(arg, "pkcs1"))
        !            89:                                {
        !            90:                                        error = "invalid RSA padding";
        !            91:                                        goto usage;
        !            92:                                }
        !            93:                                continue;
        !            94:                        case 'i':
        !            95:                                file = arg;
        !            96:                                continue;
        !            97:                        case 'd':
        !            98:                                dn = arg;
        !            99:                                continue;
        !           100:                        case 'a':
        !           101:                                san->insert_last(san, identification_create_from_string(arg));
        !           102:                                continue;
        !           103:                        case 'p':
        !           104:                                challenge_password = chunk_create(arg, strlen(arg));
        !           105:                                continue;
        !           106:                        case 'f':
        !           107:                                if (!get_form(arg, &form, CRED_CERTIFICATE))
        !           108:                                {
        !           109:                                        error = "invalid output format";
        !           110:                                        goto usage;
        !           111:                                }
        !           112:                                continue;
        !           113:                        case 'x':
        !           114:                                keyid = arg;
        !           115:                                continue;
        !           116:                        case EOF:
        !           117:                                break;
        !           118:                        default:
        !           119:                                error = "invalid --req option";
        !           120:                                goto usage;
        !           121:                }
        !           122:                break;
        !           123:        }
        !           124: 
        !           125:        if (!dn)
        !           126:        {
        !           127:                error = "--dn is required";
        !           128:                goto usage;
        !           129:        }
        !           130:        id = identification_create_from_string(dn);
        !           131:        if (id->get_type(id) != ID_DER_ASN1_DN)
        !           132:        {
        !           133:                error = "supplied --dn is not a distinguished name";
        !           134:                goto end;
        !           135:        }
        !           136:        if (file)
        !           137:        {
        !           138:                private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
        !           139:                                                                         BUILD_FROM_FILE, file, BUILD_END);
        !           140:        }
        !           141:        else if (keyid)
        !           142:        {
        !           143:                chunk_t chunk;
        !           144: 
        !           145:                chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
        !           146:                private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
        !           147:                                                                          BUILD_PKCS11_KEYID, chunk, BUILD_END);
        !           148:                free(chunk.ptr);
        !           149:        }
        !           150:        else
        !           151:        {
        !           152:                chunk_t chunk;
        !           153: 
        !           154:                set_file_mode(stdin, CERT_ASN1_DER);
        !           155:                if (!chunk_from_fd(0, &chunk))
        !           156:                {
        !           157:                        fprintf(stderr, "reading private key failed: %s\n", strerror(errno));
        !           158:                        error = "";
        !           159:                        goto end;
        !           160:                }
        !           161:                private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
        !           162:                                                                         BUILD_BLOB, chunk, BUILD_END);
        !           163:                free(chunk.ptr);
        !           164:        }
        !           165:        if (!private)
        !           166:        {
        !           167:                error = "parsing private key failed";
        !           168:                goto end;
        !           169:        }
        !           170:        scheme = get_signature_scheme(private, digest, pss);
        !           171:        if (!scheme)
        !           172:        {
        !           173:                error = "no signature scheme found";
        !           174:                goto end;
        !           175:        }
        !           176: 
        !           177:        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
        !           178:                                                          BUILD_SIGNING_KEY, private,
        !           179:                                                          BUILD_SUBJECT, id,
        !           180:                                                          BUILD_SUBJECT_ALTNAMES, san,
        !           181:                                                          BUILD_CHALLENGE_PWD, challenge_password,
        !           182:                                                          BUILD_SIGNATURE_SCHEME, scheme,
        !           183:                                                          BUILD_END);
        !           184:        if (!cert)
        !           185:        {
        !           186:                error = "generating certificate request failed";
        !           187:                goto end;
        !           188:        }
        !           189:        if (!cert->get_encoding(cert, form, &encoding))
        !           190:        {
        !           191:                error = "encoding certificate request failed";
        !           192:                goto end;
        !           193:        }
        !           194:        set_file_mode(stdout, form);
        !           195:        if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
        !           196:        {
        !           197:                error = "writing certificate request failed";
        !           198:                goto end;
        !           199:        }
        !           200: 
        !           201: end:
        !           202:        DESTROY_IF(id);
        !           203:        DESTROY_IF(cert);
        !           204:        DESTROY_IF(private);
        !           205:        san->destroy_offset(san, offsetof(identification_t, destroy));
        !           206:        signature_params_destroy(scheme);
        !           207:        free(encoding.ptr);
        !           208: 
        !           209:        if (error)
        !           210:        {
        !           211:                fprintf(stderr, "%s\n", error);
        !           212:                return 1;
        !           213:        }
        !           214:        return 0;
        !           215: 
        !           216: usage:
        !           217:        san->destroy_offset(san, offsetof(identification_t, destroy));
        !           218:        return command_usage(error);
        !           219: }
        !           220: 
        !           221: /**
        !           222:  * Register the command.
        !           223:  */
        !           224: static void __attribute__ ((constructor))reg()
        !           225: {
        !           226:        command_register((command_t) {
        !           227:                req, 'r', "req",
        !           228:                "create a PKCS#10 certificate request",
        !           229:                {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv] --dn distinguished-name",
        !           230:                 "[--san subjectAltName]+ [--password challengePassword]",
        !           231:                 "[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
        !           232:                 "[--rsa-padding pkcs1|pss]",
        !           233:                 "[--outform der|pem]"},
        !           234:                {
        !           235:                        {"help",                'h', 0, "show usage information"},
        !           236:                        {"in",                  'i', 1, "private key input file, default: stdin"},
        !           237:                        {"keyid",               'x', 1, "smartcard or TPM private key object handle"},
        !           238:                        {"type",                't', 1, "type of input key, default: priv"},
        !           239:                        {"dn",                  'd', 1, "subject distinguished name"},
        !           240:                        {"san",                 'a', 1, "subjectAltName to include in cert request"},
        !           241:                        {"password",    'p', 1, "challengePassword to include in cert request"},
        !           242:                        {"digest",              'g', 1, "digest for signature creation, default: key-specific"},
        !           243:                        {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
        !           244:                        {"outform",             'f', 1, "encoding of generated request, default: der"},
        !           245:                }
        !           246:        });
        !           247: }

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