Beispiel #1
0
int ssls_register_ssl_key( DSSL_Session* sess,EVP_PKEY* pk )
{
	struct in_addr server_ip = sess->last_packet->ip_header->ip_dst;
	uint16_t server_port = ntohs(sess->last_packet->tcp_header->th_dport);
	EVP_PKEY* dup_key = ssls_dup_PrivateRSA_ENV_PKEY( pk );
	int rc = DSSL_RC_OK;

#if !defined(__APPLE__)
	/* MacOS uses OpenSSL v 0.9.7 that doesn't have EVP_PKEY_cmp */
	_ASSERT( EVP_PKEY_cmp(pk, dup_key) == 1);
#endif

	rc = DSSL_EnvSetServerInfoWithKey(sess->env, &server_ip, server_port, dup_key);
	if( rc == DSSL_RC_OK)
	{
		sess->flags |= SSF_TEST_SSL_KEY; /* set a flag to watch this key until it's proven to work */
		sess->ssl_si = DSSL_EnvFindServerInfo( sess->env, server_ip, server_port);
		_ASSERT(sess->ssl_si);
	}
	else
	{
		EVP_PKEY_free(dup_key);
		dup_key = NULL;
	}

	return rc;
}
Beispiel #2
0
int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
	{
	EVP_PKEY *xk=NULL;
	int ok=0;

	xk=X509_REQ_get_pubkey(x);
	switch (EVP_PKEY_cmp(xk, k))
		{
	case 1:
		ok=1;
		break;
	case 0:
		OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
		break;
	case -1:
		OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
		break;
	case -2:
		if (k->type == EVP_PKEY_EC)
			{
			OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
			break;
			}
		if (k->type == EVP_PKEY_DH)
			{
			/* No idea */
			OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
			break;
			}
	        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
		}

	EVP_PKEY_free(xk);
	return(ok);
	}
