Exemplo n.º 1
0
static int load_all(vici_conn_t *conn)
{
	bool clear = FALSE, noprompt = FALSE;
	command_format_options_t format = COMMAND_FORMAT_NONE;
	settings_t *cfg;
	int ret = 0;
	char *arg;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'c':
				clear = TRUE;
				continue;
			case 'n':
				noprompt = TRUE;
				continue;
			case 'P':
				format |= COMMAND_FORMAT_PRETTY;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_RAW;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --load-all option");
		}
		break;
	}

	cfg = settings_create(SWANCTL_CONF);
	if (!cfg)
	{
		fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF);
		return EINVAL;
	}

	if (ret == 0)
	{
		ret = load_creds_cfg(conn, format, cfg, clear, noprompt);
	}
	if (ret == 0)
	{
		ret = load_pools_cfg(conn, format, cfg);
	}
	if (ret == 0)
	{
		ret = load_conns_cfg(conn, format, cfg);
	}

	cfg->destroy(cfg);

	return ret;
}
Exemplo n.º 2
0
static int list_pools(vici_conn_t *conn)
{
	vici_req_t *req;
	vici_res_t *res;
	bool raw = FALSE;
	char *arg;
	int ret = 0;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'r':
				raw = TRUE;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --list-pools option");
		}
		break;
	}

	req = vici_begin("get-pools");
	res = vici_submit(req, conn);
	if (!res)
	{
		fprintf(stderr, "get-pools request failed: %s\n", strerror(errno));
		return errno;
	}
	if (raw)
	{
		vici_dump(res, "get-pools reply", stdout);
	}
	else
	{
		ret = vici_parse_cb(res, list_pool, NULL, NULL, NULL);
	}
	vici_free_res(res);
	return ret;
}
Exemplo n.º 3
0
static int load_authorities(vici_conn_t *conn)
{
	command_format_options_t format = COMMAND_FORMAT_NONE;
	settings_t *cfg;
	char *arg, *file = NULL;
	int ret;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'P':
				format |= COMMAND_FORMAT_PRETTY;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_RAW;
				continue;
			case 'f':
				file = arg;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --load-authorities option");
		}
		break;
	}

	cfg = load_swanctl_conf(file);
	if (!cfg)
	{
		return EINVAL;
	}

	ret = load_authorities_cfg(conn, format, cfg);

	cfg->destroy(cfg);

	return ret;
}
Exemplo n.º 4
0
static int load_authorities(vici_conn_t *conn)
{
	command_format_options_t format = COMMAND_FORMAT_NONE;
	settings_t *cfg;
	char *arg;
	int ret;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'P':
				format |= COMMAND_FORMAT_PRETTY;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_RAW;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --load-authorities option");
		}
		break;
	}

	cfg = settings_create(SWANCTL_CONF);
	if (!cfg)
	{
		fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF);
		return EINVAL;
	}

	ret = load_authorities_cfg(conn, format, cfg);

	cfg->destroy(cfg);

	return ret;
}
Exemplo n.º 5
0
static int logcmd(vici_conn_t *conn)
{
	command_format_options_t format = COMMAND_FORMAT_NONE;
	char *arg;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'P':
				format |= COMMAND_FORMAT_PRETTY;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_RAW;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --log option");
		}
		break;
	}

	if (vici_register(conn, "log", log_cb, &format) != 0)
	{
		fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
		return errno;
	}

	wait_sigint();

	fprintf(stderr, "disconnecting...\n");

	return 0;
}
Exemplo n.º 6
0
/**
 * Verify a certificate signature
 */
static int verify()
{
	bool trusted = FALSE, valid = FALSE, revoked = FALSE;
	bool has_ca = FALSE, online = FALSE;
	certificate_t *cert;
	enumerator_t *enumerator;
	auth_cfg_t *auth;
	mem_cred_t *creds;
	char *arg, *file = NULL;

	creds = mem_cred_create();
	lib->credmgr->add_set(lib->credmgr, &creds->set);

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				creds->destroy(creds);
				return command_usage(NULL);
			case 'i':
				file = arg;
				continue;
			case 'c':
				if (load_certs(creds, arg, CERT_X509))
				{
					has_ca = TRUE;
				}
				continue;
			case 'l':
				if (load_certs(creds, arg, CERT_X509_CRL))
				{
					online = TRUE;
				}
				continue;
			case 'o':
				online = TRUE;
				continue;
			case EOF:
				break;
			default:
				creds->destroy(creds);
				return command_usage("invalid --verify option");
		}
		break;
	}

	if (file)
	{
		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								  BUILD_FROM_FILE, file, BUILD_END);
	}
	else
	{
		chunk_t chunk;

		set_file_mode(stdin, CERT_ASN1_DER);
		if (!chunk_from_fd(0, &chunk))
		{
			fprintf(stderr, "reading certificate failed: %s\n", strerror(errno));
			goto end;
		}
		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								  BUILD_BLOB, chunk, BUILD_END);
		free(chunk.ptr);
	}
	if (!cert)
	{
		fprintf(stderr, "parsing certificate failed\n");
		goto end;
	}
	cert = creds->add_cert_ref(creds, !has_ca, cert);

	enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr,
									KEY_ANY, cert->get_subject(cert), online);
	if (enumerator->enumerate(enumerator, &cert, &auth))
	{
		trusted = TRUE;
		if (cert->get_validity(cert, NULL, NULL, NULL))
		{
			printf("certificate trusted, lifetimes valid");
			valid = TRUE;
		}
		else
		{
			printf("certificate trusted, but no valid lifetime");
		}
		if (online)
		{
			switch ((uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION))
			{
				case VALIDATION_GOOD:
					printf(", certificate not revoked");
					break;
				case VALIDATION_SKIPPED:
					printf(", no revocation information");
					break;
				case VALIDATION_STALE:
					printf(", revocation information stale");
					break;
				case VALIDATION_FAILED:
					printf(", revocation checking failed");
					break;
				case VALIDATION_ON_HOLD:
					printf(", certificate revocation on hold");
					revoked = TRUE;
					break;
				case VALIDATION_REVOKED:
					printf(", certificate revoked");
					revoked = TRUE;
					break;
			}
		}
		printf("\n");
	}
	enumerator->destroy(enumerator);
	cert->destroy(cert);

	if (!trusted)
	{
		printf("certificate untrusted\n");
	}

