Beispiel #1
0
/*
 * EVP_PKEY_METHOD callback decrypt
 * Implementation of GOST2001 key transport, cryptopo variation
 */
int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key,
                          size_t *key_len, const unsigned char *in,
                          size_t in_len)
{
    const unsigned char *p = in;
    EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
    GOST_KEY_TRANSPORT *gkt = NULL;
    int ret = 0;
    unsigned char wrappedKey[44];
    unsigned char sharedKey[32];
    gost_ctx ctx;
    const struct gost_cipher_info *param = NULL;
    EVP_PKEY *eph_key = NULL, *peerkey = NULL;

    if (!key) {
        *key_len = 32;
        return 1;
    }
    gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len);
    if (!gkt) {
        GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
                GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
        return -1;
    }

    /* If key transport structure contains public key, use it */
    eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
    if (eph_key) {
        if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) {
            GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
                    GOST_R_INCOMPATIBLE_PEER_KEY);
            goto err;
        }
    } else {
        /* Set control "public key from client certificate used" */
        if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL)
            <= 0) {
            GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_CTRL_CALL_FAILED);
            goto err;
        }
    }
    peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
    if (!peerkey) {
        GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_NO_PEER_KEY);
        goto err;
    }

    param = get_encryption_params(gkt->key_agreement_info->cipher);
    if (!param) {
        goto err;
    }

    gost_init(&ctx, param->sblock);
    OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8);
    memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8);
    OPENSSL_assert(gkt->key_info->encrypted_key->length == 32);
    memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32);
    OPENSSL_assert(gkt->key_info->imit->length == 4);
    memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
    VKO_compute_key(sharedKey, 32,
                    EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)),
                    EVP_PKEY_get0(priv), wrappedKey);
    if (!keyUnwrapCryptoPro(&ctx, sharedKey, wrappedKey, key)) {
        GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
                GOST_R_ERROR_COMPUTING_SHARED_KEY);
        goto err;
    }

    ret = 1;
 err:
    EVP_PKEY_free(eph_key);
    GOST_KEY_TRANSPORT_free(gkt);
    return ret;
}
Beispiel #2
0
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
{
    if (req == NULL)
        return (NULL);
    return (X509_PUBKEY_get(req->req_info.pubkey));
}
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
{
    if ((x == NULL) || (x->spkac == NULL))
        return(NULL);
    return(X509_PUBKEY_get(x->spkac->pubkey));
}
OP_STATUS CryptoSignature_impl::SetPublicKey(const UINT8* public_key, int key_length)
{
	if (!public_key || key_length <= 0)
		return OpStatus::ERR_OUT_OF_RANGE;

	// This function supports public keys in different formats, such as
	// X509_PUBKEY and EVP_PKEY-with-RSA-key-only objects.
	// It should be made more generic, simple and straightforward:
	// only EVP_PKEY objects should be supported.

	// This function tries to decode data at "public_key" pointer as X509_PUBKEY,
	// if fails - as EVP_PKEY_RSA.

	// Clear the existing key, if any.
	if (m_keyspec)
	{
		EVP_PKEY_free(m_keyspec);
		m_keyspec = NULL;
	}


	// Try hypothesis: public key is X509_PUBKEY.

	// Temporary variable as recommended by "man d2i_X509".
	const unsigned char* public_key_tmp = public_key;
	// Construct X509_PUBKEY object. We own it.
	X509_PUBKEY* pubkey = d2i_X509_PUBKEY(NULL, &public_key_tmp, key_length);
	if (pubkey)
	{
		m_keyspec = X509_PUBKEY_get(pubkey);
		// X509_PUBKEY_get allocates new EVP_PKEY, so it's safe
		// to deallocate pubkey now.
		X509_PUBKEY_free(pubkey);
	}
	ERR_clear_error();


	// Try hypothesis: public key is EVP_PKEY_RSA.

	if (m_keyspec == NULL)
	{
		switch (m_cipher_algorithm )
		{
		case CRYPTO_CIPHER_TYPE_RSA:
			// Temporary variable my have changed its value, resetting.
			public_key_tmp = public_key;
			m_keyspec = d2i_PublicKey(EVP_PKEY_RSA, NULL, &public_key_tmp, key_length);
			ERR_clear_error();
			break;

		default:
			return OpStatus::ERR_NOT_SUPPORTED;
		}
	}


	if (m_keyspec)
		return OpStatus::OK;

	return OpStatus::ERR;
}
/* EVP_PLEY_METHOD callback decrypt for
 * GOST R 34.10-94 cryptopro modification
 */
