Пример #1
0
int
sldns_key_EVP_load_gost_id(void)
{
	static int gost_id = 0;
	const EVP_PKEY_ASN1_METHOD* meth;
	ENGINE* e;

	if(gost_id) return gost_id;

	/* see if configuration loaded gost implementation from other engine*/
	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
	if(meth) {
		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
		return gost_id;
	}

	/* see if engine can be loaded already */
	e = ENGINE_by_id("gost");
	if(!e) {
		/* load it ourself, in case statically linked */
		ENGINE_load_builtin_engines();
		ENGINE_load_dynamic();
		e = ENGINE_by_id("gost");
	}
	if(!e) {
		/* no gost engine in openssl */
		return 0;
	}
	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
		ENGINE_finish(e);
		ENGINE_free(e);
		return 0;
	}

	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
	if(!meth) {
		/* algo not found */
		ENGINE_finish(e);
		ENGINE_free(e);
		return 0;
	}
        /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
         * on some platforms this frees up the meth and unloads gost stuff */
        sldns_gost_engine = e;
	
	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
	return gost_id;
} 
int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
			const char *algname, ENGINE *e, int do_param)
	{
	EVP_PKEY_CTX *ctx = NULL;
	const EVP_PKEY_ASN1_METHOD *ameth;
	ENGINE *tmpeng = NULL;
	int pkey_id;

	if (*pctx)
		{
		BIO_puts(err, "Algorithm already set!\n");
		return 0;
		}

	ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);

#ifndef OPENSSL_NO_ENGINE
	if (!ameth && e)
		ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
#endif

	if (!ameth)
		{
		BIO_printf(bio_err, "Algorithm %s not found\n", algname);
		return 0;
		}

	ERR_clear_error();

	EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
#ifndef OPENSSL_NO_ENGINE
	if (tmpeng)
		ENGINE_finish(tmpeng);
#endif
	ctx = EVP_PKEY_CTX_new_id(pkey_id, e);

	if (!ctx)
		goto err;
	if (do_param)
		{
		if (EVP_PKEY_paramgen_init(ctx) <= 0)
			goto err;
		}
	else
		{
		if (EVP_PKEY_keygen_init(ctx) <= 0)
			goto err;
		}

	*pctx = ctx;
	return 1;

	err:
	BIO_printf(err, "Error initializing %s context\n", algname);
	ERR_print_errors(err);
	if (ctx)
		EVP_PKEY_CTX_free(ctx);
	return 0;

	}
Пример #3
0
static int get_optional_pkey_id(const char *pkey_name)
	{
	const EVP_PKEY_ASN1_METHOD *ameth;
	int pkey_id=0;
	ameth = EVP_PKEY_asn1_find_str(NULL,pkey_name,-1);
	if (ameth) 
		{
		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
		}		
	return pkey_id;
	}
Пример #4
0
static int get_optional_pkey_id(const char *pkey_name)
	{
	const EVP_PKEY_ASN1_METHOD *ameth;
	ENGINE *tmpeng = NULL;
	int pkey_id=0;
	ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1);
	if (ameth)
		{
		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
		}
	if (tmpeng) ENGINE_finish(tmpeng);
	return pkey_id;
	}
Пример #5
0
static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
	{
	const EVP_PKEY_ASN1_METHOD *ameth;
	ENGINE *e = NULL;
	if (pkey)
		{
		if (pkey->pkey.ptr)
			EVP_PKEY_free_it(pkey);
		/* If key type matches and a method exists then this
		 * lookup has succeeded once so just indicate success.
		 */
		if ((type == pkey->save_type) && pkey->ameth)
			return 1;
#ifndef OPENSSL_NO_ENGINE
		/* If we have an ENGINE release it */
		if (pkey->engine)
			{
			ENGINE_finish(pkey->engine);
			pkey->engine = NULL;
			}
#endif
		}
	if (str)
		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
	else
		ameth = EVP_PKEY_asn1_find(&e, type);
#ifndef OPENSSL_NO_ENGINE
	if (!pkey && e)
		ENGINE_finish(e);
#endif
	if (!ameth)
		{
		EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
		return 0;
		}
	if (pkey)
		{
		pkey->ameth = ameth;
		pkey->engine = e;

		pkey->type = pkey->ameth->pkey_id;
		pkey->save_type=type;
		}
	return 1;
	}