end:
	lib->credmgr->remove_set(lib->credmgr, &creds->set);
	creds->destroy(creds);

	if (!trusted)
	{
		return 1;
	}
	if (!valid)
	{
		return 2;
	}
	if (revoked)
	{
		return 3;
	}
	return 0;
}
Exemplo n.º 7
0
static int load_pools(vici_conn_t *conn)
{
	command_format_options_t format = COMMAND_FORMAT_NONE;
	u_int found = 0, loaded = 0, unloaded = 0;
	char *arg, *section;
	enumerator_t *enumerator;
	linked_list_t *pools;
	settings_t *cfg;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'P':
				format |= COMMAND_FORMAT_PRETTY;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_RAW;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --load-pools option");
		}
		break;
	}

	cfg = settings_create(SWANCTL_CONF);
	if (!cfg)
	{
		fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF);
		return EINVAL;
	}

	pools = list_pools(conn, format);

	enumerator = cfg->create_section_enumerator(cfg, "pools");
	while (enumerator->enumerate(enumerator, &section))
	{
		remove_from_list(pools, section);
		found++;
		if (load_pool(conn, cfg, section, format))
		{
			loaded++;
		}
	}
	enumerator->destroy(enumerator);

	cfg->destroy(cfg);

	/* unload all pools in daemon, but not in file */
	while (pools->remove_first(pools, (void**)&section) == SUCCESS)
	{
		if (unload_pool(conn, section, format))
		{
			unloaded++;
		}
		free(section);
	}
	pools->destroy(pools);

	if (format & COMMAND_FORMAT_RAW)
	{
		return 0;
	}
	if (found == 0)
	{
		printf("no pools found, %u unloaded\n", unloaded);
		return 0;
	}
	if (loaded == found)
	{
		printf("successfully loaded %u pools, %u unloaded\n",
			   loaded, unloaded);
		return 0;
	}
	fprintf(stderr, "loaded %u of %u pools, %u failed to load, "
			"%u unloaded\n", loaded, found, found - loaded, unloaded);
	return EINVAL;
}
Exemplo n.º 8
0
/**
 * Extract subject DN
 */
static int dn()
{
	identification_t *id;
	certificate_t *cert;
	chunk_t chunk;
	enum {
		FORMAT_CONFIG,
		FORMAT_HEX,
		FORMAT_BASE64,
		FORMAT_BINARY,
	} format = FORMAT_CONFIG;
	char *arg, *file = NULL, *fmt;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'f':
				if (streq(arg, "hex"))
				{
					format = FORMAT_HEX;
				}
				else if (streq(arg, "base64"))
				{
					format = FORMAT_BASE64;
				}
				else if (streq(arg, "bin"))
				{
					format = FORMAT_BINARY;
				}
				else if (!streq(arg, "config"))
				{
					return command_usage( "invalid output format");
				}
				continue;
			case 'i':
				file = arg;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --print option");
		}
		break;
	}
	if (file)
	{
		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								  BUILD_FROM_FILE, file, BUILD_END);
	}
	else
	{
		chunk_t chunk;

		set_file_mode(stdin, CERT_ASN1_DER);
		if (!chunk_from_fd(0, &chunk))
		{
			fprintf(stderr, "reading input failed: %s\n", strerror(errno));
			return 1;
		}
		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								  BUILD_BLOB, chunk, BUILD_END);
		free(chunk.ptr);
	}
	if (!cert)
	{
		fprintf(stderr, "parsing input failed\n");
		return 1;
	}
	id = cert->get_subject(cert);
	if (!id)
	{
		fprintf(stderr, "failed to get certificate's subject DN\n");
		cert->destroy(cert);
		return 1;
	}
	fmt = "%.*s\n";
	switch (format)
	{
		case FORMAT_CONFIG:
			fmt = "\"asn1dn:#%.*s\"\n";
			/* fall-through */
		case FORMAT_HEX:
			chunk = chunk_to_hex(id->get_encoding(id), NULL, FALSE);
			printf(fmt, (int)chunk.len, chunk.ptr);
			chunk_free(&chunk);
			break;
		case FORMAT_BASE64:
			chunk = chunk_to_base64(id->get_encoding(id), NULL);
			printf(fmt, (int)chunk.len, chunk.ptr);
			chunk_free(&chunk);
			break;
		case FORMAT_BINARY:
			chunk = id->get_encoding(id);
			if (fwrite(chunk.ptr, chunk.len, 1, stdout) != 1)
			{
				fprintf(stderr, "writing subject DN failed\n");
			}
			break;
	}
	cert->destroy(cert);
	return 0;
}
Exemplo n.º 9
0
/**
 * Issue an attribute certificate
 */