TEST_F(KeymasterTest, ImportKeyPair_EC_Success) {
    uint8_t* key_blob;
    size_t key_blob_length;

    ASSERT_EQ(0,
            sDevice->import_keypair(sDevice, TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1),
                    &key_blob, &key_blob_length))
            << "Should successfully import an EC key";
    UniqueKey key(&sDevice, key_blob, key_blob_length);

    uint8_t* x509_data;
    size_t x509_data_length;
    ASSERT_EQ(0,
            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
                    &x509_data, &x509_data_length))
            << "Should be able to retrieve EC public key successfully";
    UniqueBlob x509_blob(x509_data, x509_data_length);

    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
    Unique_EVP_PKEY actual(d2i_PUBKEY((EVP_PKEY**) NULL, &tmp,
            static_cast<long>(x509_blob.length())));

    ASSERT_EQ(EVP_PKEY_type(actual.get()->type), EVP_PKEY_EC)
            << "Generated key type should be of type EC";

    const unsigned char *expectedTmp = static_cast<const unsigned char*>(TEST_EC_KEY_1);
    Unique_PKCS8_PRIV_KEY_INFO expectedPkcs8(
            d2i_PKCS8_PRIV_KEY_INFO((PKCS8_PRIV_KEY_INFO**) NULL, &expectedTmp,
                    sizeof(TEST_EC_KEY_1)));

    Unique_EVP_PKEY expected(EVP_PKCS82PKEY(expectedPkcs8.get()));

    ASSERT_EQ(1, EVP_PKEY_cmp(expected.get(), actual.get()))
            << "Expected and actual keys should match";
}
Beispiel #4
0
int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
                                       const EVP_PKEY *privkey) {
  if (EVP_PKEY_is_opaque(privkey)) {
    /* We cannot check an opaque private key and have to trust that it
     * matches. */
    return 1;
  }

  int ret = 0;

  switch (EVP_PKEY_cmp(pubkey, privkey)) {
    case 1:
      ret = 1;
      break;
    case 0:
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
      break;
    case -1:
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
      break;
    case -2:
      OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
    default:
      assert(0);
      break;
  }

  return ret;
}
Beispiel #5
0
TEST(SignTest, TestLoadValidPemKeys)
{
    ScopedEVP_PKEY private_key(nullptr, EVP_PKEY_free);
    ScopedEVP_PKEY public_key(nullptr, EVP_PKEY_free);

    ScopedBIO bio_private_key_enc(BIO_new(BIO_s_mem()), BIO_free);
    ASSERT_TRUE(!!bio_private_key_enc);
    ScopedBIO bio_private_key_noenc(BIO_new(BIO_s_mem()), BIO_free);
    ASSERT_TRUE(!!bio_private_key_noenc);
    ScopedBIO bio_public_key(BIO_new(BIO_s_mem()), BIO_free);
    ASSERT_TRUE(!!bio_public_key);

    // Generate keys
    ASSERT_TRUE(generate_keys(private_key, public_key));

    // Write keys
    ASSERT_TRUE(PEM_write_bio_PrivateKey(bio_private_key_enc.get(),
                                         private_key.get(), EVP_des_ede3_cbc(),
                                         nullptr, 0, nullptr,
                                         const_cast<char *>("testing")));
    ASSERT_TRUE(PEM_write_bio_PrivateKey(bio_private_key_noenc.get(),
                                         private_key.get(), nullptr, nullptr, 0,
                                         nullptr, nullptr));
    ASSERT_TRUE(PEM_write_bio_PUBKEY(bio_public_key.get(), public_key.get()));

    // Read back the keys
    ScopedEVP_PKEY private_key_enc_read(mb::sign::load_private_key(
            bio_private_key_enc.get(), mb::sign::KEY_FORMAT_PEM, "testing"),
            EVP_PKEY_free);
    ASSERT_TRUE(!!private_key_enc_read);
    ScopedEVP_PKEY private_key_noenc_read(mb::sign::load_private_key(
            bio_private_key_noenc.get(), mb::sign::KEY_FORMAT_PEM, nullptr),
            EVP_PKEY_free);
    ASSERT_TRUE(!!private_key_noenc_read);
    ScopedEVP_PKEY public_key_read(mb::sign::load_public_key(
            bio_public_key.get(), mb::sign::KEY_FORMAT_PEM, "testing"),
            EVP_PKEY_free);
    ASSERT_TRUE(!!public_key_read);

    // Compare keys
    ASSERT_EQ(EVP_PKEY_cmp(private_key.get(), private_key_enc_read.get()), 1);
    ASSERT_EQ(EVP_PKEY_cmp(private_key.get(), private_key_noenc_read.get()), 1);
    ASSERT_EQ(EVP_PKEY_cmp(public_key.get(), public_key_read.get()), 1);
}
Beispiel #6
0
extern int match_user_openssh(EVP_PKEY *authkey, const char *login)
{
	char filename[PATH_MAX];
	char line[OPENSSH_LINE_MAX];
	struct passwd *pw;
	int found;
	FILE *file;

	pw = getpwnam(login);
	if (!pw || !pw->pw_dir)
		return -1;

	snprintf(filename, PATH_MAX, "%s/.ssh/authorized_keys", pw->pw_dir);

	file = fopen(filename, "r");
	if (!file)
		return -1;

	found = 0;
	do {
		EVP_PKEY *key = NULL;
		char *cp;
		if (!fgets(line, sizeof line, file))
			break;

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++) {
		}
		if (!*cp || *cp == '\n' || *cp == '#') {
			continue;
		}

		if (*cp >= '0' && *cp <= '9') {
			/* ssh v1 key format */
			key = ssh1_line_to_key(cp);
		} else if (strncmp("ssh-rsa", cp, 7) == 0) {
			/* ssh v2 rsa key format */
			key = ssh2_line_to_key(cp);
		} else if (strncmp("ecdsa-sha2-nistp", cp, 16) == 0) {
			/* ssh nistp256/384/521 key */
			key = ssh_nistp_line_to_key(cp);
		}
		if (key == NULL)
			continue;

		if (1 == EVP_PKEY_cmp(authkey, key)) {
			found = 1;
		}
		EVP_PKEY_free(key);
	} while (found == 0);

	fclose(file);

	return found;
}
static int verify_pubkey(X509* cert, const char *key, size_t key_size)
{
    EVP_PKEY* cert_pubkey = NULL;
    EVP_PKEY* orig_pubkey = NULL;
    BIO* bio = NULL;
    int ret = 0;

    if (!key || key_size == 0)
        return 0;

    if (!cert) {
        SPICE_DEBUG("warning: no cert!");
        return 0;
    }

    cert_pubkey = X509_get_pubkey(cert);
    if (!cert_pubkey) {
        SPICE_DEBUG("warning: reading public key from certificate failed");
        goto finish;
    }

    bio = BIO_new_mem_buf((void*)key, key_size);
    if (!bio) {
        SPICE_DEBUG("creating BIO failed");
        goto finish;
    }

    orig_pubkey = d2i_PUBKEY_bio(bio, NULL);
    if (!orig_pubkey) {
        SPICE_DEBUG("reading pubkey from bio failed");
        goto finish;
    }

    ret = EVP_PKEY_cmp(orig_pubkey, cert_pubkey);

    if (ret == 1)
        SPICE_DEBUG("public keys match");
    else if (ret == 0)
        SPICE_DEBUG("public keys mismatch");
    else
        SPICE_DEBUG("public keys types mismatch");

finish:
    if (bio)
        BIO_free(bio);

    if (orig_pubkey)
        EVP_PKEY_free(orig_pubkey);

    if (cert_pubkey)
        EVP_PKEY_free(cert_pubkey);

    return ret;
}
Beispiel #8
0
bool pki_key::compare(pki_base *ref)
{
	pki_key *kref = (pki_key *)ref;

	if (kref->getKeyType() != getKeyType())
		return false;
	if (!kref || !kref->key || !key)
		return false;

	int r = EVP_PKEY_cmp(key, kref->key);
	pki_openssl_error();
	return r == 1;
}
Beispiel #9
0
EP_STAT
ep_crypto_key_compat(const EP_CRYPTO_KEY *pubkey, const EP_CRYPTO_KEY *seckey)
{
	int istat = EVP_PKEY_cmp(pubkey, seckey);
	int icheck;

	// setting this param to false is mostly for debugging
	if (ep_adm_getboolparam("libep.crypto.key.compat.strict", true))
		icheck = 1;	// check to see that key halves match
	else
		icheck = 0;	// just check to see if they are the same type
	if (istat >= icheck)
		return EP_STAT_OK;
	return EP_STAT_CRYPTO_KEYCOMPAT;
}
Beispiel #10
0
int ssls_register_ssl_key( DSSL_Session* sess,EVP_PKEY* pk )
{
	struct ip_addr server_ip;
	uint16_t server_port = ntohs(sess->last_packet->tcp_header->th_dport);
	int rc = DSSL_RC_OK;
	int bAddToCache = 1;

	GET_IP_DST_ST(sess->last_packet->ip_header, &server_ip);
	/* check if need to add the server to the cache */
	if( sess->env->flags & DSSL_ENV_FORCE_TRY_SSL_KEYS )
	{
		/* only dup the key and add if the server is not already in the cache */
		bAddToCache = (DSSL_EnvFindServerInfo(sess->env, &server_ip, server_port) == NULL);
	}

	if( bAddToCache )
	{
		EVP_PKEY* dup_key = ssls_dup_PrivateRSA_ENV_PKEY( pk );
	#if !defined(__APPLE__)
		/* MacOS uses OpenSSL v 0.9.7 that doesn't have EVP_PKEY_cmp */
		_ASSERT( EVP_PKEY_cmp(pk, dup_key) == 1);
	#endif

		rc = DSSL_EnvSetServerInfoWithKey(sess->env, &server_ip, server_port, dup_key);
		dup_key = NULL; /*DSSL_EnvSetServerInfoWithKey is now managing dup_key data */
	}

	if(rc == DSSL_RC_OK)
	{
		if(sess->env->flags & DSSL_ENV_FORCE_TRY_SSL_KEYS)
		{
			/* don't use the cached value if "force" flag is set 
				because it may be a wrong key due to load balancer
				(multiple SSL servers at a single IP:port) */
			sess->ssl_pkey = pk;
		}
		else
		{
			 /* set a flag to watch this key until it's proven to work */
			sess->flags |= SSF_TEST_SSL_KEY;
			/* query the cached server info back and store in the session */
			sess->ssl_si = DSSL_EnvFindServerInfo( sess->env, &server_ip, server_port);
			_ASSERT(sess->ssl_si);
		}
	}

	return rc;
}
Beispiel #11
0
static isc_boolean_t
opensslgost_compare(const dst_key_t *key1, const dst_key_t *key2) {
	EVP_PKEY *pkey1, *pkey2;

	pkey1 = key1->keydata.pkey;
	pkey2 = key2->keydata.pkey;

	if (pkey1 == NULL && pkey2 == NULL)
		return (ISC_TRUE);
	else if (pkey1 == NULL || pkey2 == NULL)
		return (ISC_FALSE);

	if (EVP_PKEY_cmp(pkey1, pkey2) != 1)
		return (ISC_FALSE);
	return (ISC_TRUE);
}
Beispiel #12
0
int CPK_PUBLIC_PARAMS_validate_private_key(CPK_PUBLIC_PARAMS *params,
	const char *id, const EVP_PKEY *priv_key)
{
	int ret = -3;
	EVP_PKEY *pub_key = NULL;
	
	if (!(pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id))) {
		CPKerr(CPK_F_CPK_PUBLIC_PARAMS_VALIDATE_PRIVATE_KEY,
			ERR_R_EVP_LIB);
		goto err;
	}
	ret = EVP_PKEY_cmp(pub_key, priv_key);