Пример #6
0
int
init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx,
    const char *algname, int do_param)
{
	EVP_PKEY_CTX *ctx = NULL;
	const EVP_PKEY_ASN1_METHOD *ameth;
	int pkey_id;

	if (*pctx) {
		BIO_puts(err, "Algorithm already set!\n");
		return 0;
	}
	ameth = EVP_PKEY_asn1_find_str(NULL, algname, -1);

	if (!ameth) {
		BIO_printf(bio_err, "Algorithm %s not found\n", algname);
		return 0;
	}
	ERR_clear_error();

	EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
	ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL);

	if (!ctx)
		goto err;
	if (do_param) {
		if (EVP_PKEY_paramgen_init(ctx) <= 0)
			goto err;
	} else {
		if (EVP_PKEY_keygen_init(ctx) <= 0)
			goto err;
	}

	*pctx = ctx;
	return 1;

err:
	BIO_printf(err, "Error initializing %s context\n", algname);
	ERR_print_errors(err);
	if (ctx)
		EVP_PKEY_CTX_free(ctx);
	return 0;

}
Пример #7
0
__owur static int parse_expected_key_type(int *ptype, const char *value)
{
    int nid;
    const EVP_PKEY_ASN1_METHOD *ameth;

    if (value == NULL)
        return 0;
    ameth = EVP_PKEY_asn1_find_str(NULL, value, -1);
    if (ameth != NULL)
        EVP_PKEY_asn1_get0_info(&nid, NULL, NULL, NULL, NULL, ameth);
    else
        nid = OBJ_sn2nid(value);
    if (nid == NID_undef)
        nid = OBJ_ln2nid(value);
#ifndef OPENSSL_NO_EC
    if (nid == NID_undef)
        nid = EC_curve_nist2nid(value);
#endif
    if (nid == NID_undef)
        return 0;
    *ptype = nid;
    return 1;
}
Пример #8
0
static int check_pem(const char *nm, const char *name)
{
    /* Normal matching nm and name */
    if (strcmp(nm, name) == 0)
        return 1;

    /* Make PEM_STRING_EVP_PKEY match any private key */

    if (strcmp(name, PEM_STRING_EVP_PKEY) == 0) {
        int slen;
        const EVP_PKEY_ASN1_METHOD *ameth;
        if (strcmp(nm, PEM_STRING_PKCS8) == 0)
            return 1;
        if (strcmp(nm, PEM_STRING_PKCS8INF) == 0)
            return 1;
        slen = pem_check_suffix(nm, "PRIVATE KEY");
        if (slen > 0) {
            /*
             * NB: ENGINE implementations won't contain a deprecated old
             * private key decode function so don't look for them.
             */
            ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
            if (ameth && ameth->old_priv_decode)
                return 1;
        }
        return 0;
    }

    if (strcmp(name, PEM_STRING_PARAMETERS) == 0) {
        int slen;
        const EVP_PKEY_ASN1_METHOD *ameth;
        slen = pem_check_suffix(nm, "PARAMETERS");
        if (slen > 0) {
            ENGINE *e;
            ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
            if (ameth) {
                int r;
                if (ameth->param_decode)
                    r = 1;
                else
                    r = 0;
#ifndef OPENSSL_NO_ENGINE
                ENGINE_finish(e);
#endif
                return r;
            }
        }
        return 0;
    }
    /* If reading DH parameters handle X9.42 DH format too */
    if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0
        && strcmp(name, PEM_STRING_DHPARAMS) == 0)
        return 1;

    /* Permit older strings */

    if (strcmp(nm, PEM_STRING_X509_OLD) == 0
        && strcmp(name, PEM_STRING_X509) == 0)
        return 1;

    if (strcmp(nm, PEM_STRING_X509_REQ_OLD) == 0
        && strcmp(name, PEM_STRING_X509_REQ) == 0)
        return 1;

    /* Allow normal certs to be read as trusted certs */
    if (strcmp(nm, PEM_STRING_X509) == 0
        && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
        return 1;

    if (strcmp(nm, PEM_STRING_X509_OLD) == 0
        && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
        return 1;

    /* Some CAs use PKCS#7 with CERTIFICATE headers */
    if (strcmp(nm, PEM_STRING_X509) == 0
        && strcmp(name, PEM_STRING_PKCS7) == 0)
        return 1;

    if (strcmp(nm, PEM_STRING_PKCS7_SIGNED) == 0
        && strcmp(name, PEM_STRING_PKCS7) == 0)
        return 1;

#ifndef OPENSSL_NO_CMS
    if (strcmp(nm, PEM_STRING_X509) == 0
        && strcmp(name, PEM_STRING_CMS) == 0)
        return 1;
    /* Allow CMS to be read from PKCS#7 headers */
    if (strcmp(nm, PEM_STRING_PKCS7) == 0
        && strcmp(name, PEM_STRING_CMS) == 0)
        return 1;
#endif

    return 0;
}
Пример #9
0
EVP_PKEY *
PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
{
	char *nm = NULL;
	const unsigned char *p = NULL;
	unsigned char *data = NULL;
	long len;
	int slen;
	EVP_PKEY *ret = NULL;

	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY,
	    bp, cb, u))
		return NULL;
	p = data;

	if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
		if (!p8inf)
			goto p8err;
		ret = EVP_PKCS82PKEY(p8inf);
		if (x) {
			EVP_PKEY_free(*x);
			*x = ret;
		}
		PKCS8_PRIV_KEY_INFO_free(p8inf);
	} else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		X509_SIG *p8;
		int klen;
		char psbuf[PEM_BUFSIZE];
		p8 = d2i_X509_SIG(NULL, &p, len);
		if (!p8)
			goto p8err;
		if (cb)
			klen = cb(psbuf, PEM_BUFSIZE, 0, u);
		else
			klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
		if (klen <= 0) {
			PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,
			    PEM_R_BAD_PASSWORD_READ);
			X509_SIG_free(p8);
			goto err;
		}
		p8inf = PKCS8_decrypt(p8, psbuf, klen);
		X509_SIG_free(p8);
		if (!p8inf)
			goto p8err;
		ret = EVP_PKCS82PKEY(p8inf);
		if (x) {
			EVP_PKEY_free(*x);
			*x = ret;
		}
		PKCS8_PRIV_KEY_INFO_free(p8inf);
	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
		const EVP_PKEY_ASN1_METHOD *ameth;
		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
		if (!ameth || !ameth->old_priv_decode)
			goto p8err;
		ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
	}