static int acert()
{
	cred_encoding_type_t form = CERT_ASN1_DER;
	hash_algorithm_t digest = HASH_SHA1;
	certificate_t *ac = NULL, *cert = NULL, *issuer =NULL;
	private_key_t *private = NULL;
	public_key_t *public = NULL;
	char *file = NULL, *hex = NULL, *issuercert = NULL, *issuerkey = NULL;
	char *error = NULL, *keyid = NULL;
	linked_list_t *groups;
	chunk_t serial = chunk_empty, encoding = chunk_empty;
	time_t not_before, not_after, lifetime = 24 * 60 * 60;
	char *datenb = NULL, *datena = NULL, *dateform = NULL;
	rng_t *rng;
	char *arg;

	groups = linked_list_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				goto usage;
			case 'g':
				if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
				{
					error = "invalid --digest type";
					goto usage;
				}
				continue;
			case 'i':
				file = arg;
				continue;
			case 'm':
				groups->insert_last(groups, arg);
				continue;
			case 'c':
				issuercert = arg;
				continue;
			case 'k':
				issuerkey = arg;
				continue;
			case 'x':
				keyid = arg;
				continue;
			case 'l':
				lifetime = atoi(arg) * 60 * 60;
				if (!lifetime)
				{
					error = "invalid --lifetime value";
					goto usage;
				}
				continue;
			case 'D':
				dateform = arg;
				continue;
			case 'F':
				datenb = arg;
				continue;
			case 'T':
				datena = arg;
				continue;
			case 's':
				hex = arg;
				continue;
			case 'f':
				if (!get_form(arg, &form, CRED_CERTIFICATE))
				{
					error = "invalid output format";
					goto usage;
				}
				continue;
			case EOF:
				break;
			default:
				error = "invalid --acert option";
				goto usage;
		}
		break;
	}

	if (!calculate_lifetime(dateform, datenb, datena, lifetime,
							&not_before, &not_after))
	{
		error = "invalid --not-before/after datetime";
		goto usage;
	}

	if (!issuercert)
	{
		error = "--issuercert is required";
		goto usage;
	}
	if (!issuerkey && !keyid)
	{
		error = "--issuerkey or --issuerkeyid is required";
		goto usage;
	}

	issuer = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								BUILD_FROM_FILE, issuercert, BUILD_END);
	if (!issuer)
	{
		error = "parsing issuer certificate failed";
		goto end;
	}
	public = issuer->get_public_key(issuer);
Exemplo n.º 10
0
/**
 * Create a self-signed PKCS#10 certificate requesst.
 */
static int req()
{
	cred_encoding_type_t form = CERT_ASN1_DER;
	key_type_t type = KEY_RSA;
	hash_algorithm_t digest = HASH_SHA1;
	certificate_t *cert = NULL;
	private_key_t *private = NULL;
	char *file = NULL, *dn = NULL, *error = NULL;
	identification_t *id = NULL;
	linked_list_t *san;
	chunk_t encoding = chunk_empty;
	chunk_t challenge_password = chunk_empty;
	char *arg;

	san = linked_list_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				goto usage;
			case 't':
				if (streq(arg, "rsa"))
				{
					type = KEY_RSA;
				}
				else if (streq(arg, "ecdsa"))
				{
					type = KEY_ECDSA;
				}
				else if (streq(arg, "bliss"))
				{
					type = KEY_BLISS;
				}
				else
				{
					error = "invalid input type";
					goto usage;
				}
				continue;
			case 'g':
				if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
				{
					error = "invalid --digest type";
					goto usage;
				}
				continue;
			case 'i':
				file = arg;
				continue;
			case 'd':
				dn = arg;
				continue;
			case 'a':
				san->insert_last(san, identification_create_from_string(arg));
				continue;
			case 'p':
				challenge_password = chunk_create(arg, strlen(arg));
				continue;
			case 'f':
				if (!get_form(arg, &form, CRED_CERTIFICATE))
				{
					error = "invalid output format";
					goto usage;
				}
				continue;
			case EOF:
				break;
			default:
				error = "invalid --req option";
				goto usage;
		}
		break;
	}

	if (type == KEY_BLISS)
	{
		/* currently only SHA-512 is supported */
		digest = HASH_SHA512;
	}
	if (!dn)
	{
		error = "--dn is required";
		goto usage;
	}
	id = identification_create_from_string(dn);
	if (id->get_type(id) != ID_DER_ASN1_DN)
	{
		error = "supplied --dn is not a distinguished name";
		goto end;
	}
	if (file)
	{
		private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
									 BUILD_FROM_FILE, file, BUILD_END);
	}