err:
	if (pub_key) EVP_PKEY_free(pub_key);
	return ret;
}
Beispiel #13
0
int abac_id_privkey_from_chunk(abac_id_t *id, abac_chunk_t chunk) {
    assert(id != NULL);

    EVP_PKEY *key=abac_load_privkey_from_chunk(chunk.ptr, chunk.len);
    if (key == NULL) return ABAC_FAILURE;

/* needs to make sure that the key matches up with the id */
    /* extract the pub key from the id */
    EVP_PKEY *pubkey=extract_pubkey_from_cert(id->cert);
    /* cmp will just compare the pub key part of the key to see
       if they are the same */
    if(!EVP_PKEY_cmp(pubkey, key)) {
        fprintf(stderr,"wrong private key for the cert!!\n");
        return ABAC_FAILURE;
    }
    id->key = key;
    return ABAC_SUCCESS;
}
static isc_boolean_t
opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
	isc_boolean_t ret;
	int status;
	EVP_PKEY *pkey1 = key1->keydata.pkey;
	EVP_PKEY *pkey2 = key2->keydata.pkey;
	EC_KEY *eckey1 = NULL;
	EC_KEY *eckey2 = NULL;
	const BIGNUM *priv1, *priv2;

	if (pkey1 == NULL && pkey2 == NULL)
		return (ISC_TRUE);
	else if (pkey1 == NULL || pkey2 == NULL)
		return (ISC_FALSE);

	eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
	eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
	if (eckey1 == NULL && eckey2 == NULL) {
		DST_RET (ISC_TRUE);
	} else if (eckey1 == NULL || eckey2 == NULL)
		DST_RET (ISC_FALSE);

	status = EVP_PKEY_cmp(pkey1, pkey2);
	if (status != 1)
		DST_RET (ISC_FALSE);

	priv1 = EC_KEY_get0_private_key(eckey1);
	priv2 = EC_KEY_get0_private_key(eckey2);
	if (priv1 != NULL || priv2 != NULL) {
		if (priv1 == NULL || priv2 == NULL)
			DST_RET (ISC_FALSE);
		if (BN_cmp(priv1, priv2) != 0)
			DST_RET (ISC_FALSE);
	}
	ret = ISC_TRUE;

 err:
	if (eckey1 != NULL)
		EC_KEY_free(eckey1);
	if (eckey2 != NULL)
		EC_KEY_free(eckey2);
	return (ret);
}
Beispiel #15
0
int
X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
{
	EVP_PKEY *xk = NULL;
	int ok = 0;

	xk = X509_REQ_get_pubkey(x);
	switch (EVP_PKEY_cmp(xk, k)) {
	case 1:
		ok = 1;
		break;
	case 0:
		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
		    X509_R_KEY_VALUES_MISMATCH);
		break;
	case -1:
		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
		    X509_R_KEY_TYPE_MISMATCH);
		break;
	case -2:
#ifndef OPENSSL_NO_EC
		if (k->type == EVP_PKEY_EC) {
			X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
			    ERR_R_EC_LIB);
			break;
		}
#endif
#ifndef OPENSSL_NO_DH
		if (k->type == EVP_PKEY_DH) {
			/* No idea */
			X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
			    X509_R_CANT_CHECK_DH_KEY);
			break;
		}
#endif
		X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
		    X509_R_UNKNOWN_KEY_TYPE);
	}

	EVP_PKEY_free(xk);
	return (ok);
}
Beispiel #16
0
/**
 * @retval 1 equal
 * @retval 0 not equal
 * @retval -1 error
 */
static int CompareCertToRSA(X509 *cert, RSA *rsa_key)
{
    int ret;
    int retval = -1;                                            /* ERROR */

    EVP_PKEY *cert_pkey = X509_get_pubkey(cert);
    if (cert_pkey == NULL)
    {
        Log(LOG_LEVEL_ERR, "X509_get_pubkey: %s",
            TLSErrorString(ERR_get_error()));
        goto ret1;
    }
    if (EVP_PKEY_type(cert_pkey->type) != EVP_PKEY_RSA)
    {
        Log(LOG_LEVEL_ERR,
            "Received key of unknown type, only RSA currently supported!");
        goto ret2;
    }

    RSA *cert_rsa_key = EVP_PKEY_get1_RSA(cert_pkey);
    if (cert_rsa_key == NULL)
    {
        Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_get1_RSA failed!");
        goto ret2;
    }

    EVP_PKEY *rsa_pkey = EVP_PKEY_new();
    if (rsa_pkey == NULL)
    {
        Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_new allocation failed!");
        goto ret3;
    }

    ret = EVP_PKEY_set1_RSA(rsa_pkey, rsa_key);
    if (ret == 0)
    {
        Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_set1_RSA failed!");
        goto ret4;
    }

    ret = EVP_PKEY_cmp(cert_pkey, rsa_pkey);
    if (ret == 1)
    {
        Log(LOG_LEVEL_DEBUG,
            "Public key to certificate compare equal");
        retval = 1;                                             /* EQUAL */
    }
    else if (ret == 0 || ret == -1)
    {
        Log(LOG_LEVEL_DEBUG,
            "Public key to certificate compare different");
        retval = 0;                                            /* NOT EQUAL */
    }
    else
    {
        Log(LOG_LEVEL_ERR, "OpenSSL EVP_PKEY_cmp: %d %s",
            ret, TLSErrorString(ERR_get_error()));
    }

  ret4:
    EVP_PKEY_free(rsa_pkey);
  ret3:
    RSA_free(cert_rsa_key);
  ret2:
    EVP_PKEY_free(cert_pkey);

  ret1:
    return retval;
}
Beispiel #17
0
Datei: ctx.c Projekt: bupt007/deo
ctx *
ctx_init(const char *tls, const char *enc, const char *dec)
{
    const int ops = SSL_OP_NO_COMPRESSION | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
    AUTO(EVP_PKEY, prv);
    AUTO(FILE, file);
    AUTO(ctx, ctx);

    if (tls == NULL || enc == NULL || dec == NULL)
        return NULL;

    ctx = OPENSSL_malloc(sizeof(*ctx));
    if (ctx == NULL)
        return NULL;
    memset(ctx, 0, sizeof(*ctx));

    ctx->ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx->ctx == NULL)
        return NULL;

    if (SSL_CTX_set_options(ctx->ctx, ops) <= 0)
        return NULL;

    if (SSL_CTX_use_certificate_chain_file(ctx->ctx, tls) <= 0)
        return NULL;

    prv = load_prv(tls);
    if (prv == NULL)
        return NULL;

    if (SSL_CTX_use_PrivateKey(ctx->ctx, prv) <= 0)
        return NULL;

    file = fopen(enc, "r");
    if (file == NULL)
        return NULL;

    ctx->crt = sk_X509_new_null();
    if (ctx->crt == NULL)
        return NULL;

    if (!deo_load(file, ctx->crt))
        return NULL;

    ctx->dec = load_decryption_certs_keys(dec);
    if (ctx->dec == NULL)
        return NULL;

    /* Check to ensure that the TLS connection key is not also listed
     * in the decryption keys. This prevents an attack where, upon
     * misconfiguration, this service could be used to decrypt its own
     * traffic. */
    for (int i = 0; i < sk_X509_INFO_num(ctx->dec); i++) {
        X509_INFO *info = sk_X509_INFO_value(ctx->dec, i);

        if (info->x_pkey == NULL)
            continue;

        if (EVP_PKEY_cmp(prv, info->x_pkey->dec_pkey) == 1) {
            fprintf(stderr, "TLS private key is exposed!\n");
            return NULL;
        }
    }

    return STEAL(ctx);
}
Beispiel #18
0
int
ca_validate_pubkey(struct iked *env, struct iked_static_id *id,
    void *data, size_t len)
{
	BIO		*rawcert = NULL;
	RSA		*peerrsa = NULL, *localrsa = NULL;
	EVP_PKEY	*peerkey = NULL, *localkey = NULL;
	int		 ret = -1;
	FILE		*fp = NULL;
	char		 idstr[IKED_ID_SIZE];
	char		 file[PATH_MAX];
	struct iked_id	 idp;

	if (len == 0 && data == NULL)
		return (-1);

	switch (id->id_type) {
	case IKEV2_ID_IPV4:
	case IKEV2_ID_FQDN:
	case IKEV2_ID_UFQDN:
	case IKEV2_ID_IPV6:
		break;
	default:
		/* Some types like ASN1_DN will not be mapped to file names */
		return (-1);
	}

	bzero(&idp, sizeof(idp));
	if ((idp.id_buf = ibuf_new(id->id_data, id->id_length)) == NULL)
		goto done;

	idp.id_type = id->id_type;
	idp.id_offset = id->id_offset;
	if (ikev2_print_id(&idp, idstr, sizeof(idstr)) == -1)
		goto done;

	if (len == 0) {
		/* Data is already an public key */
		peerkey = (EVP_PKEY *)data;
	} else {
		if ((rawcert = BIO_new_mem_buf(data, len)) == NULL)
			goto done;

		if ((peerrsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL)
			goto sslerr;
		if ((peerkey = EVP_PKEY_new()) == NULL)
			goto sslerr;
		if (!EVP_PKEY_set1_RSA(peerkey, peerrsa))
			goto sslerr;
	}

	lc_string(idstr);
	if (strlcpy(file, IKED_PUBKEY_DIR, sizeof(file)) >= sizeof(file) ||
	    strlcat(file, idstr, sizeof(file)) >= sizeof(file))
		goto done;

	if ((fp = fopen(file, "r")) == NULL)
		goto done;
	localkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
	if (localkey == NULL) {
		/* reading PKCS #8 failed, try PEM */
		rewind(fp);
		localrsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
		fclose(fp);
		if (localrsa == NULL)
			goto sslerr;
		if ((localkey = EVP_PKEY_new()) == NULL)
			goto sslerr;
		if (!EVP_PKEY_set1_RSA(localkey, localrsa))
			goto sslerr;
	} else {
		fclose(fp);
	}
	if (localkey == NULL)
		goto sslerr;

	if (!EVP_PKEY_cmp(peerkey, localkey))
		goto done;

	log_debug("%s: valid public key in file %s", __func__, file);

	ret = 0;
 sslerr:
	if (ret != 0)
		ca_sslerror(__func__);
 done:
	ibuf_release(idp.id_buf);
	if (peerkey != NULL)
		EVP_PKEY_free(peerkey);
	if (localkey != NULL)
		EVP_PKEY_free(localkey);
	if (peerrsa != NULL)
		RSA_free(peerrsa);
	if (localrsa != NULL)
		RSA_free(localrsa);
	if (rawcert != NULL)
		BIO_free(rawcert);

	return (ret);
}