Exemplo n.º 1
0
/**
 * Load certificate distribution points
 */
static void load_cdps(settings_t *settings)
{
	enumerator_t *enumerator;
	identification_t *id;
	char *ca, *uri, *section;
	certificate_type_t type;
	x509_t *x509;

	enumerator = settings->create_section_enumerator(settings, "cdps");
	while (enumerator->enumerate(enumerator, &section))
	{
		if (strncaseeq(section, "crl", strlen("crl")))
		{
			type = CERT_X509_CRL;
		}
		else if (strncaseeq(section, "ocsp", strlen("ocsp")))
		{
			type = CERT_X509_OCSP_RESPONSE;
		}
		else
		{
			fprintf(stderr, "unknown cdp type '%s', ignored\n", section);
			continue;
		}

		uri = settings->get_str(settings, "cdps.%s.uri", NULL, section);
		ca = settings->get_str(settings, "cdps.%s.ca", NULL, section);
		if (!ca || !uri)
		{
			fprintf(stderr, "cdp '%s' misses ca/uri, ignored\n", section);
			continue;
		}
		x509 = lib->creds->create(lib->creds, CRED_CERTIFICATE,
							CERT_X509, BUILD_FROM_FILE, ca, BUILD_END);
		if (!x509)
		{
			fprintf(stderr, "loading cdp '%s' ca failed, ignored\n", section);
			continue;
		}
		id = identification_create_from_encoding(ID_KEY_ID,
									x509->get_subjectKeyIdentifier(x509));
		conftest->creds->add_cdp(conftest->creds, type, id, uri);
		DESTROY_IF((certificate_t*)x509);
		id->destroy(id);
	}
	enumerator->destroy(enumerator);
}
Exemplo n.º 2
0
/**
 * Check, as client, if we have a client certificate with private key
 */
static identification_t *find_client_id()
{
    identification_t *client = NULL, *keyid;
    enumerator_t *enumerator;
    certificate_t *cert;
    public_key_t *pubkey;
    private_key_t *privkey;
    chunk_t chunk;

    enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
                 CERT_X509, KEY_ANY, NULL, FALSE);
    while (enumerator->enumerate(enumerator, &cert))
    {
        pubkey = cert->get_public_key(cert);
        if (pubkey)
        {
            if (pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &chunk))
            {
                keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
                privkey = lib->credmgr->get_private(lib->credmgr,
                                                    pubkey->get_type(pubkey), keyid, NULL);
                keyid->destroy(keyid);
                if (privkey)
                {
                    client = cert->get_subject(cert);
                    client = client->clone(client);
                    privkey->destroy(privkey);
                }
            }
            pubkey->destroy(pubkey);
        }
        if (client)
        {
            break;
        }
    }
    enumerator->destroy(enumerator);

    return client;
}
Exemplo n.º 3
0
/**
 * ipsec pool --statusattr - show all attribute entries
 */