Exemplo n.º 11
0
static int stats(vici_conn_t *conn)
{
    vici_req_t *req;
    vici_res_t *res;
    char *arg;
    command_format_options_t format = COMMAND_FORMAT_NONE;

    while (TRUE)
    {
        switch (command_getopt(&arg))
        {
        case 'h':
            return command_usage(NULL);
        case 'P':
            format |= COMMAND_FORMAT_PRETTY;
        /* fall through to raw */
        case 'r':
            format |= COMMAND_FORMAT_RAW;
            continue;
        case EOF:
            break;
        default:
            return command_usage("invalid --stats option");
        }
        break;
    }

    req = vici_begin("stats");
    res = vici_submit(req, conn);
    if (!res)
    {
        fprintf(stderr, "stats request failed: %s\n", strerror(errno));
        return errno;
    }
    if (format & COMMAND_FORMAT_RAW)
    {
        vici_dump(res, "stats reply", format & COMMAND_FORMAT_PRETTY, stdout);
    }
    else
    {
        printf("uptime: %s, since %s\n",
               vici_find_str(res, "", "uptime.running"),
               vici_find_str(res, "", "uptime.since"));

        printf("worker threads: %s total, %s idle, working: %s/%s/%s/%s\n",
               vici_find_str(res, "", "workers.total"),
               vici_find_str(res, "", "workers.idle"),
               vici_find_str(res, "", "workers.active.critical"),
               vici_find_str(res, "", "workers.active.high"),
               vici_find_str(res, "", "workers.active.medium"),
               vici_find_str(res, "", "workers.active.low"));

        printf("job queues: %s/%s/%s/%s\n",
               vici_find_str(res, "", "queues.critical"),
               vici_find_str(res, "", "queues.high"),
               vici_find_str(res, "", "queues.medium"),
               vici_find_str(res, "", "queues.low"));

        printf("jobs scheduled: %s\n",
               vici_find_str(res, "", "scheduled"));

        printf("IKE_SAs: %s total, %s half-open\n",
               vici_find_str(res, "", "ikesas.total"),
               vici_find_str(res, "", "ikesas.half-open"));

        if (vici_find_str(res, NULL, "mem.total"))
        {
            printf("memory usage: %s bytes, %s allocations\n",
                   vici_find_str(res, "", "mem.total"),
                   vici_find_str(res, "", "mem.allocs"));
        }
        if (vici_find_str(res, NULL, "mallinfo.sbrk"))
        {
            printf("mallinfo: sbrk %s, mmap %s, used %s, free %s\n",
                   vici_find_str(res, "", "mallinfo.sbrk"),
                   vici_find_str(res, "", "mallinfo.mmap"),
                   vici_find_str(res, "", "mallinfo.used"),
                   vici_find_str(res, "", "mallinfo.free"));
        }
    }
    vici_free_res(res);
    return 0;
}
Exemplo n.º 12
0
static int manage_policy(vici_conn_t *conn, char *label)
{
	vici_req_t *req;
	vici_res_t *res;
	command_format_options_t format = COMMAND_FORMAT_NONE;
	char *arg, *child = NULL, *ike = NULL;
	int ret = 0;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'P':
				format |= COMMAND_FORMAT_RAW;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_PRETTY;
				continue;
			case 'c':
				child = arg;
				continue;
			case 'i':
				ike = arg;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --%s option", label);
		}
		break;
	}
	req = vici_begin(label);
	if (child)
	{
		vici_add_key_valuef(req, "child", "%s", child);
	}
	if (ike)
	{
		vici_add_key_valuef(req, "ike", "%s", ike);
	}
	res = vici_submit(req, conn);
	if (!res)
	{
		ret = errno;
		fprintf(stderr, "%s request failed: %s\n", label, strerror(errno));
		return ret;
	}
	if (format & COMMAND_FORMAT_RAW)
	{
		puts(label);
		vici_dump(res, " reply", format & COMMAND_FORMAT_PRETTY, stdout);
	}
	else
	{
		if (streq(vici_find_str(res, "no", "success"), "yes"))
		{
			printf("%s completed successfully\n", label);
		}
		else
		{
			fprintf(stderr, "%s failed: %s\n",
					label, vici_find_str(res, "", "errmsg"));
			ret = 1;
		}
	}
	vici_free_res(res);
	return ret;
}
Exemplo n.º 13
0
static int initiate(vici_conn_t *conn)
{
	vici_req_t *req;
	vici_res_t *res;
	command_format_options_t format = COMMAND_FORMAT_NONE;
	char *arg, *child = NULL;
	int ret = 0, timeout = 0, level = 1;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'P':
				format |= COMMAND_FORMAT_PRETTY;
				/* fall through to raw */
			case 'r':
				format |= COMMAND_FORMAT_RAW;
				continue;
			case 'c':
				child = arg;
				continue;
			case 't':
				timeout = atoi(arg);
				continue;
			case 'l':
				level = atoi(arg);
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --initiate option");
		}
		break;
	}

	if (vici_register(conn, "control-log", log_cb, &format) != 0)
	{
		fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
		return errno;
	}
	req = vici_begin("initiate");
	if (child)
	{
		vici_add_key_valuef(req, "child", "%s", child);
	}
	if (timeout)
	{
		vici_add_key_valuef(req, "timeout", "%d", timeout * 1000);
	}
	vici_add_key_valuef(req, "loglevel", "%d", level);
	res = vici_submit(req, conn);
	if (!res)
	{
		fprintf(stderr, "initiate request failed: %s\n", strerror(errno));
		return errno;
	}
	if (format & COMMAND_FORMAT_RAW)
	{
		vici_dump(res, "initiate reply", format & COMMAND_FORMAT_PRETTY,
				  stdout);
	}
	else
	{
		if (streq(vici_find_str(res, "no", "success"), "yes"))
		{
			printf("initiate completed successfully\n");
		}
		else
		{
			fprintf(stderr, "initiate failed: %s\n",
					vici_find_str(res, "", "errmsg"));
			ret = 1;
		}
	}
	vici_free_res(res);
	return ret;
}
Exemplo n.º 14
0
/**
 * Create a self-signed PKCS#10 certificate requesst.
 */
