File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / pki / commands / keyid.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    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>