File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / pki / commands / verify.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) 2016-2018 Tobias Brunner
    3:  * Copyright (C) 2009 Martin Willi
    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 <sys/types.h>
   18: #include <sys/stat.h>
   19: #include <unistd.h>
   20: #include <errno.h>
   21: 
   22: #include "pki.h"
   23: 
   24: #include <credentials/certificates/certificate.h>
   25: #include <credentials/certificates/x509.h>
   26: #include <credentials/sets/mem_cred.h>
   27: 
   28: /**
   29:  * Load a CA or CRL and add it to the credential set
   30:  */
   31: static bool load_cert(mem_cred_t *creds, char *path, certificate_type_t subtype)
   32: {
   33: 	certificate_t *cert;
   34: 	char *credname;
   35: 
   36: 	switch (subtype)
   37: 	{
   38: 		case CERT_X509:
   39: 			credname = "CA certificate";
   40: 			break;
   41: 		case CERT_X509_CRL:
   42: 			credname = "CRL";
   43: 			break;
   44: 		default:
   45: 			return FALSE;
   46: 	}
   47: 	cert = lib->creds->create(lib->creds,
   48: 							  CRED_CERTIFICATE, subtype,
   49: 							  BUILD_FROM_FILE, path, BUILD_END);
   50: 	if (!cert)
   51: 	{
   52: 		fprintf(stderr, "parsing %s from '%s' failed\n", credname, path);
   53: 		return FALSE;
   54: 	}
   55: 	if (subtype == CERT_X509_CRL)
   56: 	{
   57: 		creds->add_crl(creds, (crl_t*)cert);
   58: 	}
   59: 	else
   60: 	{
   61: 		creds->add_cert(creds, TRUE, cert);
   62: 	}
   63: 	return TRUE;
   64: }
   65: 
   66: /**
   67:  * Load CA cert or CRL either from a file or a path
   68:  */
   69: static bool load_certs(mem_cred_t *creds, char *path,
   70: 					   certificate_type_t subtype)
   71: {
   72: 	enumerator_t *enumerator;
   73: 	struct stat st;
   74: 	bool loaded = FALSE;
   75: 
   76: 	if (stat(path, &st))
   77: 	{
   78: 		fprintf(stderr, "failed to access '%s': %s\n", path, strerror(errno));
   79: 		return FALSE;
   80: 	}
   81: 	if (S_ISDIR(st.st_mode))
   82: 	{
   83: 		enumerator = enumerator_create_directory(path);
   84: 		if (!enumerator)
   85: 		{
   86: 			fprintf(stderr, "directory '%s' can not be opened: %s",
   87: 					path, strerror(errno));
   88: 			return FALSE;
   89: 		}
   90: 		while (enumerator->enumerate(enumerator, NULL, &path, &st))
   91: 		{
   92: 			if (S_ISREG(st.st_mode) && load_cert(creds, path, subtype))
   93: 			{
   94: 				loaded = TRUE;
   95: 			}
   96: 		}
   97: 		enumerator->destroy(enumerator);
   98: 	}
   99: 	else
  100: 	{
  101: 		loaded = load_cert(creds, path, subtype);
  102: 	}
  103: 	return loaded;
  104: }
  105: 
  106: /**
  107:  * Verify a certificate signature
  108:  */
  109: static int verify()
  110: {
  111: 	bool trusted = FALSE, valid = FALSE, revoked = FALSE;
  112: 	bool has_ca = FALSE, online = FALSE;
  113: 	certificate_t *cert;
  114: 	enumerator_t *enumerator;
  115: 	auth_cfg_t *auth;
  116: 	mem_cred_t *creds;
  117: 	char *arg, *file = NULL;
  118: 
  119: 	creds = mem_cred_create();
  120: 	lib->credmgr->add_set(lib->credmgr, &creds->set);
  121: 
  122: 	while (TRUE)
  123: 	{
  124: 		switch (command_getopt(&arg))
  125: 		{
  126: 			case 'h':
  127: 				creds->destroy(creds);
  128: 				return command_usage(NULL);
  129: 			case 'i':
  130: 				file = arg;
  131: 				continue;
  132: 			case 'c':
  133: 				if (load_certs(creds, arg, CERT_X509))
  134: 				{
  135: 					has_ca = TRUE;
  136: 				}
  137: 				continue;
  138: 			case 'l':
  139: 				if (load_certs(creds, arg, CERT_X509_CRL))
  140: 				{
  141: 					online = TRUE;
  142: 				}
  143: 				continue;
  144: 			case 'o':
  145: 				online = TRUE;
  146: 				continue;
  147: 			case EOF:
  148: 				break;
  149: 			default:
  150: 				creds->destroy(creds);
  151: 				return command_usage("invalid --verify option");
  152: 		}
  153: 		break;
  154: 	}
  155: 
  156: 	if (file)
  157: 	{
  158: 		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
  159: 								  BUILD_FROM_FILE, file, BUILD_END);
  160: 	}
  161: 	else
  162: 	{
  163: 		chunk_t chunk;
  164: 
  165: 		set_file_mode(stdin, CERT_ASN1_DER);
  166: 		if (!chunk_from_fd(0, &chunk))
  167: 		{
  168: 			fprintf(stderr, "reading certificate failed: %s\n", strerror(errno));
  169: 			goto end;
  170: 		}
  171: 		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
  172: 								  BUILD_BLOB, chunk, BUILD_END);
  173: 		free(chunk.ptr);
  174: 	}
  175: 	if (!cert)
  176: 	{
  177: 		fprintf(stderr, "parsing certificate failed\n");
  178: 		goto end;
  179: 	}
  180: 	cert = creds->add_cert_ref(creds, !has_ca, cert);
  181: 
  182: 	enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr,
  183: 									KEY_ANY, cert->get_subject(cert), online);
  184: 	if (enumerator->enumerate(enumerator, &cert, &auth))
  185: 	{
  186: 		trusted = TRUE;
  187: 		if (cert->get_validity(cert, NULL, NULL, NULL))
  188: 		{
  189: 			printf("certificate trusted, lifetimes valid");
  190: 			valid = TRUE;
  191: 		}
  192: 		else
  193: 		{
  194: 			printf("certificate trusted, but no valid lifetime");
  195: 		}
  196: 		if (online)
  197: 		{
  198: 			switch ((uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION))
  199: 			{
  200: 				case VALIDATION_GOOD:
  201: 					printf(", certificate not revoked");
  202: 					break;
  203: 				case VALIDATION_SKIPPED:
  204: 					printf(", no revocation information");
  205: 					break;
  206: 				case VALIDATION_STALE:
  207: 					printf(", revocation information stale");
  208: 					break;
  209: 				case VALIDATION_FAILED:
  210: 					printf(", revocation checking failed");
  211: 					break;
  212: 				case VALIDATION_ON_HOLD:
  213: 					printf(", certificate revocation on hold");
  214: 					revoked = TRUE;
  215: 					break;
  216: 				case VALIDATION_REVOKED:
  217: 					printf(", certificate revoked");
  218: 					revoked = TRUE;
  219: 					break;
  220: 			}
  221: 		}
  222: 		printf("\n");
  223: 	}
  224: 	enumerator->destroy(enumerator);
  225: 	cert->destroy(cert);
  226: 
  227: 	if (!trusted)
  228: 	{
  229: 		printf("certificate untrusted\n");
  230: 	}
  231: 
  232: end:
  233: 	lib->credmgr->remove_set(lib->credmgr, &creds->set);
  234: 	creds->destroy(creds);
  235: 
  236: 	if (!trusted)
  237: 	{
  238: 		return 1;
  239: 	}
  240: 	if (!valid)
  241: 	{
  242: 		return 2;
  243: 	}
  244: 	if (revoked)
  245: 	{
  246: 		return 3;
  247: 	}
  248: 	return 0;
  249: }
  250: 
  251: /**
  252:  * Register the command.
  253:  */
  254: static void __attribute__ ((constructor))reg()
  255: {
  256: 	command_register((command_t) {
  257: 		verify, 'v', "verify",
  258: 		"verify a certificate using the CA certificate",
  259: 		{"[--in file] [--cacert file] [--crl file]"},
  260: 		{
  261: 			{"help",	'h', 0, "show usage information"},
  262: 			{"in",		'i', 1, "X.509 certificate to verify, default: stdin"},
  263: 			{"cacert",	'c', 1, "CA certificate for trustchain verification"},
  264: 			{"crl",		'l', 1, "CRL for trustchain verification"},
  265: 			{"online",	'o', 0, "enable online CRL/OCSP revocation checking"},
  266: 		}
  267: 	});
  268: }

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