static int req()
{
	cred_encoding_type_t form = CERT_ASN1_DER;
	key_type_t type = KEY_ANY;
	hash_algorithm_t digest = HASH_UNKNOWN;
	signature_params_t *scheme = NULL;
	certificate_t *cert = NULL;
	private_key_t *private = NULL;
	char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
	identification_t *id = NULL;
	linked_list_t *san;
	chunk_t encoding = chunk_empty;
	chunk_t challenge_password = chunk_empty;
	char *arg;
	bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
									   lib->ns);

	san = linked_list_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				goto usage;
			case 't':
				if (streq(arg, "rsa"))
				{
					type = KEY_RSA;
				}
				else if (streq(arg, "ecdsa"))
				{
					type = KEY_ECDSA;
				}
				else if (streq(arg, "bliss"))
				{
					type = KEY_BLISS;
				}
				else if (streq(arg, "priv"))
				{
					type = KEY_ANY;
				}
				else
				{
					error = "invalid input type";
					goto usage;
				}
				continue;
			case 'g':
				if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
				{
					error = "invalid --digest type";
					goto usage;
				}
				continue;
			case 'R':
				if (streq(arg, "pss"))
				{
					pss = TRUE;
				}
				else if (!streq(arg, "pkcs1"))
				{
					error = "invalid RSA padding";
					goto usage;
				}
				continue;
			case 'i':
				file = arg;
				continue;
			case 'd':
				dn = arg;
				continue;
			case 'a':
				san->insert_last(san, identification_create_from_string(arg));
				continue;
			case 'p':
				challenge_password = chunk_create(arg, strlen(arg));
				continue;
			case 'f':
				if (!get_form(arg, &form, CRED_CERTIFICATE))
				{
					error = "invalid output format";
					goto usage;
				}
				continue;
			case 'x':
				keyid = arg;
				continue;
			case EOF:
				break;
			default:
				error = "invalid --req option";
				goto usage;
		}
		break;
	}

	if (!dn)
	{
		error = "--dn is required";
		goto usage;
	}
	id = identification_create_from_string(dn);
	if (id->get_type(id) != ID_DER_ASN1_DN)
	{
		error = "supplied --dn is not a distinguished name";
		goto end;
	}
	if (file)
	{
		private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
									 BUILD_FROM_FILE, file, BUILD_END);
	}
Exemplo n.º 15
0
/**
 * Wrap/Unwrap PKCs#7 containers
 */
static int pkcs7()
{
	char *arg, *file = NULL;
	private_key_t *key = NULL;
	certificate_t *cert = NULL;
	chunk_t data = chunk_empty;
	mem_cred_t *creds;
	int res = 1;
	FILE *in;
	enum {
		OP_NONE,
		OP_SIGN,
		OP_VERIFY,
		OP_ENCRYPT,
		OP_DECRYPT,
		OP_SHOW,
	} op = OP_NONE;

	creds = mem_cred_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				creds->destroy(creds);
				return command_usage(NULL);
			case 'i':
				file = arg;
				continue;
			case 's':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_SIGN;
				continue;
			case 'u':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_VERIFY;
				continue;
			case 'e':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_ENCRYPT;
				continue;
			case 'd':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_DECRYPT;
				continue;
			case 'p':
				if (op != OP_NONE)
				{
					goto invalid;
				}
				op = OP_SHOW;
				continue;
			case 'k':
				key = lib->creds->create(lib->creds,
										 CRED_PRIVATE_KEY, KEY_RSA,
										 BUILD_FROM_FILE, arg, BUILD_END);
				if (!key)
				{
					fprintf(stderr, "parsing private key failed\n");
					goto end;
				}
				creds->add_key(creds, key);
				continue;
			case 'c':
				cert = lib->creds->create(lib->creds,
										  CRED_CERTIFICATE, CERT_X509,
										  BUILD_FROM_FILE, arg, BUILD_END);
				if (!cert)
				{
					fprintf(stderr, "parsing certificate failed\n");
					goto end;
				}
				creds->add_cert(creds, TRUE, cert);
				continue;
			case EOF:
				break;
			default:
			invalid:
				creds->destroy(creds);
				return command_usage("invalid --pkcs7 option");
		}
		break;
	}

	if (file)
	{
		in = fopen(file, "r");
		if (in)
		{
			data = read_from_stream(in);
			fclose(in);
		}
	}
	else
	{
		data = read_from_stream(stdin);
	}

	if (!data.len)
	{
		fprintf(stderr, "reading input failed!\n");
		goto end;
	}
	if (op != OP_SHOW && !cert)
	{
		fprintf(stderr, "requiring a certificate!\n");
		goto end;
	}

	lib->credmgr->add_local_set(lib->credmgr, &creds->set, FALSE);

	switch (op)
	{
		case OP_SIGN:
			if (!key)
			{
				fprintf(stderr, "signing requires a private key\n");
				res = 1;
				break;
			}
			res = sign(data, cert, key);
			break;
		case OP_VERIFY:
			res = verify(data);
			break;
		case OP_ENCRYPT:
			res = encrypt(data, cert);
			break;
		case OP_DECRYPT:
			if (!key)
			{
				fprintf(stderr, "decryption requires a private key\n");
				res = 1;
				break;
			}
			res = decrypt(data);
			break;
		case OP_SHOW:
			res = show(data);
			break;
		default:
			res = 1;
			break;
	}
	lib->credmgr->remove_local_set(lib->credmgr, &creds->set);

end:
	creds->destroy(creds);
	free(data.ptr);
	return res;
}
Exemplo n.º 16
0
/**
 * Sign a CRL
 */
