Exemplo n.º 1
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 not_before, not_after, lifetime = 1095 * 24 * 60 * 60;
	char *datenb = NULL, *datena = NULL, *dateform = NULL;
	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':
				if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
				{
					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) * 24 * 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 '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;
				}
				else if (streq(arg, "msSmartcardLogon"))
				{
					flags |= X509_MS_SMARTCARD_LOGON;
				}
				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;
	}
	if (!calculate_lifetime(dateform, datenb, datena, lifetime,
							&not_before, &not_after))
	{
		error = "invalid --not-before/after datetime";
		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.º 2
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.º 3
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);