File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / pki / commands / pkcs12.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) 2014 Tobias Brunner
    3:  * HSR Hochschule fuer Technik Rapperswil
    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 <errno.h>
   17: 
   18: #include "pki.h"
   19: 
   20: #include <credentials/certificates/x509.h>
   21: #include <credentials/containers/pkcs12.h>
   22: 
   23: /**
   24:  * Show info about PKCS#12 container
   25:  */
   26: static int show(pkcs12_t *pkcs12)
   27: {
   28: 	enumerator_t *enumerator;
   29: 	certificate_t *cert;
   30: 	private_key_t *key;
   31: 	int index = 1;
   32: 
   33: 	printf("Certificates:\n");
   34: 	enumerator = pkcs12->create_cert_enumerator(pkcs12);
   35: 	while (enumerator->enumerate(enumerator, &cert))
   36: 	{
   37: 		x509_t *x509 = (x509_t*)cert;
   38: 
   39: 		if (x509->get_flags(x509) & X509_CA)
   40: 		{
   41: 			printf("[%2d] \"%Y\" (CA)\n", index++, cert->get_subject(cert));
   42: 		}
   43: 		else
   44: 		{
   45: 			printf("[%2d] \"%Y\"\n", index++, cert->get_subject(cert));
   46: 		}
   47: 	}
   48: 	enumerator->destroy(enumerator);
   49: 
   50: 	printf("Private keys:\n");
   51: 	enumerator = pkcs12->create_key_enumerator(pkcs12);
   52: 	while (enumerator->enumerate(enumerator, &key))
   53: 	{
   54: 		printf("[%2d] %N %d bits\n", index++, key_type_names,
   55: 			   key->get_type(key), key->get_keysize(key));
   56: 	}
   57: 	enumerator->destroy(enumerator);
   58: 	return 0;
   59: }
   60: 
   61: static int export(pkcs12_t *pkcs12, int index, char *outform)
   62: {
   63: 	cred_encoding_type_t form;
   64: 	enumerator_t *enumerator;
   65: 	certificate_t *cert;
   66: 	private_key_t *key;
   67: 	chunk_t encoding;
   68: 	int i = 1;
   69: 
   70: 	enumerator = pkcs12->create_cert_enumerator(pkcs12);
   71: 	while (enumerator->enumerate(enumerator, &cert))
   72: 	{
   73: 		if (i++ == index)
   74: 		{
   75: 			form = CERT_ASN1_DER;
   76: 			if (outform && !get_form(outform, &form, CRED_CERTIFICATE))
   77: 			{
   78: 				enumerator->destroy(enumerator);
   79: 				return command_usage("invalid output format");
   80: 			}
   81: 			if (cert->get_encoding(cert, form, &encoding))
   82: 			{
   83: 				set_file_mode(stdout, form);
   84: 				if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
   85: 				{
   86: 					free(encoding.ptr);
   87: 					enumerator->destroy(enumerator);
   88: 					return 0;
   89: 				}
   90: 				free(encoding.ptr);
   91: 			}
   92: 			fprintf(stderr, "certificate export failed\n");
   93: 			enumerator->destroy(enumerator);
   94: 			return 1;
   95: 		}
   96: 	}
   97: 	enumerator->destroy(enumerator);
   98: 
   99: 	enumerator = pkcs12->create_key_enumerator(pkcs12);
  100: 	while (enumerator->enumerate(enumerator, &key))
  101: 	{
  102: 		if (i++ == index)
  103: 		{
  104: 			form = PRIVKEY_ASN1_DER;
  105: 			if (outform && !get_form(outform, &form, CRED_PRIVATE_KEY))
  106: 			{
  107: 				enumerator->destroy(enumerator);
  108: 				return command_usage("invalid output format");
  109: 			}
  110: 			if (key->get_encoding(key, form, &encoding))
  111: 			{
  112: 				set_file_mode(stdout, form);
  113: 				if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
  114: 				{
  115: 					free(encoding.ptr);
  116: 					enumerator->destroy(enumerator);
  117: 					return 0;
  118: 				}
  119: 				free(encoding.ptr);
  120: 			}
  121: 			fprintf(stderr, "private key export failed\n");
  122: 			enumerator->destroy(enumerator);
  123: 			return 0;
  124: 		}
  125: 	}
  126: 	enumerator->destroy(enumerator);
  127: 
  128: 	fprintf(stderr, "invalid index %d\n", index);
  129: 	return 1;
  130: }
  131: 
  132: 
  133: /**
  134:  * Handle PKCs#12 containers
  135:  */
  136: static int pkcs12()
  137: {
  138: 	char *arg, *file = NULL, *outform = NULL;
  139: 	pkcs12_t *p12 = NULL;
  140: 	int res = 1, index = 0;
  141: 	enum {
  142: 		OP_NONE,
  143: 		OP_LIST,
  144: 		OP_EXPORT,
  145: 	} op = OP_NONE;
  146: 
  147: 	while (TRUE)
  148: 	{
  149: 		switch (command_getopt(&arg))
  150: 		{
  151: 			case 'h':
  152: 				return command_usage(NULL);
  153: 			case 'i':
  154: 				file = arg;
  155: 				continue;
  156: 			case 'l':
  157: 				if (op != OP_NONE)
  158: 				{
  159: 					goto invalid;
  160: 				}
  161: 				op = OP_LIST;
  162: 				continue;
  163: 			case 'e':
  164: 				if (op != OP_NONE)
  165: 				{
  166: 					goto invalid;
  167: 				}
  168: 				op = OP_EXPORT;
  169: 				index = atoi(arg);
  170: 				continue;
  171: 			case 'f':
  172: 				outform = arg;
  173: 				continue;
  174: 			case EOF:
  175: 				break;
  176: 			default:
  177: 			invalid:
  178: 				return command_usage("invalid --pkcs12 option");
  179: 		}
  180: 		break;
  181: 	}
  182: 
  183: 	if (file)
  184: 	{
  185: 		p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
  186: 								  BUILD_FROM_FILE, file, BUILD_END);
  187: 	}
  188: 	else
  189: 	{
  190: 		chunk_t chunk;
  191: 
  192: 		set_file_mode(stdin, CERT_ASN1_DER);
  193: 		if (!chunk_from_fd(0, &chunk))
  194: 		{
  195: 			fprintf(stderr, "reading input failed: %s\n", strerror(errno));
  196: 			return 1;
  197: 		}
  198: 		p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
  199: 								  BUILD_BLOB, chunk, BUILD_END);
  200: 		free(chunk.ptr);
  201: 	}
  202: 
  203: 	if (!p12)
  204: 	{
  205: 		fprintf(stderr, "reading input failed!\n");
  206: 		goto end;
  207: 	}
  208: 
  209: 	switch (op)
  210: 	{
  211: 		case OP_LIST:
  212: 			res = show(p12);
  213: 			break;
  214: 		case OP_EXPORT:
  215: 			res = export(p12, index, outform);
  216: 			break;
  217: 		default:
  218: 			p12->container.destroy(&p12->container);
  219: 			return command_usage(NULL);
  220: 	}
  221: 
  222: end:
  223: 	if (p12)
  224: 	{
  225: 		p12->container.destroy(&p12->container);
  226: 	}
  227: 	return res;
  228: }
  229: 
  230: /**
  231:  * Register the command.
  232:  */
  233: static void __attribute__ ((constructor))reg()
  234: {
  235: 	command_register((command_t) {
  236: 		pkcs12, 'u', "pkcs12", "PKCS#12 functions",
  237: 		{"--export index|--list [--in file]",
  238: 		 "[--outform der|pem]"},
  239: 		{
  240: 			{"help",	'h', 0, "show usage information"},
  241: 			{"in",		'i', 1, "input file, default: stdin"},
  242: 			{"list",	'l', 0, "list certificates and keys"},
  243: 			{"export",	'e', 1, "export the credential with the given index"},
  244: 			{"outform",	'f', 1, "encoding of exported credentials, default: der"},
  245: 		}
  246: 	});
  247: }

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