static int sign_crl()
{
	cred_encoding_type_t form = CERT_ASN1_DER;
	private_key_t *private = NULL;
	public_key_t *public = NULL;
	certificate_t *ca = NULL, *crl = NULL;
	crl_t *lastcrl = NULL;
	x509_t *x509;
	hash_algorithm_t digest = HASH_UNKNOWN;
	signature_params_t *scheme = NULL;
	char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL;
	char *basecrl = NULL;
	char serial[512], *keyid = NULL;
	int serial_len;
	crl_reason_t reason = CRL_REASON_UNSPECIFIED;
	time_t thisUpdate, nextUpdate, date = time(NULL);
	time_t lifetime = 15 * 24 * 60 * 60;
	char *datetu = NULL, *datenu = NULL, *dateform = NULL;
	linked_list_t *list, *cdps;
	enumerator_t *enumerator, *lastenum = NULL;
	x509_cdp_t *cdp;
	chunk_t crl_serial = chunk_empty, baseCrlNumber = chunk_empty;
	chunk_t encoding = chunk_empty;
	bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
									   lib->ns);

	list = linked_list_create();
	cdps = linked_list_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				goto usage;
			case 'g':
				if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
				{
					error = "invalid --digest type";
					goto usage;
				}
				continue;
			case 'R':
				if (streq(arg, "pss"))
				{
					pss = TRUE;
				}
				else if (!streq(arg, "pkcs1"))
				{
					error = "invalid RSA padding";
					goto usage;
				}
				continue;
			case 'c':
				cacert = arg;
				continue;
			case 'k':
				cakey = arg;
				continue;
			case 'x':
				keyid = arg;
				continue;
			case 'a':
				lastupdate = arg;
				continue;
			case 'l':
				lifetime = atoi(arg) * 24 * 60 * 60;
				if (!lifetime)
				{
					error = "invalid --lifetime value";
					goto usage;
				}
				continue;
			case 'D':
				dateform = arg;
				continue;
			case 'F':
				datetu = arg;
				continue;
			case 'T':
				datenu = arg;
				continue;
			case 'z':
				serial_len = read_serial(arg, serial, sizeof(serial));
				if (serial_len < 0)
				{
					snprintf(serial, sizeof(serial),
							 "parsing certificate '%s' failed", arg);
					error = serial;
					goto error;
				}
				add_revoked(list, chunk_create(serial, serial_len), reason, date);
				date = time(NULL);
				reason = CRL_REASON_UNSPECIFIED;
				continue;
			case 's':
			{
				chunk_t chunk;
				int hex_len;

				hex_len = strlen(arg);
				if ((hex_len / 2) + (hex_len % 2) > sizeof(serial))
				{
					error = "invalid serial";
					goto usage;
				}
				chunk = chunk_from_hex(chunk_create(arg, hex_len), serial);
				serial_len = chunk.len;
				add_revoked(list, chunk_create(serial, serial_len), reason, date);
				date = time(NULL);
				reason = CRL_REASON_UNSPECIFIED;
				continue;
			}
			case 'b':
				basecrl = arg;
				continue;
			case 'u':
				INIT(cdp,
					.uri = strdup(arg),
				);
				cdps->insert_last(cdps, cdp);
				continue;
			case 'r':
				if (streq(arg, "key-compromise"))
				{
					reason = CRL_REASON_KEY_COMPROMISE;
				}
				else if (streq(arg, "ca-compromise"))
				{
					reason = CRL_REASON_CA_COMPROMISE;
				}
				else if (streq(arg, "affiliation-changed"))
				{
					reason = CRL_REASON_AFFILIATION_CHANGED;
				}
				else if (streq(arg, "superseded"))
				{
					reason = CRL_REASON_SUPERSEDED;
				}
				else if (streq(arg, "cessation-of-operation"))
				{
					reason = CRL_REASON_CESSATION_OF_OPERATON;
				}
				else if (streq(arg, "certificate-hold"))
				{
					reason = CRL_REASON_CERTIFICATE_HOLD;
				}
				else
				{
					error = "invalid revocation reason";
					goto usage;
				}
				continue;
			case 'd':
				date = atol(arg);
				if (!date)
				{
					error = "invalid date";
					goto usage;
				}
				continue;
			case 'f':
				if (!get_form(arg, &form, CRED_CERTIFICATE))
				{
					error = "invalid output format";
					goto usage;
				}
				continue;
			case EOF:
				break;
			default:
				error = "invalid --signcrl option";
				goto usage;
		}
		break;
	}

	if (!cacert)
	{
		error = "--cacert is required";
		goto usage;
	}
	if (!cakey && !keyid)
	{
		error = "--cakey or --keyid is required";
		goto usage;
	}
	if (!calculate_lifetime(dateform, datetu, datenu, lifetime,
							&thisUpdate, &nextUpdate))
	{
		error = "invalid --this/next-update datetime";
		goto usage;
	}

	ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
							BUILD_FROM_FILE, cacert, BUILD_END);
	if (!ca)
	{
		error = "parsing CA certificate failed";
		goto error;
	}
	x509 = (x509_t*)ca;
	if (!(x509->get_flags(x509) & (X509_CA | X509_CRL_SIGN)))
	{
		error = "CA certificate misses CA basicConstraint / CRLSign keyUsage";
		goto error;
	}
	public = ca->get_public_key(ca);
Exemplo n.º 17
0
/**
 * Generate a private key
 */