void status_attr(bool hexout)
{
	configuration_attribute_type_t type;
	value_type_t value_type;
	chunk_t value, addr_chunk, mask_chunk, identity_chunk;
	identification_t *identity;
	enumerator_t *enumerator;
	host_t *addr, *mask;
	char type_name[30];
	bool first = TRUE;
	int i, identity_type;
	char *pool_name;

	/* enumerate over all attributes */
	enumerator = db->query(db,
					"SELECT attributes.type, attribute_pools.name, "
					"identities.type, identities.data, attributes.value "
					"FROM attributes "
					"LEFT OUTER JOIN identities "
					"ON attributes.identity = identities.id "
					"LEFT OUTER JOIN attribute_pools "
					"ON attributes.pool = attribute_pools.id "
					"ORDER BY attributes.type, attribute_pools.name, "
					"identities.type, identities.data, attributes.value",
					DB_INT, DB_TEXT, DB_INT, DB_BLOB, DB_BLOB);
	if (enumerator)
	{
		while (enumerator->enumerate(enumerator, &type,&pool_name,
									 &identity_type, &identity_chunk, &value))
		{
			if (first)
			{
				printf(" type  description           pool       "
					   " identity              value\n");
				first = FALSE;
			}
			snprintf(type_name, sizeof(type_name), "%N",
					 configuration_attribute_type_names, type);
			if (type_name[0] == '(')
			{
				type_name[0] = '\0';
			}
			printf("%5d  %-20s ",type, type_name);

			printf(" %-10s ", (pool_name ? pool_name : ""));

			if (identity_type)
			{
				identity = identification_create_from_encoding(identity_type, identity_chunk);
				printf(" %-20.20Y ", identity);
				identity->destroy(identity);
			}
			else
			{
				printf("                      ");
			}

			value_type = VALUE_HEX;
			if (!hexout)
			{
				for (i = 0; i < countof(attr_info); i++)
				{
					if (type == attr_info[i].type)
					{
						value_type = attr_info[i].value_type;
						break;
					}
				}
			}
			switch (value_type)
			{
				case VALUE_ADDR:
					addr = host_create_from_chunk(AF_UNSPEC, value, 0);
					if (addr)
					{
						printf(" %H\n", addr);
						addr->destroy(addr);
					}
					else
					{
						/* value cannot be represented as an IP address */
						printf(" %#B\n", &value);
					}
					break;
				case VALUE_SUBNET:
					if (value.len % UNITY_NETWORK_LEN == 0)
					{
						for (i = 0; i < value.len / UNITY_NETWORK_LEN; i++)
						{
							addr_chunk = chunk_create(value.ptr + i*UNITY_NETWORK_LEN, 4);
							addr = host_create_from_chunk(AF_INET, addr_chunk, 0);
							mask_chunk = chunk_create(addr_chunk.ptr + 4, 4);
							mask = host_create_from_chunk(AF_INET, mask_chunk, 0);
							printf("%s%H/%H", (i > 0) ? "," : " ", addr, mask);
							addr->destroy(addr);
							mask->destroy(mask);
						}
						printf("\n");
					}
					else
					{
						/* value cannot be represented as a list of subnets */
						printf(" %#B\n", &value);
					}
					break;
				case VALUE_STRING:
					printf("\"%.*s\"\n", (int)value.len, value.ptr);
					break;
				case VALUE_HEX:
				default:
					printf(" %#B\n", &value);
			}
		}
		enumerator->destroy(enumerator);
	}
}
Exemplo n.º 4
0
/**
 * ipsec pool --leases - show lease information of a pool
 */
static void leases(char *filter, bool utc)
{
	enumerator_t *query;
	array_t *to_free = NULL;
	chunk_t address_chunk, identity_chunk;
	int identity_type;
	char *name;
	u_int db_acquired, db_released, db_timeout;
	time_t acquired, released, timeout;
	host_t *address;
	identification_t *identity;
	bool found = FALSE;

	query = create_lease_query(filter, &to_free);
	if (!query)
	{
		fprintf(stderr, "querying leases failed.\n");
		exit(EXIT_FAILURE);
	}
	while (query->enumerate(query, &name, &address_chunk, &identity_type,
							&identity_chunk, &db_acquired, &db_released, &db_timeout))
	{
		if (!found)
		{
			int len = utc ? 25 : 21;

			found = TRUE;
			printf("%-8s %-15s %-7s  %-*s %-*s %s\n",
				   "name", "address", "status", len, "start", len, "end", "identity");
		}
		address = host_create_from_chunk(AF_UNSPEC, address_chunk, 0);
		identity = identification_create_from_encoding(identity_type, identity_chunk);

		/* u_int is not always equal to time_t */
		acquired = (time_t)db_acquired;
		released = (time_t)db_released;
		timeout  = (time_t)db_timeout;

		printf("%-8s %-15H ", name, address);
		if (released == 0)
		{
			printf("%-7s ", "online");
		}
		else if (timeout == 0)
		{
			printf("%-7s ", "static");
		}
		else if (released >= time(NULL) - timeout)
		{
			printf("%-7s ", "valid");
		}
		else
		{
			printf("%-7s ", "expired");
		}

		printf(" %T  ", &acquired, utc);
		if (released)
		{
			printf("%T  ", &released, utc);
		}
		else
		{
			printf("                      ");
			if (utc)
			{
				printf("    ");
			}
		}
		printf("%Y\n", identity);
		DESTROY_IF(address);
		identity->destroy(identity);
	}
	query->destroy(query);
	if (to_free)
	{
		array_destroy_function(to_free, (void*)free, NULL);
	}
	if (!found)
	{
		fprintf(stderr, "no matching leases found.\n");
		exit(EXIT_FAILURE);
	}
}
Exemplo n.º 5
0
/**
 * Parse a PKCS#7 envelopedData object
 */
bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
							   chunk_t serialNumber,
							   private_key_t *key)
{
	asn1_parser_t *parser;
	chunk_t object;
	chunk_t iv                = chunk_empty;
	chunk_t symmetric_key     = chunk_empty;
	chunk_t encrypted_content = chunk_empty;

	crypter_t *crypter = NULL;

	int enc_alg         = OID_UNKNOWN;
	int content_enc_alg = OID_UNKNOWN;
	int version;
	int objectID;
	bool success = FALSE;

	contentInfo_t cInfo = empty_contentInfo;
	*data = chunk_empty;

	if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
	{
		goto failed;
	}
	if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
	{
		DBG1(DBG_LIB, "pkcs7 content type is not envelopedData");
		goto failed;
	}

	parser = asn1_parser_create(envelopedDataObjects, cInfo.content);
	parser->set_top_level(parser, 2);

	while (parser->iterate(parser, &objectID, &object))
	{
		u_int level = parser->get_level(parser);

		switch (objectID)
		{
		case PKCS7_ENVELOPED_VERSION:
			version = object.len ? (int)*object.ptr : 0;
			DBG2(DBG_LIB, "  v%d", version);
			if (version != 0)
			{
				DBG1(DBG_LIB, "envelopedData version is not 0");
				goto end;
			}
			break;
		case PKCS7_RECIPIENT_INFO_VERSION:
			version = object.len ? (int)*object.ptr : 0;
			DBG2(DBG_LIB, "  v%d", version);
			if (version != 0)
			{
				DBG1(DBG_LIB, "recipient info version is not 0");
				goto end;
			}
			break;
		case PKCS7_ISSUER:
			{
				identification_t *issuer = identification_create_from_encoding(
													ID_DER_ASN1_DN, object);
				DBG2(DBG_LIB, "  \"%Y\"", issuer);
				issuer->destroy(issuer);
				break;
			}
		case PKCS7_SERIAL_NUMBER:
			if (!chunk_equals(serialNumber, object))
			{
				DBG1(DBG_LIB, "serial numbers do not match");
				goto end;
			}
			break;
		case PKCS7_ENCRYPTION_ALG:
			enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
			if (enc_alg != OID_RSA_ENCRYPTION)
			{
				DBG1(DBG_LIB, "only rsa encryption supported");
				goto end;
			}
			break;
		case PKCS7_ENCRYPTED_KEY:
			if (!key->decrypt(key, ENCRYPT_RSA_PKCS1, object, &symmetric_key))
			{
				DBG1(DBG_LIB, "symmetric key could not be decrypted with rsa");
				goto end;
			}
			DBG4(DBG_LIB, "symmetric key %B", &symmetric_key);
			break;
		case PKCS7_CONTENT_TYPE:
			if (asn1_known_oid(object) != OID_PKCS7_DATA)
			{
				 DBG1(DBG_LIB, "encrypted content not of type pkcs7 data");
				 goto end;
			}
			break;
		case PKCS7_CONTENT_ENC_ALGORITHM:
			content_enc_alg = asn1_parse_algorithmIdentifier(object, level, &iv);

			if (content_enc_alg == OID_UNKNOWN)
			{
				DBG1(DBG_LIB, "unknown content encryption algorithm");
				goto end;
			}
			if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
			{
				DBG1(DBG_LIB, "IV could not be parsed");
				goto end;
			}
			break;
		case PKCS7_ENCRYPTED_CONTENT:
			encrypted_content = object;
			break;
		}
	}
	success = parser->success(parser);

end:
	parser->destroy(parser);
	if (!success)
	{
		goto failed;
	}
	success = FALSE;

	/* decrypt the content */
	{
		encryption_algorithm_t alg;
		size_t key_size;
		crypter_t *crypter;

		alg = encryption_algorithm_from_oid(content_enc_alg, &key_size);
		if (alg == ENCR_UNDEFINED)
		{
			DBG1(DBG_LIB, "unsupported content encryption algorithm");
			goto failed;
		}
		crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
		if (crypter == NULL)
		{
			DBG1(DBG_LIB, "crypter %N not available", encryption_algorithm_names, alg);
			goto failed;
		}
		if (symmetric_key.len != crypter->get_key_size(crypter))
		{
			DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
			goto failed;
		}
		if (iv.len != crypter->get_iv_size(crypter))
		{
			DBG1(DBG_LIB, "IV length %d is wrong", iv.len);
			goto failed;
		}
		crypter->set_key(crypter, symmetric_key);
		crypter->decrypt(crypter, encrypted_content, iv, data);
		DBG4(DBG_LIB, "decrypted content with padding: %B", data);
	}

	/* remove the padding */
	{
		u_char *pos = data->ptr + data->len - 1;
		u_char pattern = *pos;
		size_t padding = pattern;

		if (padding > data->len)
		{
			DBG1(DBG_LIB, "padding greater than data length");
			goto failed;
		}
		data->len -= padding;

		while (padding-- > 0)
		{
			if (*pos-- != pattern)
			{
				DBG1(DBG_LIB, "wrong padding pattern");
				goto failed;
			}
		}
	}
	success = TRUE;

failed:
	DESTROY_IF(crypter);
	chunk_clear(&symmetric_key);
	if (!success)
	{
		free(data->ptr);
	}
	return success;
}
Exemplo n.º 6
0
/**
 * Parse a PKCS#7 signedData object
 */
bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
							linked_list_t *certs,
							chunk_t *attributes, certificate_t *cacert)
{
	asn1_parser_t *parser;
	chunk_t object;
	int digest_alg = OID_UNKNOWN;
	int enc_alg    = OID_UNKNOWN;
	int signerInfos = 0;
	int version;
	int objectID;
	bool success = FALSE;

	contentInfo_t cInfo = empty_contentInfo;
	chunk_t encrypted_digest = chunk_empty;

	if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
	{
		return FALSE;
	}
	if (cInfo.type != OID_PKCS7_SIGNED_DATA)
	{
		DBG1(DBG_LIB, "pkcs7 content type is not signedData");
		return FALSE;
	}

	parser = asn1_parser_create(signedDataObjects, cInfo.content);
	parser->set_top_level(parser, 2);

	while (parser->iterate(parser, &objectID, &object))
	{
		u_int level = parser->get_level(parser);

		switch (objectID)
		{
		case PKCS7_SIGNED_VERSION:
			version = object.len ? (int)*object.ptr : 0;
			DBG2(DBG_LIB, "  v%d", version);
			break;
		case PKCS7_DIGEST_ALG:
			digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
			break;
		case PKCS7_SIGNED_CONTENT_INFO:
			if (data != NULL)
			{
				pkcs7_parse_contentInfo(object, level, data);
			}
			break;
		case PKCS7_SIGNED_CERT:
			{
				certificate_t *cert;

				DBG2(DBG_LIB, "  parsing pkcs7-wrapped certificate");
				cert = lib->creds->create(lib->creds,
								  		  CRED_CERTIFICATE, CERT_X509,
								  		  BUILD_BLOB_ASN1_DER, object,
								  		  BUILD_END);
				if (cert)
				{
					certs->insert_last(certs, cert);
				}
			}
			break;
		case PKCS7_SIGNER_INFO:
			signerInfos++;
			DBG2(DBG_LIB, "  signer #%d", signerInfos);
			break;
		case PKCS7_SIGNER_INFO_VERSION:
			version = object.len ? (int)*object.ptr : 0;
			DBG2(DBG_LIB, "  v%d", version);
			break;
		case PKCS7_SIGNED_ISSUER:
			{
				identification_t *issuer = identification_create_from_encoding(
													ID_DER_ASN1_DN, object);
				DBG2(DBG_LIB, "  \"%Y\"", issuer);
				issuer->destroy(issuer);
				break;
			}
		case PKCS7_AUTH_ATTRIBUTES:
			if (attributes != NULL)
			{
				*attributes = object;
				*attributes->ptr = ASN1_SET;
			}
			break;
		case PKCS7_DIGEST_ALGORITHM:
			digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
			break;
		case PKCS7_DIGEST_ENC_ALGORITHM:
			enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
			break;
		case PKCS7_ENCRYPTED_DIGEST:
			encrypted_digest = object;
		}
	}
	success = parser->success(parser);
	parser->destroy(parser);
	if (!success)
	{
		return FALSE;
	}

	/* check the signature only if a cacert is available */
	if (cacert != NULL)
	{
		public_key_t *key;
		signature_scheme_t scheme;

		scheme = signature_scheme_from_oid(digest_alg);
		if (scheme == SIGN_UNKNOWN)
		{
			DBG1(DBG_LIB, "unsupported signature scheme");
			return FALSE;
		}
		if (signerInfos == 0)
		{
			DBG1(DBG_LIB, "no signerInfo object found");
			return FALSE;
		}
		else if (signerInfos > 1)
		{
			DBG1(DBG_LIB, "more than one signerInfo object found");
			return FALSE;
		}
		if (attributes->ptr == NULL)
		{
			DBG1(DBG_LIB, "no authenticatedAttributes object found");
			return FALSE;
		}
		if (enc_alg != OID_RSA_ENCRYPTION)
		{
			DBG1(DBG_LIB, "only RSA digest encryption supported");
			return FALSE;
		}

		/* verify the signature */
		key = cacert->get_public_key(cacert);
		if (key == NULL)
		{
			DBG1(DBG_LIB, "no public key found in CA certificate");
			return FALSE;
		}
		if (key->verify(key, scheme, *attributes, encrypted_digest))
		{
			DBG2(DBG_LIB, "signature is valid");
		}
		else
		{
			DBG1(DBG_LIB, "invalid signature");
			success = FALSE;
		}
		key->destroy(key);
	}
	return success;
}