int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) {
	const unsigned char *p = in;
	GOST_KEY_TRANSPORT *gkt = NULL;
	unsigned char wrappedKey[44];
	unsigned char sharedKey[32];
	gost_ctx cctx;
	const struct gost_cipher_info *param=NULL;
	EVP_PKEY *eph_key=NULL, *peerkey=NULL;
	EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); 
	
	if (!key)
		{
		*key_len = 32;
		return 1;
		}	
	
	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
		in_len);
	if (!gkt)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
		return 0;
		}	
	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
	if (eph_key)
		{
		if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
				GOST_R_INCOMPATIBLE_PEER_KEY);
			goto err;
			}
		}
	else
		{
		/* Set control "public key from client certificate used" */
		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
				GOST_R_CTRL_CALL_FAILED);
			goto err;
			}
		}
	peerkey = EVP_PKEY_CTX_get0_peerkey(ctx);
	if (!peerkey)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
			GOST_R_NO_PEER_KEY);
		goto err;
		}

	param = get_encryption_params(gkt->key_agreement_info->cipher);
	gost_init(&cctx,param->sblock);	
	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
	TINYCLR_SSL_MEMCPY(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
	TINYCLR_SSL_MEMCPY(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
	OPENSSL_assert(gkt->key_info->imit->length==4);
	TINYCLR_SSL_MEMCPY(wrappedKey+40,gkt->key_info->imit->data,4);	
	make_cp_exchange_key(gost_get0_priv_key(priv),peerkey,sharedKey);
	if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key))
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
			GOST_R_ERROR_COMPUTING_SHARED_KEY);
		goto err;
		}	
				
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return 1;
err:
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}	
Beispiel #6
0
EVP_PKEY *original_X509_get_pubkey(X509 *x)
{
    if ((x == NULL) || (x->cert_info == NULL))
        return(NULL);
    return(X509_PUBKEY_get(x->cert_info->key));
}
Beispiel #7
0
ldns_status
ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
		ldns_tlsa_selector      selector,
		ldns_tlsa_matching_type matching_type)
{
	unsigned char* buf = NULL;
	size_t len;

	X509_PUBKEY* xpubkey;
	EVP_PKEY* epubkey;

	unsigned char* digest;

	assert(rdf != NULL);
	assert(cert != NULL);

	switch(selector) {
	case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:

		len = (size_t)i2d_X509(cert, &buf);
		break;

	case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:

#ifndef S_SPLINT_S
		xpubkey = X509_get_X509_PUBKEY(cert);
#endif
		if (! xpubkey) {
			return LDNS_STATUS_SSL_ERR;
		}
		epubkey = X509_PUBKEY_get(xpubkey);
		if (! epubkey) {
			return LDNS_STATUS_SSL_ERR;
		}
		len = (size_t)i2d_PUBKEY(epubkey, &buf);
		break;
	
	default:
		return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
	}

	switch(matching_type) {
	case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:

		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
		
		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
		break;
	
	case LDNS_TLSA_MATCHING_TYPE_SHA256:

		digest = LDNS_XMALLOC(unsigned char, SHA256_DIGEST_LENGTH);
		if (digest == NULL) {
			LDNS_FREE(buf);
			return LDNS_STATUS_MEM_ERR;
		}
		(void) ldns_sha256(buf, (unsigned int)len, digest);
		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
				digest);
		LDNS_FREE(buf);

		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
		break;

	case LDNS_TLSA_MATCHING_TYPE_SHA512:

		digest = LDNS_XMALLOC(unsigned char, SHA512_DIGEST_LENGTH);
		if (digest == NULL) {
			LDNS_FREE(buf);
			return LDNS_STATUS_MEM_ERR;
		}
		(void) ldns_sha512(buf, (unsigned int)len, digest);
		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA512_DIGEST_LENGTH,
				digest);
		LDNS_FREE(buf);

		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
		break;
	
	default:
		LDNS_FREE(buf);
		return LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE;
	}
}