static int gen()
{
	key_encoding_type_t form = KEY_PRIV_ASN1_DER;
	key_type_t type = KEY_RSA;
	u_int size = 0;
	private_key_t *key;
	chunk_t encoding;
	char *arg;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 't':
				if (streq(arg, "rsa"))
				{
					type = KEY_RSA;
				}
				else if (streq(arg, "ecdsa"))
				{
					type = KEY_ECDSA;
				}
				else
				{
					return command_usage("invalid key type");
				}
				continue;
			case 'f':
				if (!get_form(arg, &form, FALSE))
				{
					return command_usage("invalid key output format");
				}
				continue;
			case 's':
				size = atoi(arg);
				if (!size)
				{
					return command_usage("invalid key size");
				}
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --gen option");
		}
		break;
	}
	/* default key sizes */
	if (!size)
	{
		switch (type)
		{
			case KEY_RSA:
				size = 2048;
				break;
			case KEY_ECDSA:
				size = 384;
				break;
			default:
				break;
		}
	}
	key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
							 BUILD_KEY_SIZE, size, BUILD_END);
	if (!key)
	{
		fprintf(stderr, "private key generation failed\n");
		return 1;
	}
	if (!key->get_encoding(key, form, &encoding))
	{
		fprintf(stderr, "private key encoding failed\n");
		key->destroy(key);
		return 1;
	}
	key->destroy(key);
	if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
	{
		fprintf(stderr, "writing private key failed\n");
		free(encoding.ptr);
		return 1;
	}
	free(encoding.ptr);
	return 0;
}
Exemplo n.º 18
0
/**
 * Calculate the keyid of a key/certificate
 */
static int keyid()
{
	credential_type_t type = CRED_PRIVATE_KEY;
	int subtype = KEY_ANY;
	certificate_t *cert;
	private_key_t *private;
	public_key_t *public;
	char *file = NULL;
	void *cred;
	chunk_t id;
	char *arg;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 't':
				if (streq(arg, "rsa") ||
					streq(arg, "rsa-priv"))
				{
					type = CRED_PRIVATE_KEY;
					subtype = KEY_RSA;
				}
				else if (streq(arg, "ecdsa") ||
						 streq(arg, "ecdsa-priv"))
				{
					type = CRED_PRIVATE_KEY;
					subtype = KEY_ECDSA;
				}
				else if (streq(arg, "bliss") ||
						 streq(arg, "bliss-priv"))
				{
					type = CRED_PRIVATE_KEY;
					subtype = KEY_BLISS;
				}
				else if (streq(arg, "priv"))
				{
					type = CRED_PRIVATE_KEY;
					subtype = KEY_ANY;
				}
				else if (streq(arg, "pub"))
				{
					type = CRED_PUBLIC_KEY;
					subtype = KEY_ANY;
				}
				else if (streq(arg, "pkcs10"))
				{
					type = CRED_CERTIFICATE;
					subtype = CERT_PKCS10_REQUEST;
				}
				else if (streq(arg, "x509"))
				{
					type = CRED_CERTIFICATE;
					subtype = CERT_X509;
				}
				else
				{
					return command_usage( "invalid input type");
				}
				continue;
			case 'i':
				file = arg;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --keyid option");
		}
		break;
	}
	if (file)
	{
		cred = lib->creds->create(lib->creds, type, subtype,
								  BUILD_FROM_FILE, file, BUILD_END);
	}
	else
	{
		chunk_t chunk;

		set_file_mode(stdin, CERT_ASN1_DER);
		if (!chunk_from_fd(0, &chunk))
		{
			fprintf(stderr, "reading input failed: %s\n", strerror(errno));
			return 1;
		}
		cred = lib->creds->create(lib->creds, type, subtype,
								  BUILD_BLOB, chunk, BUILD_END);
		free(chunk.ptr);
	}
	if (!cred)
	{
		fprintf(stderr, "parsing input failed\n");
		return 1;
	}

	if (type == CRED_PRIVATE_KEY)
	{
		private = cred;
		if (private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &id))
		{
			printf("subjectKeyIdentifier:      %#B\n", &id);
		}
		if (private->get_fingerprint(private, KEYID_PUBKEY_INFO_SHA1, &id))
		{
			printf("subjectPublicKeyInfo hash: %#B\n", &id);
		}
		private->destroy(private);
Exemplo n.º 19
0
/**
 * Create a self signed certificate.
 */