p8err:
	if (ret == NULL)
		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
err:
	free(nm);
	OPENSSL_cleanse(data, len);
	free(data);
	return (ret);
}
Пример #10
0
static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
                                              const char *pem_header,
                                              const unsigned char *blob,
                                              size_t len, void **pctx,
                                              int *matchcount,
                                              const UI_METHOD *ui_method,
                                              void *ui_data)
{
    OSSL_STORE_INFO *store_info = NULL;
    EVP_PKEY *pkey = NULL;
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) {
            PKCS8_PRIV_KEY_INFO *p8inf =
                d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len);

            *matchcount = 1;
            if (p8inf != NULL)
                pkey = EVP_PKCS82PKEY(p8inf);
            PKCS8_PRIV_KEY_INFO_free(p8inf);
        } else {
            int slen;

            if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
                && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
                                                   slen)) != NULL) {
                *matchcount = 1;
                pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
            }
        }
    } else {
        int i;

        for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
            EVP_PKEY *tmp_pkey = NULL;
            const unsigned char *tmp_blob = blob;

            ameth = EVP_PKEY_asn1_get0(i);
            if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
                continue;

            tmp_pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &tmp_blob, len);
            if (tmp_pkey != NULL) {
                if (pkey != NULL)
                    EVP_PKEY_free(tmp_pkey);
                else
                    pkey = tmp_pkey;
                (*matchcount)++;
            }
        }

        if (*matchcount > 1) {
            EVP_PKEY_free(pkey);
            pkey = NULL;
        }
    }
    if (pkey == NULL)
        /* No match */
        return NULL;

    store_info = OSSL_STORE_INFO_new_PKEY(pkey);
    if (store_info == NULL)
        EVP_PKEY_free(pkey);

    return store_info;
}