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

1.1       misho       1: /*
                      2:  * Copyright (C) 2009 Martin Willi
                      3:  * Copyright (C) 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 <errno.h>
                     18: 
                     19: #include "pki.h"
                     20: 
                     21: #include <credentials/certificates/certificate.h>
                     22: #include <credentials/certificates/x509.h>
                     23: 
                     24: typedef enum {
                     25:                FORMAT_PRETTY,
                     26:                FORMAT_HEX,
                     27:                FORMAT_BASE64,
                     28:                FORMAT_BINARY,
                     29: } format_t;
                     30: 
                     31: /**
                     32:  * Print a single keyid in the requested format
                     33:  */
                     34: static bool print_id(chunk_t id, format_t format, char *desc)
                     35: {
                     36:        chunk_t chunk;
                     37: 
                     38:        switch (format)
                     39:        {
                     40:                case FORMAT_PRETTY:
                     41:                        printf("%s:\n             %#B\n", desc, &id);
                     42:                        break;
                     43:                case FORMAT_HEX:
                     44:                        chunk = chunk_to_hex(id, NULL, FALSE);
                     45:                        printf("%.*s\n", (int)chunk.len, chunk.ptr);
                     46:                        chunk_free(&chunk);
                     47:                        break;
                     48:                case FORMAT_BASE64:
                     49:                        chunk = chunk_to_base64(id, NULL);
                     50:                        printf("%.*s\n", (int)chunk.len, chunk.ptr);
                     51:                        chunk_free(&chunk);
                     52:                        break;
                     53:                case FORMAT_BINARY:
                     54:                        if (fwrite(id.ptr, id.len, 1, stdout) != 1)
                     55:                        {
                     56:                                fprintf(stderr, "writing %s failed\n", desc);
                     57:                                return FALSE;
                     58:                        }
                     59:                        break;
                     60:        }
                     61:        return TRUE;
                     62: }
                     63: 
                     64: /**
                     65:  * Calculate the keyid of a key/certificate
                     66:  */
                     67: static int keyid()
                     68: {
                     69:        credential_type_t type = CRED_PRIVATE_KEY;
                     70:        int subtype = KEY_ANY;
                     71:        certificate_t *cert;
                     72:        private_key_t *private;
                     73:        public_key_t *public;
                     74:        format_t format = FORMAT_PRETTY;
                     75:        enum {
                     76:                ID_TYPE_ALL,
                     77:                ID_TYPE_SPK,
                     78:                ID_TYPE_SPKI,
                     79:        } id_type = FORMAT_PRETTY;
                     80:        char *file = NULL, *keyid = NULL;
                     81:        void *cred;
                     82:        chunk_t id, spk = chunk_empty, spki = chunk_empty;
                     83:        char *arg;
                     84: 
                     85:        while (TRUE)
                     86:        {
                     87:                switch (command_getopt(&arg))
                     88:                {
                     89:                        case 'h':
                     90:                                return command_usage(NULL);
                     91:                        case 't':
                     92:                                if (streq(arg, "rsa") ||
                     93:                                        streq(arg, "rsa-priv"))
                     94:                                {
                     95:                                        type = CRED_PRIVATE_KEY;
                     96:                                        subtype = KEY_RSA;
                     97:                                }
                     98:                                else if (streq(arg, "ecdsa") ||
                     99:                                                 streq(arg, "ecdsa-priv"))
                    100:                                {
                    101:                                        type = CRED_PRIVATE_KEY;
                    102:                                        subtype = KEY_ECDSA;
                    103:                                }
                    104:                                else if (streq(arg, "bliss") ||
                    105:                                                 streq(arg, "bliss-priv"))
                    106:                                {
                    107:                                        type = CRED_PRIVATE_KEY;
                    108:                                        subtype = KEY_BLISS;
                    109:                                }
                    110:                                else if (streq(arg, "priv"))
                    111:                                {
                    112:                                        type = CRED_PRIVATE_KEY;
                    113:                                        subtype = KEY_ANY;
                    114:                                }
                    115:                                else if (streq(arg, "pub"))
                    116:                                {
                    117:                                        type = CRED_PUBLIC_KEY;
                    118:                                        subtype = KEY_ANY;
                    119:                                }
                    120:                                else if (streq(arg, "pkcs10"))
                    121:                                {
                    122:                                        type = CRED_CERTIFICATE;
                    123:                                        subtype = CERT_PKCS10_REQUEST;
                    124:                                }
                    125:                                else if (streq(arg, "x509"))
                    126:                                {
                    127:                                        type = CRED_CERTIFICATE;
                    128:                                        subtype = CERT_X509;
                    129:                                }
                    130:                                else
                    131:                                {
                    132:                                        return command_usage( "invalid input type");
                    133:                                }
                    134:                                continue;
                    135:                        case 'I':
                    136:                                if (streq(arg, "spk"))
                    137:                                {
                    138:                                        id_type = ID_TYPE_SPK;
                    139:                                }
                    140:                                else if (streq(arg, "spki"))
                    141:                                {
                    142:                                        id_type = ID_TYPE_SPKI;
                    143:                                }
                    144:                                else if (!streq(arg, "all"))
                    145:                                {
                    146:                                        return command_usage( "invalid id type");
                    147:                                }
                    148:                                continue;
                    149:                        case 'f':
                    150:                                if (streq(arg, "hex"))
                    151:                                {
                    152:                                        format = FORMAT_HEX;
                    153:                                }
                    154:                                else if (streq(arg, "base64"))
                    155:                                {
                    156:                                        format = FORMAT_BASE64;
                    157:                                }
                    158:                                else if (streq(arg, "bin"))
                    159:                                {
                    160:                                        format = FORMAT_BINARY;
                    161:                                }
                    162:                                else if (!streq(arg, "pretty"))
                    163:                                {
                    164:                                        return command_usage( "invalid output format");
                    165:                                }
                    166:                                continue;
                    167:                        case 'i':
                    168:                                file = arg;
                    169:                                continue;
                    170:                        case 'x':
                    171:                                keyid = arg;
                    172:                                continue;
                    173:                        case EOF:
                    174:                                break;
                    175:                        default:
                    176:                                return command_usage("invalid --keyid option");
                    177:                }
                    178:                break;
                    179:        }
                    180:        if (file)
                    181:        {
                    182:                cred = lib->creds->create(lib->creds, type, subtype,
                    183:                                                                  BUILD_FROM_FILE, file, BUILD_END);
                    184:        }
                    185:        else if (keyid)
                    186:        {
                    187:                chunk_t chunk;
                    188: 
                    189:                chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
                    190:                cred = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
                    191:                                                                  BUILD_PKCS11_KEYID, chunk, BUILD_END);
                    192:                free(chunk.ptr);
                    193:        }
                    194:        else
                    195:        {
                    196:                chunk_t chunk;
                    197: 
                    198:                set_file_mode(stdin, CERT_ASN1_DER);
                    199:                if (!chunk_from_fd(0, &chunk))
                    200:                {
                    201:                        fprintf(stderr, "reading input failed: %s\n", strerror(errno));
                    202:                        return 1;
                    203:                }
                    204:                cred = lib->creds->create(lib->creds, type, subtype,
                    205:                                                                  BUILD_BLOB, chunk, BUILD_END);
                    206:                free(chunk.ptr);
                    207:        }
                    208:        if (!cred)
                    209:        {
                    210:                fprintf(stderr, "parsing input failed\n");
                    211:                return 1;
                    212:        }
                    213: 
                    214:        if (type == CRED_PRIVATE_KEY)
                    215:        {
                    216:                private = cred;
                    217:                if (private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &id))
                    218:                {
                    219:                        spk = chunk_clone(id);
                    220:                }
                    221:                if (private->get_fingerprint(private, KEYID_PUBKEY_INFO_SHA1, &id))
                    222:                {
                    223:                        spki = chunk_clone(id);
                    224:                }
                    225:                private->destroy(private);
                    226:        }
                    227:        else if (type == CRED_PUBLIC_KEY)
                    228:        {
                    229:                public = cred;
                    230:                if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &id))
                    231:                {
                    232:                        spk = chunk_clone(id);
                    233:                }
                    234:                if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &id))
                    235:                {
                    236:                        spki = chunk_clone(id);
                    237:                }
                    238:                public->destroy(public);
                    239:        }
                    240:        else
                    241:        {
                    242:                cert = cred;
                    243:                public = cert->get_public_key(cert);
                    244:                if (!public)
                    245:                {
                    246:                        fprintf(stderr, "extracting public key from certificate failed");
                    247:                        return 1;
                    248:                }
                    249:                if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &id))
                    250:                {
                    251:                        spk = chunk_clone(id);
                    252:                }
                    253:                if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &id))
                    254:                {
                    255:                        spki = chunk_clone(id);
                    256:                }
                    257:                public->destroy(public);
                    258:                cert->destroy(cert);
                    259:        }
                    260: 
                    261:        if (id_type == ID_TYPE_ALL || id_type == ID_TYPE_SPK)
                    262:        {
                    263:                if (!spk.len ||
                    264:                        !print_id(spk, format, "subjkey (SHA-1 of subjectPublicKey)"))
                    265:                {
                    266:                        return 1;
                    267:                }
                    268:        }
                    269:        if (id_type == ID_TYPE_ALL || id_type == ID_TYPE_SPKI)
                    270:        {
                    271:                if (!spki.len ||
                    272:                        !print_id(spki, format, "keyid (SHA-1 of subjectPublicKeyInfo)"))
                    273:                {
                    274:                        return 1;
                    275:                }
                    276:        }
                    277:        chunk_free(&spk);
                    278:        chunk_free(&spki);
                    279:        return 0;
                    280: }
                    281: 
                    282: /**
                    283:  * Register the command.
                    284:  */
                    285: static void __attribute__ ((constructor))reg()
                    286: {
                    287:        command_register((command_t)
                    288:                { keyid, 'k', "keyid",
                    289:                "calculate key identifiers of a key/certificate",
                    290:                {"[--in file|--keyid hex] [--type priv|rsa|ecdsa|bliss|pub|pkcs10|x509]",
                    291:                 "[--id all|spk|spki] [--format pretty|hex|base64|bin]"},
                    292:                {
                    293:                        {"help",        'h', 0, "show usage information"},
                    294:                        {"in",          'i', 1, "input file, default: stdin"},
                    295:                        {"keyid",       'x', 1, "smartcard or TPM private key object handle"},
                    296:                        {"type",        't', 1, "type of key, default: priv"},
                    297:                        {"id",          'I', 1, "type of identifier, default: all"},
                    298:                        {"format",      'f', 1, "output format, default: pretty"},
                    299:                }
                    300:        });
                    301: }

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