static int self()
{
	cred_encoding_type_t form = CERT_ASN1_DER;
	key_type_t type = KEY_RSA;
	hash_algorithm_t digest = HASH_SHA1;
	certificate_t *cert = NULL;
	private_key_t *private = NULL;
	public_key_t *public = NULL;
	char *file = NULL, *dn = NULL, *hex = NULL, *error = NULL, *keyid = NULL;
	identification_t *id = NULL;
	linked_list_t *san, *ocsp, *permitted, *excluded, *policies, *mappings;
	int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
	int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
	chunk_t serial = chunk_empty;
	chunk_t encoding = chunk_empty;
	time_t lifetime = 1095;
	time_t not_before, not_after;
	x509_flag_t flags = 0;
	x509_cert_policy_t *policy = NULL;
	char *arg;

	san = linked_list_create();
	ocsp = linked_list_create();
	permitted = linked_list_create();
	excluded = linked_list_create();
	policies = linked_list_create();
	mappings = linked_list_create();

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				goto usage;
			case 't':
				if (streq(arg, "rsa"))
				{
					type = KEY_RSA;
				}
				else if (streq(arg, "ecdsa"))
				{
					type = KEY_ECDSA;
				}
				else
				{
					error = "invalid input type";
					goto usage;
				}
				continue;
			case 'g':
				digest = enum_from_name(hash_algorithm_short_names, arg);
				if (digest == -1)
				{
					error = "invalid --digest type";
					goto usage;
				}
				continue;
			case 'i':
				file = arg;
				continue;
			case 'x':
				keyid = arg;
				continue;
			case 'd':
				dn = arg;
				continue;
			case 'a':
				san->insert_last(san, identification_create_from_string(arg));
				continue;
			case 'l':
				lifetime = atoi(arg);
				if (!lifetime)
				{
					error = "invalid --lifetime value";
					goto usage;
				}
				continue;
			case 's':
				hex = arg;
				continue;
			case 'b':
				flags |= X509_CA;
				continue;
			case 'p':
				pathlen = atoi(arg);
				continue;
			case 'n':
				permitted->insert_last(permitted,
									   identification_create_from_string(arg));
				continue;
			case 'N':
				excluded->insert_last(excluded,
									  identification_create_from_string(arg));
				continue;
			case 'P':
			{
				chunk_t oid;

				oid = asn1_oid_from_string(arg);
				if (!oid.len)
				{
					error = "--cert-policy OID invalid";
					goto usage;
				}
				INIT(policy,
					.oid = oid,
				);
				policies->insert_last(policies, policy);
				continue;
			}
			case 'C':
				if (!policy)
				{
					error = "--cps-uri must follow a --cert-policy";
					goto usage;
				}
				policy->cps_uri = arg;
				continue;
			case 'U':
				if (!policy)
				{
					error = "--user-notice must follow a --cert-policy";
					goto usage;
				}
				policy->unotice_text = arg;
				continue;
			case 'M':
			{
				char *pos = strchr(arg, ':');
				x509_policy_mapping_t *mapping;
				chunk_t subject_oid, issuer_oid;

				if (pos)
				{
					*pos++ = '\0';
					issuer_oid = asn1_oid_from_string(arg);
					subject_oid = asn1_oid_from_string(pos);
				}
				if (!pos || !issuer_oid.len || !subject_oid.len)
				{
					error = "--policy-map OIDs invalid";
					goto usage;
				}
				INIT(mapping,
					.issuer = issuer_oid,
					.subject = subject_oid,
				);
				mappings->insert_last(mappings, mapping);
				continue;
			}
			case 'E':
				require_explicit = atoi(arg);
				continue;
			case 'H':
				inhibit_mapping = atoi(arg);
				continue;
			case 'A':
				inhibit_any = atoi(arg);
				continue;
			case 'e':
				if (streq(arg, "serverAuth"))
				{
					flags |= X509_SERVER_AUTH;
				}
				else if (streq(arg, "clientAuth"))
				{
					flags |= X509_CLIENT_AUTH;
				}
				else if (streq(arg, "ikeIntermediate"))
				{
					flags |= X509_IKE_INTERMEDIATE;
				}
				else if (streq(arg, "crlSign"))
				{
					flags |= X509_CRL_SIGN;
				}
				else if (streq(arg, "ocspSigning"))
				{
					flags |= X509_OCSP_SIGNER;
				}
				continue;
			case 'f':
				if (!get_form(arg, &form, CRED_CERTIFICATE))
				{
					error = "invalid output format";
					goto usage;
				}
				continue;
			case 'o':
				ocsp->insert_last(ocsp, arg);
				continue;
			case EOF:
				break;
			default:
				error = "invalid --self option";
				goto usage;
		}
		break;
	}

	if (!dn)
	{
		error = "--dn is required";
		goto usage;
	}
	id = identification_create_from_string(dn);
	if (id->get_type(id) != ID_DER_ASN1_DN)
	{
		error = "supplied --dn is not a distinguished name";
		goto end;
	}
	if (file)
	{
		private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
									 BUILD_FROM_FILE, file, BUILD_END);
	}
Exemplo n.º 20
0
/**
 * Verify a certificate signature
 */
static int verify()
{
	certificate_t *cert, *ca;
	char *file = NULL, *cafile = NULL;
	bool good = FALSE;
	char *arg;

	while (TRUE)
	{
		switch (command_getopt(&arg))
		{
			case 'h':
				return command_usage(NULL);
			case 'i':
				file = arg;
				continue;
			case 'c':
				cafile = arg;
				continue;
			case EOF:
				break;
			default:
				return command_usage("invalid --verify option");
		}
		break;
	}

	if (file)
	{
		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								  BUILD_FROM_FILE, file, BUILD_END);
	}
	else
	{
		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								  BUILD_FROM_FD, 0, BUILD_END);
	}
	if (!cert)
	{
		fprintf(stderr, "parsing certificate failed\n");
		return 1;
	}
	if (cafile)
	{
		ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
								BUILD_FROM_FILE, cafile, BUILD_END);
		if (!ca)
		{
			fprintf(stderr, "parsing CA certificate failed\n");
			return 1;
		}
	}
	else
	{
		ca = cert;
	}
	if (cert->issued_by(cert, ca, NULL))
	{
		if (cert->get_validity(cert, NULL, NULL, NULL))
		{
			if (cafile)
			{
				if (ca->get_validity(ca, NULL, NULL, NULL))
				{
					printf("signature good, certificates valid\n");
					good = TRUE;
				}
				else
				{
					printf("signature good, CA certificates not valid now\n");
				}
			}
			else
			{
				printf("signature good, certificate valid\n");
				good = TRUE;
			}
		}
		else
		{
			printf("certificate not valid now\n");
		}
	}
	else
	{
		printf("signature invalid\n");
	}
	if (cafile)
	{
		ca->destroy(ca);
	}
	cert->destroy(cert);

	return good ? 0 : 2;
}