/* load a coded key or certificate file with autodetection
 * of binary DER or base64 PEM ASN.1 formats and armored PGP format
 */
bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
						const char *type, chunk_t *blob, bool *pgp)
{
	err_t ugh = NULL;

	FILE *fd = fopen(filename, "r");

	pem_init_logger();

	if (fd)
	{
		int bytes;
		fseek(fd, 0, SEEK_END );
		blob->len = ftell(fd);
		rewind(fd);
		blob->ptr = malloc(blob->len);
		bytes = fread(blob->ptr, 1, blob->len, fd);
		fclose(fd);
		logger->log(logger, CONTROL, "  loading %s file '%s' (%d bytes)", type, filename, bytes);

		*pgp = FALSE;

		/* try DER format */
		if (is_asn1(*blob))
		{
			logger->log(logger, CONTROL|LEVEL1, "  file coded in DER format");
			return TRUE;
		}

		if (passphrase != NULL)
			logger->log_bytes(logger, PRIVATE, "  passphrase:", passphrase->ptr, passphrase->len);

		/* try PEM format */
		ugh = pem_to_bin(blob, passphrase, pgp);

		if (ugh == NULL)
		{
			if (*pgp)
			{
				logger->log(logger, CONTROL|LEVEL1, "  file coded in armored PGP format");
				return TRUE;
			}
			if (is_asn1(*blob))
			{
				logger->log(logger, CONTROL|LEVEL1, "  file coded in PEM format");
				return TRUE;
			}
			ugh = "file coded in unknown format, discarded";
		}

		/* a conversion error has occured */
		logger->log(logger, ERROR, "  %s", ugh);
		chunk_free(blob);
	}
	else
	{
		logger->log(logger, ERROR, "  could not open %s file '%s'", type, filename);
	}
	return FALSE;
}
/**
 * load the credential from a blob
 */
static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
							chunk_t(*cb)(void*,int), void *cb_data,
							x509_flag_t flags)
{
	void *cred = NULL;
	bool pgp = FALSE;

	blob = chunk_clone(blob);
	if (!is_asn1(blob))
	{
		if (pem_to_bin(&blob, cb, cb_data, &pgp) != SUCCESS)
		{
			chunk_clear(&blob);
			return NULL;
		}
		if (pgp && type == CRED_PRIVATE_KEY)
		{
			/* PGP encoded keys are parsed with a KEY_ANY key type, as it
			 * can contain any type of key. However, ipsec.secrets uses
			 * RSA for PGP keys, which is actually wrong. */
			subtype = KEY_ANY;
		}
	}
	/* if CERT_ANY is given, ASN1 encoded blob is handled as X509 */
	if (type == CRED_CERTIFICATE && subtype == CERT_ANY)
	{
		subtype = pgp ? CERT_GPG : CERT_X509;
	}
	cred = lib->creds->create(lib->creds, type, subtype,
							  pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob,
							  flags ? BUILD_X509_FLAG : BUILD_END,
							  flags, BUILD_END);
	chunk_clear(&blob);
	return cred;
}