示例#1
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid, keylen;
    EVP_CIPHER_CTX ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBE2PARAM *pbe2 = NULL;
    ASN1_OBJECT *obj;

    alg_nid = EVP_CIPHER_type(cipher);
    if (alg_nid == NID_undef) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        goto err;
    }
    obj = OBJ_nid2obj(alg_nid);

    if (!(pbe2 = PBE2PARAM_new()))
        goto merr;

    /* Setup the AlgorithmIdentifier for the encryption scheme */
    scheme = pbe2->encryption;

    scheme->algorithm = obj;
    if (!(scheme->parameter = ASN1_TYPE_new()))
        goto merr;

    /* Create random IV */
    if (EVP_CIPHER_iv_length(cipher)) {
        if (aiv)
            sgx_memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
        else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
            goto err;
    }

    EVP_CIPHER_CTX_init(&ctx);

    /* Dummy cipherinit to just setup the IV, and PRF */
    if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
        goto err;
    if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        EVP_CIPHER_CTX_cleanup(&ctx);
        goto err;
    }
    /*
     * If prf NID unspecified see if cipher has a preference. An error is OK
     * here: just means use default PRF.
     */
    if ((prf_nid == -1) &&
        EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
        ERR_clear_error();
        prf_nid = NID_hmacWithSHA1;
    }
    EVP_CIPHER_CTX_cleanup(&ctx);

    /* If its RC2 then we'd better setup the key length */

    if (alg_nid == NID_rc2_cbc)
        keylen = EVP_CIPHER_key_length(cipher);
    else
        keylen = -1;

    /* Setup keyfunc */

    X509_ALGOR_free(pbe2->keyfunc);

    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);

    if (!pbe2->keyfunc)
        goto merr;

    /* Now set up top level AlgorithmIdentifier */

    if (!(ret = X509_ALGOR_new()))
        goto merr;
    if (!(ret->parameter = ASN1_TYPE_new()))
        goto merr;

    ret->algorithm = OBJ_nid2obj(NID_pbes2);

    /* Encode PBE2PARAM into parameter */

    if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
                        &ret->parameter->value.sequence))
         goto merr;
    ret->parameter->type = V_ASN1_SEQUENCE;

    PBE2PARAM_free(pbe2);
    pbe2 = NULL;

    return ret;

 merr:
    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);

 err:
    PBE2PARAM_free(pbe2);
    /* Note 'scheme' is freed as part of pbe2 */
    X509_ALGOR_free(kalg);
    X509_ALGOR_free(ret);

    return NULL;

}
示例#2
0
文件: ts.c 项目: 375670450/openssl
static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
                            const char *policy, int no_nonce, int cert)
{
    int ret = 0;
    TS_REQ *ts_req = NULL;
    int len;
    TS_MSG_IMPRINT *msg_imprint = NULL;
    X509_ALGOR *algo = NULL;
    unsigned char *data = NULL;
    ASN1_OBJECT *policy_obj = NULL;
    ASN1_INTEGER *nonce_asn1 = NULL;

    /* Setting default message digest. */
    if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL)
        goto err;

    /* Creating request object. */
    if ((ts_req = TS_REQ_new()) == NULL)
        goto err;

    /* Setting version. */
    if (!TS_REQ_set_version(ts_req, 1))
        goto err;

    /* Creating and adding MSG_IMPRINT object. */
    if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL)
        goto err;

    /* Adding algorithm. */
    if ((algo = X509_ALGOR_new()) == NULL)
        goto err;
    if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
        goto err;
    if ((algo->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    algo->parameter->type = V_ASN1_NULL;
    if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo))
        goto err;

    /* Adding message digest. */
    if ((len = create_digest(data_bio, digest, md, &data)) == 0)
        goto err;
    if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len))
        goto err;

    if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint))
        goto err;

    /* Setting policy if requested. */
    if (policy && (policy_obj = txt2obj(policy)) == NULL)
        goto err;
    if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj))
        goto err;

    /* Setting nonce if requested. */
    if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL)
        goto err;
    if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1))
        goto err;

    /* Setting certificate request flag if requested. */
    if (!TS_REQ_set_cert_req(ts_req, cert))
        goto err;

    ret = 1;
 err:
    if (!ret) {
        TS_REQ_free(ts_req);
        ts_req = NULL;
        BIO_printf(bio_err, "could not create query\n");
    }
    TS_MSG_IMPRINT_free(msg_imprint);
    X509_ALGOR_free(algo);
    OPENSSL_free(data);
    ASN1_OBJECT_free(policy_obj);
    ASN1_INTEGER_free(nonce_asn1);
    return ts_req;
}
示例#3
0
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                             int prf_nid, int keylen)
{
    X509_ALGOR *keyfunc = NULL;
    PBKDF2PARAM *kdf = NULL;
    ASN1_OCTET_STRING *osalt = NULL;

    if (!(kdf = PBKDF2PARAM_new()))
        goto merr;
    if (!(osalt = M_ASN1_OCTET_STRING_new()))
        goto merr;

    kdf->salt->value.octet_string = osalt;
    kdf->salt->type = V_ASN1_OCTET_STRING;

    if (!saltlen)
        saltlen = PKCS5_SALT_LEN;
    if (!(osalt->data = OPENSSL_malloc(saltlen)))
        goto merr;

    osalt->length = saltlen;

    if (salt)
        sgx_memcpy(osalt->data, salt, saltlen);
    else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
        goto merr;

    if (iter <= 0)
        iter = PKCS5_DEFAULT_ITER;

    if (!ASN1_INTEGER_set(kdf->iter, iter))
        goto merr;

    /* If have a key len set it up */

    if (keylen > 0) {
        if (!(kdf->keylength = M_ASN1_INTEGER_new()))
            goto merr;
        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
            goto merr;
    }

    /* prf can stay NULL if we are using hmacWithSHA1 */
    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
        kdf->prf = X509_ALGOR_new();
        if (!kdf->prf)
            goto merr;
        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
    }

    /* Finally setup the keyfunc structure */

    keyfunc = X509_ALGOR_new();
    if (!keyfunc)
        goto merr;

    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

    /* Encode PBKDF2PARAM into parameter of pbe2 */

    if (!(keyfunc->parameter = ASN1_TYPE_new()))
        goto merr;

    if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
                        &keyfunc->parameter->value.sequence))
         goto merr;
    keyfunc->parameter->type = V_ASN1_SEQUENCE;

    PBKDF2PARAM_free(kdf);
    return keyfunc;

 merr:
    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
    PBKDF2PARAM_free(kdf);
    X509_ALGOR_free(keyfunc);
    return NULL;
}
示例#4
0
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
	{
	BIO *b;
	EVP_CIPHER_CTX *ctx;
	const EVP_CIPHER *ciph;
	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
	unsigned char *tkey = NULL;
	size_t tkeylen = 0;

	int ok = 0;

	int enc, keep_key = 0;

	enc = ec->cipher ? 1 : 0;

	b = BIO_new(BIO_f_cipher());
	if (!b)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							ERR_R_MALLOC_FAILURE);
		return NULL;
		}

	BIO_get_cipher_ctx(b, &ctx);

	if (enc)
		{
		ciph = ec->cipher;
		/* If not keeping key set cipher to NULL so subsequent calls
		 * decrypt.
		 */
		if (ec->key)
			ec->cipher = NULL;
		}
	else
		{
		ciph = EVP_get_cipherbyobj(calg->algorithm);

		if (!ciph)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							CMS_R_UNKNOWN_CIPHER);
			goto err;
			}
		}

	if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_INITIALISATION_ERROR);
		goto err;
		}

	if (enc)
		{
		int ivlen;
		calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
		/* Generate a random IV if we need one */
		ivlen = EVP_CIPHER_CTX_iv_length(ctx);
		if (ivlen > 0)
			{
			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
				goto err;
			piv = iv;
			}
		}
	else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
		goto err;
		}
	tkeylen = EVP_CIPHER_CTX_key_length(ctx);
	/* Generate random session key */
	if (!enc || !ec->key)
		{
		tkey = OPENSSL_malloc(tkeylen);
		if (!tkey)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
			goto err;
		}

	if (!ec->key)
		{
		ec->key = tkey;
		ec->keylen = tkeylen;
		tkey = NULL;
		if (enc)
			keep_key = 1;
		else
			ERR_clear_error();
		
		}

	if (ec->keylen != tkeylen)
		{
		/* If necessary set key length */
		if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
			{
			/* Only reveal failure if debugging so we don't
			 * leak information which may be useful in MMA.
			 */
			if (enc || ec->debug)
				{
				CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
						CMS_R_INVALID_KEY_LENGTH);
				goto err;
				}
			else
				{
				/* Use random key */
				OPENSSL_cleanse(ec->key, ec->keylen);
				OPENSSL_free(ec->key);
				ec->key = tkey;
				ec->keylen = tkeylen;
				tkey = NULL;
				ERR_clear_error();
				}
			}
		}

	if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_INITIALISATION_ERROR);
		goto err;
		}

	if (piv)
		{
		calg->parameter = ASN1_TYPE_new();
		if (!calg->parameter)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
			goto err;
			}
		}
	ok = 1;

	err:
	if (ec->key && !keep_key)
		{
		OPENSSL_cleanse(ec->key, ec->keylen);
		OPENSSL_free(ec->key);
		ec->key = NULL;
		}
	if (tkey)
		{
		OPENSSL_cleanse(tkey, tkeylen);
		OPENSSL_free(tkey);
		}
	if (ok)
		return b;
	BIO_free(b);
	return NULL;
	}
示例#5
0
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
                           unsigned char *salt, int saltlen)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid;
    EVP_CIPHER_CTX ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBKDF2PARAM *kdf = NULL;
    PBE2PARAM *pbe2 = NULL;
    ASN1_OCTET_STRING *osalt = NULL;
    ASN1_OBJECT *obj;

    alg_nid = EVP_CIPHER_type(cipher);
    if (alg_nid == NID_undef) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET,
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        goto err;
    }
    obj = OBJ_nid2obj(alg_nid);

    if (!(pbe2 = PBE2PARAM_new()))
        goto merr;

    /* Setup the AlgorithmIdentifier for the encryption scheme */
    scheme = pbe2->encryption;

    scheme->algorithm = obj;
    if (!(scheme->parameter = ASN1_TYPE_new()))
        goto merr;

    /* Create random IV */
    if (EVP_CIPHER_iv_length(cipher) &&
        RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
        goto err;

    EVP_CIPHER_CTX_init(&ctx);

    /* Dummy cipherinit to just setup the IV */
    EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
    if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        EVP_CIPHER_CTX_cleanup(&ctx);
        goto err;
    }
    EVP_CIPHER_CTX_cleanup(&ctx);

    if (!(kdf = PBKDF2PARAM_new()))
        goto merr;
    if (!(osalt = M_ASN1_OCTET_STRING_new()))
        goto merr;

    if (!saltlen)
        saltlen = PKCS5_SALT_LEN;
    if (!(osalt->data = OPENSSL_malloc(saltlen)))
        goto merr;
    osalt->length = saltlen;
    if (salt)
        memcpy(osalt->data, salt, saltlen);
    else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
        goto merr;

    if (iter <= 0)
        iter = PKCS5_DEFAULT_ITER;
    if (!ASN1_INTEGER_set(kdf->iter, iter))
        goto merr;

    /* Now include salt in kdf structure */
    kdf->salt->value.octet_string = osalt;
    kdf->salt->type = V_ASN1_OCTET_STRING;
    osalt = NULL;

    /* If its RC2 then we'd better setup the key length */

    if (alg_nid == NID_rc2_cbc) {
        if (!(kdf->keylength = M_ASN1_INTEGER_new()))
            goto merr;
        if (!ASN1_INTEGER_set(kdf->keylength, EVP_CIPHER_key_length(cipher)))
            goto merr;
    }

    /* prf can stay NULL because we are using hmacWithSHA1 */

    /* Now setup the PBE2PARAM keyfunc structure */

    pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

    /* Encode PBKDF2PARAM into parameter of pbe2 */

    if (!(pbe2->keyfunc->parameter = ASN1_TYPE_new()))
        goto merr;

    if (!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM,
                             &pbe2->keyfunc->parameter->value.sequence))
         goto merr;
    pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;

    PBKDF2PARAM_free(kdf);
    kdf = NULL;

    /* Now set up top level AlgorithmIdentifier */

    if (!(ret = X509_ALGOR_new()))
        goto merr;
    if (!(ret->parameter = ASN1_TYPE_new()))
        goto merr;

    ret->algorithm = OBJ_nid2obj(NID_pbes2);

    /* Encode PBE2PARAM into parameter */

    if (!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM,
                             &ret->parameter->value.sequence))
         goto merr;
    ret->parameter->type = V_ASN1_SEQUENCE;

    PBE2PARAM_free(pbe2);
    pbe2 = NULL;

    return ret;

 merr:
    ASN1err(ASN1_F_PKCS5_PBE2_SET, ERR_R_MALLOC_FAILURE);

 err:
    PBE2PARAM_free(pbe2);
    /* Note 'scheme' is freed as part of pbe2 */
    M_ASN1_OCTET_STRING_free(osalt);
    PBKDF2PARAM_free(kdf);
    X509_ALGOR_free(kalg);
    X509_ALGOR_free(ret);

    return NULL;

}
示例#6
0
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
	{
	int i;
	BIO *out=NULL,*btmp=NULL;
	X509_ALGOR *xa = NULL;
	const EVP_CIPHER *evp_cipher=NULL;
	STACK_OF(X509_ALGOR) *md_sk=NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
	X509_ALGOR *xalg=NULL;
	PKCS7_RECIP_INFO *ri=NULL;
	ASN1_OCTET_STRING *os=NULL;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signed:
		md_sk=p7->d.sign->md_algs;
		os = PKCS7_get_octet_string(p7->d.sign->contents);
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk=p7->d.signed_and_enveloped->recipientinfo;
		md_sk=p7->d.signed_and_enveloped->md_algs;
		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	case NID_pkcs7_enveloped:
		rsk=p7->d.enveloped->recipientinfo;
		xalg=p7->d.enveloped->enc_data->algorithm;
		evp_cipher=p7->d.enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	case NID_pkcs7_digest:
		xa = p7->d.digest->md;
		os = PKCS7_get_octet_string(p7->d.digest->contents);
		break;
	case NID_pkcs7_data:
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
	        goto err;
		}

	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
			goto err;

	if (xa && !PKCS7_bio_add_digest(&out, xa))
			goto err;

	if (evp_cipher != NULL)
		{
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		int keylen,ivlen;
		EVP_CIPHER_CTX *ctx;

		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
			goto err;
			}
		BIO_get_cipher_ctx(btmp, &ctx);
		keylen=EVP_CIPHER_key_length(evp_cipher);
		ivlen=EVP_CIPHER_iv_length(evp_cipher);
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0)
			if (RAND_pseudo_bytes(iv,ivlen) <= 0)
				goto err;
		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
			goto err;
		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
			goto err;
		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
			goto err;

		if (ivlen > 0) {
			if (xalg->parameter == NULL) {
				xalg->parameter = ASN1_TYPE_new();
				if (xalg->parameter == NULL)
					goto err;
			}
			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
				goto err;
		}

		/* Lets do the pub key stuff :-) */
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
				goto err;
			}
		OPENSSL_cleanse(key, keylen);

		if (out == NULL)
			out=btmp;
		else
			BIO_push(out,btmp);
		btmp=NULL;
		}

	if (bio == NULL)
		{
		if (PKCS7_is_detached(p7))
			bio=BIO_new(BIO_s_null());
		else if (os && os->length > 0)
			bio = BIO_new_mem_buf(os->data, os->length);
		if(bio == NULL)
			{
			bio=BIO_new(BIO_s_mem());
			if (bio == NULL)
				goto err;
			BIO_set_mem_eof_return(bio,0);
			}
		}
	if (out)
		BIO_push(out,bio);
	else
		out = bio;
	bio=NULL;
	if (0)
		{
err:
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		out=NULL;
		}
	return(out);
	}
示例#7
0
CMS_RecipientInfo *
CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, int wrap_nid,
    int pbe_nid, unsigned char *pass, ssize_t passlen,
    const EVP_CIPHER *kekciph)
{
	CMS_RecipientInfo *ri = NULL;
	CMS_EnvelopedData *env;
	CMS_PasswordRecipientInfo *pwri;
	EVP_CIPHER_CTX ctx;
	X509_ALGOR *encalg = NULL;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	int ivlen;

	env = cms_get0_enveloped(cms);
	if (!env)
		return NULL;

	if (wrap_nid <= 0)
		wrap_nid = NID_id_alg_PWRI_KEK;

	if (pbe_nid <= 0)
		pbe_nid = NID_id_pbkdf2;

	/* Get from enveloped data */
	if (kekciph == NULL)
		kekciph = env->encryptedContentInfo->cipher;

	if (kekciph == NULL) {
		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
		return NULL;
	}
	if (wrap_nid != NID_id_alg_PWRI_KEK) {
		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
		    CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
		return NULL;
	}

	/* Setup algorithm identifier for cipher */
	encalg = X509_ALGOR_new();
	EVP_CIPHER_CTX_init(&ctx);

	if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) {
		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
		goto err;
	}

	ivlen = EVP_CIPHER_CTX_iv_length(&ctx);

	if (ivlen > 0) {
		arc4random_buf(iv, ivlen);
		if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) {
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
			    ERR_R_EVP_LIB);
			goto err;
		}
		encalg->parameter = ASN1_TYPE_new();
		if (!encalg->parameter) {
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
			    ERR_R_MALLOC_FAILURE);
			goto err;
		}
		if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) {
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
			    CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
			goto err;
		}
	}


	encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));

	EVP_CIPHER_CTX_cleanup(&ctx);

	/* Initialize recipient info */
	ri = M_ASN1_new_of(CMS_RecipientInfo);
	if (!ri)
		goto merr;

	ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
	if (!ri->d.pwri)
		goto merr;
	ri->type = CMS_RECIPINFO_PASS;

	pwri = ri->d.pwri;
	/* Since this is overwritten, free up empty structure already there */
	X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
	pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
	if (!pwri->keyEncryptionAlgorithm)
		goto merr;
	pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
	pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
	if (!pwri->keyEncryptionAlgorithm->parameter)
		goto merr;

	if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
	    &pwri->keyEncryptionAlgorithm->parameter->value.sequence))
		goto merr;
	pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;

	X509_ALGOR_free(encalg);
	encalg = NULL;

	/* Setup PBE algorithm */

	pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);

	if (!pwri->keyDerivationAlgorithm)
		goto err;

	CMS_RecipientInfo_set0_password(ri, pass, passlen);
	pwri->version = 0;

	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
		goto merr;

	return ri;

merr:
	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
err:
	EVP_CIPHER_CTX_cleanup(&ctx);
	if (ri)
		M_ASN1_free_of(ri, CMS_RecipientInfo);
	if (encalg)
		X509_ALGOR_free(encalg);
	return NULL;
}
示例#8
0
int i2d_RSA_NET(RSA *a, unsigned char **pp, int (*cb)(), int sgckey)
	{
	int i,j,l[6];
	NETSCAPE_PKEY *pkey;
	unsigned char buf[256],*zz;
	unsigned char key[EVP_MAX_KEY_LENGTH];
	EVP_CIPHER_CTX ctx;
	X509_ALGOR *alg=NULL;
	ASN1_OCTET_STRING os,os2;
	M_ASN1_I2D_vars(a);

	if (a == NULL) return(0);

#ifdef WIN32
	r=r; /* shut the damn compiler up :-) */
#endif

	os.data=os2.data=NULL;
	if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
	if (!ASN1_INTEGER_set(pkey->version,0)) goto err;

	if (pkey->algor->algorithm != NULL)
		ASN1_OBJECT_free(pkey->algor->algorithm);
	pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
	if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
	pkey->algor->parameter->type=V_ASN1_NULL;

	l[0]=i2d_RSAPrivateKey(a,NULL);
	pkey->private_key->length=l[0];

	os2.length=i2d_NETSCAPE_PKEY(pkey,NULL);
	l[1]=i2d_ASN1_OCTET_STRING(&os2,NULL);

	if ((alg=X509_ALGOR_new()) == NULL) goto err;
	if (alg->algorithm != NULL)
		ASN1_OBJECT_free(alg->algorithm);
	alg->algorithm=OBJ_nid2obj(NID_rc4);
	if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err;
	alg->parameter->type=V_ASN1_NULL;

	l[2]=i2d_X509_ALGOR(alg,NULL);
	l[3]=ASN1_object_size(1,l[2]+l[1],V_ASN1_SEQUENCE);

#ifndef CONST_STRICT
	os.data=(unsigned char *)"private-key";
#endif
	os.length=11;
	l[4]=i2d_ASN1_OCTET_STRING(&os,NULL);

	l[5]=ASN1_object_size(1,l[4]+l[3],V_ASN1_SEQUENCE);

	if (pp == NULL)
		{
		if (pkey != NULL) NETSCAPE_PKEY_free(pkey);
		if (alg != NULL) X509_ALGOR_free(alg);
		return(l[5]);
		}

	if (pkey->private_key->data != NULL)
		OPENSSL_free(pkey->private_key->data);
	if ((pkey->private_key->data=(unsigned char *)OPENSSL_malloc(l[0])) == NULL)
		{
		ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	zz=pkey->private_key->data;
	i2d_RSAPrivateKey(a,&zz);

	if ((os2.data=(unsigned char *)OPENSSL_malloc(os2.length)) == NULL)
		{
		ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	zz=os2.data;
	i2d_NETSCAPE_PKEY(pkey,&zz);
		
	if (cb == NULL)
		cb=EVP_read_pw_string;
	i=cb(buf,256,"Enter Private Key password:"******"SGCKEYSALT", 10);
		i = 26;
	}
		
	EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
	memset(buf,0,256);

	EVP_CIPHER_CTX_init(&ctx);
	EVP_EncryptInit(&ctx,EVP_rc4(),key,NULL);
	EVP_EncryptUpdate(&ctx,os2.data,&i,os2.data,os2.length);
	EVP_EncryptFinal(&ctx,&(os2.data[i]),&j);
	EVP_CIPHER_CTX_cleanup(&ctx);

	p= *pp;
	ASN1_put_object(&p,1,l[4]+l[3],V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
	i2d_ASN1_OCTET_STRING(&os,&p);
	ASN1_put_object(&p,1,l[2]+l[1],V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
	i2d_X509_ALGOR(alg,&p);
	i2d_ASN1_OCTET_STRING(&os2,&p);
	ret=l[5];
err:
	if (os2.data != NULL) OPENSSL_free(os2.data);
	if (alg != NULL) X509_ALGOR_free(alg);
	if (pkey != NULL) NETSCAPE_PKEY_free(pkey);
	r=r;
	return(ret);
	}
示例#9
0
static ASN1_TYPE *
asn1_str2type(const char *str, int format, int utype)
{
	ASN1_TYPE *atmp = NULL;
	CONF_VALUE vtmp;
	unsigned char *rdata;
	long rdlen;
	int no_unused = 1;

	if (!(atmp = ASN1_TYPE_new())) {
		ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	if (!str)
		str = "";

	switch (utype) {

	case V_ASN1_NULL:
		if (str && *str) {
			ASN1err(ASN1_F_ASN1_STR2TYPE,
			    ASN1_R_ILLEGAL_NULL_VALUE);
			goto bad_form;
		}
		break;

	case V_ASN1_BOOLEAN:
		if (format != ASN1_GEN_FORMAT_ASCII) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
			goto bad_form;
		}
		vtmp.name = NULL;
		vtmp.section = NULL;
		vtmp.value = (char *)str;
		if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
			goto bad_str;
		}
		break;

	case V_ASN1_INTEGER:
	case V_ASN1_ENUMERATED:
		if (format != ASN1_GEN_FORMAT_ASCII) {
			ASN1err(ASN1_F_ASN1_STR2TYPE,
			    ASN1_R_INTEGER_NOT_ASCII_FORMAT);
			goto bad_form;
		}
		if (!(atmp->value.integer =
		    s2i_ASN1_INTEGER(NULL, (char *)str))) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
			goto bad_str;
		}
		break;

	case V_ASN1_OBJECT:
		if (format != ASN1_GEN_FORMAT_ASCII) {
			ASN1err(ASN1_F_ASN1_STR2TYPE,
			    ASN1_R_OBJECT_NOT_ASCII_FORMAT);
			goto bad_form;
		}
		if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
			goto bad_str;
		}
		break;

	case V_ASN1_UTCTIME:
	case V_ASN1_GENERALIZEDTIME:
		if (format != ASN1_GEN_FORMAT_ASCII) {
			ASN1err(ASN1_F_ASN1_STR2TYPE,
			    ASN1_R_TIME_NOT_ASCII_FORMAT);
			goto bad_form;
		}
		if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_str;
		}
		if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_str;
		}
		atmp->value.asn1_string->type = utype;
		if (!ASN1_TIME_check(atmp->value.asn1_string)) {
			ASN1err(ASN1_F_ASN1_STR2TYPE,
			    ASN1_R_ILLEGAL_TIME_VALUE);
			goto bad_str;
		}
		break;

	case V_ASN1_BMPSTRING:
	case V_ASN1_PRINTABLESTRING:
	case V_ASN1_IA5STRING:
	case V_ASN1_T61STRING:
	case V_ASN1_UTF8STRING:
	case V_ASN1_VISIBLESTRING:
	case V_ASN1_UNIVERSALSTRING:
	case V_ASN1_GENERALSTRING:
	case V_ASN1_NUMERICSTRING:

		if (format == ASN1_GEN_FORMAT_ASCII)
			format = MBSTRING_ASC;
		else if (format == ASN1_GEN_FORMAT_UTF8)
			format = MBSTRING_UTF8;
		else {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
			goto bad_form;
		}

		if (ASN1_mbstring_copy(&atmp->value.asn1_string,
		    (unsigned char *)str, -1, format,
		    ASN1_tag2bit(utype)) <= 0) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_str;
		}
		break;

	case V_ASN1_BIT_STRING:
	case V_ASN1_OCTET_STRING:
		if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_form;
		}

		if (format == ASN1_GEN_FORMAT_HEX) {

			if (!(rdata = string_to_hex((char *)str, &rdlen))) {
				ASN1err(ASN1_F_ASN1_STR2TYPE,
				    ASN1_R_ILLEGAL_HEX);
				goto bad_str;
			}

			atmp->value.asn1_string->data = rdata;
			atmp->value.asn1_string->length = rdlen;
			atmp->value.asn1_string->type = utype;

		} else if (format == ASN1_GEN_FORMAT_ASCII)
			ASN1_STRING_set(atmp->value.asn1_string, str, -1);
		else if ((format == ASN1_GEN_FORMAT_BITLIST) &&
		    (utype == V_ASN1_BIT_STRING)) {
			if (!CONF_parse_list(str, ',', 1, bitstr_cb,
			    atmp->value.bit_string)) {
				ASN1err(ASN1_F_ASN1_STR2TYPE,
				    ASN1_R_LIST_ERROR);
				goto bad_str;
			}
			no_unused = 0;

		} else {
			ASN1err(ASN1_F_ASN1_STR2TYPE,
			    ASN1_R_ILLEGAL_BITSTRING_FORMAT);
			goto bad_form;
		}

		if ((utype == V_ASN1_BIT_STRING) && no_unused) {
			atmp->value.asn1_string->flags &=
			    ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
			atmp->value.asn1_string->flags |=
			    ASN1_STRING_FLAG_BITS_LEFT;
		}

		break;

	default:
		ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
		goto bad_str;
		break;
	}

	atmp->type = utype;
	return atmp;

bad_str:
	ERR_asprintf_error_data("string=%s", str);
bad_form:
	ASN1_TYPE_free(atmp);
	return NULL;
}
示例#10
0
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
	{
	int ok=0;
	X509_PUBKEY *pk;
	X509_ALGOR *a;
	ASN1_OBJECT *o;
	unsigned char *s,*p;
	int i;

	if (x == NULL) return(0);

	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
	a=pk->algor;

	/* set the algorithm id */
	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
	ASN1_OBJECT_free(a->algorithm);
	a->algorithm=o;

	/* Set the parameter list */
	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
		{
		if ((a->parameter == NULL) ||
			(a->parameter->type != V_ASN1_NULL))
			{
			ASN1_TYPE_free(a->parameter);
			a->parameter=ASN1_TYPE_new();
			a->parameter->type=V_ASN1_NULL;
			}
		}
	else
#ifndef NO_DSA
		if (pkey->type == EVP_PKEY_DSA)
		{
		unsigned char *pp;
		DSA *dsa;

		dsa=pkey->pkey.dsa;
		dsa->write_params=0;
		ASN1_TYPE_free(a->parameter);
		i=i2d_DSAparams(dsa,NULL);
		p=(unsigned char *)OPENSSL_malloc(i);
		pp=p;
		i2d_DSAparams(dsa,&pp);
		a->parameter=ASN1_TYPE_new();
		a->parameter->type=V_ASN1_SEQUENCE;
		a->parameter->value.sequence=ASN1_STRING_new();
		ASN1_STRING_set(a->parameter->value.sequence,p,i);
		OPENSSL_free(p);
		}
	else
#endif
		{
		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
		goto err;
		}

	if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
	if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL) goto err;
	p=s;
	i2d_PublicKey(pkey,&p);
	if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
	/* Set number of unused bits to zero */
	pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;

	OPENSSL_free(s);

#if 0
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
	pk->pkey=pkey;
#endif

	if (*x != NULL)
		X509_PUBKEY_free(*x);

	*x=pk;
	pk=NULL;

	ok=1;
err:
	if (pk != NULL) X509_PUBKEY_free(pk);
	return(ok);
	}
示例#11
0
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
	{
	ASN1_TYPE *ret = NULL;
	STACK_OF(ASN1_TYPE) *sk = NULL;
	STACK_OF(CONF_VALUE) *sect = NULL;
	unsigned char *der = NULL;
	int derlen;
	size_t i;
	sk = sk_ASN1_TYPE_new_null();
	if (!sk)
		goto bad;
	if (section)
		{
		if (!cnf)
			goto bad;
		sect = X509V3_get_section(cnf, (char *)section);
		if (!sect)
			goto bad;
		for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
			{
			ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
			if (!typ)
				goto bad;
			if (!sk_ASN1_TYPE_push(sk, typ))
				goto bad;
			}
		}

	/* Now we has a STACK of the components, convert to the correct form */

	if (utype == V_ASN1_SET)
		derlen = i2d_ASN1_SET_ANY(sk, &der);
	else
		derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);

	if (derlen < 0)
		goto bad;

	if (!(ret = ASN1_TYPE_new()))
		goto bad;

	if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
		goto bad;

	ret->type = utype;

	ret->value.asn1_string->data = der;
	ret->value.asn1_string->length = derlen;

	der = NULL;

	bad:

	if (der)
		OPENSSL_free(der);

	if (sk)
		sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
	if (sect)
		X509V3_section_free(cnf, sect);

	return ret;
	}
示例#12
0
static int dh_cms_encrypt(CMS_RecipientInfo *ri)
{
    EVP_PKEY_CTX *pctx;
    EVP_PKEY *pkey;
    EVP_CIPHER_CTX *ctx;
    int keylen;
    X509_ALGOR *talg, *wrap_alg = NULL;
    ASN1_OBJECT *aoid;
    ASN1_BIT_STRING *pubkey;
    ASN1_STRING *wrap_str;
    ASN1_OCTET_STRING *ukm;
    unsigned char *penc = NULL, *dukm = NULL;
    int penclen;
    size_t dukmlen = 0;
    int rv = 0;
    int kdf_type, wrap_nid;
    const EVP_MD *kdf_md;
    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    if (!pctx)
        return 0;
    /* Get ephemeral key */
    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
                                             NULL, NULL, NULL))
        goto err;
    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
    /* Is everything uninitialised? */
    if (aoid == OBJ_nid2obj(NID_undef)) {
        ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
        if (!pubk)
            goto err;
        /* Set the key */

        penclen = i2d_ASN1_INTEGER(pubk, &penc);
        ASN1_INTEGER_free(pubk);
        if (penclen <= 0)
            goto err;
        ASN1_STRING_set0(pubkey, penc, penclen);
        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;

        penc = NULL;
        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
                        V_ASN1_UNDEF, NULL);
    }

    /* See if custom paraneters set */
    kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
    if (kdf_type <= 0)
        goto err;
    if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
        goto err;

    if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
        kdf_type = EVP_PKEY_DH_KDF_X9_42;
        if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
            goto err;
    } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
        /* Unknown KDF */
        goto err;
    if (kdf_md == NULL) {
        /* Only SHA1 supported */
        kdf_md = EVP_sha1();
        if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
            goto err;
    } else if (EVP_MD_type(kdf_md) != NID_sha1)
        /* Unsupported digest */
        goto err;

    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
        goto err;

    /* Get wrap NID */
    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
    wrap_nid = EVP_CIPHER_CTX_type(ctx);
    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
        goto err;
    keylen = EVP_CIPHER_CTX_key_length(ctx);

    /* Package wrap algorithm in an AlgorithmIdentifier */

    wrap_alg = X509_ALGOR_new();
    if (!wrap_alg)
        goto err;
    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
    wrap_alg->parameter = ASN1_TYPE_new();
    if (!wrap_alg->parameter)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
        goto err;
    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
        ASN1_TYPE_free(wrap_alg->parameter);
        wrap_alg->parameter = NULL;
    }

    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
        goto err;

    if (ukm) {
        dukmlen = ASN1_STRING_length(ukm);
        dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
        if (!dukm)
            goto err;
    }

    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
        goto err;
    dukm = NULL;

    /*
     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
     * of another AlgorithmIdentifier.
     */
    penc = NULL;
    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
    if (!penc || !penclen)
        goto err;
    wrap_str = ASN1_STRING_new();
    if (!wrap_str)
        goto err;
    ASN1_STRING_set0(wrap_str, penc, penclen);
    penc = NULL;
    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
                    V_ASN1_SEQUENCE, wrap_str);

    rv = 1;

 err:
    OPENSSL_free(penc);
    X509_ALGOR_free(wrap_alg);
    return rv;
}
示例#13
0
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
	{
	int i,j;
	BIO *out=NULL,*btmp=NULL;
	X509_ALGOR *xa;
	const EVP_MD *evp_md;
	const EVP_CIPHER *evp_cipher=NULL;
	STACK_OF(X509_ALGOR) *md_sk=NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
	X509_ALGOR *xalg=NULL;
	PKCS7_RECIP_INFO *ri=NULL;
	EVP_PKEY *pkey;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signed:
		md_sk=p7->d.sign->md_algs;
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk=p7->d.signed_and_enveloped->recipientinfo;
		md_sk=p7->d.signed_and_enveloped->md_algs;
		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	case NID_pkcs7_enveloped:
		rsk=p7->d.enveloped->recipientinfo;
		xalg=p7->d.enveloped->enc_data->algorithm;
		evp_cipher=p7->d.enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
	        goto err;
		}

	if (md_sk != NULL)
		{
		for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
			{
			xa=sk_X509_ALGOR_value(md_sk,i);
			if ((btmp=BIO_new(BIO_f_md())) == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
				goto err;
				}

			j=OBJ_obj2nid(xa->algorithm);
			evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
			if (evp_md == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
				goto err;
				}

			BIO_set_md(btmp,evp_md);
			if (out == NULL)
				out=btmp;
			else
				BIO_push(out,btmp);
			btmp=NULL;
			}
		}

	if (evp_cipher != NULL)
		{
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		int keylen,ivlen;
		int jj,max;
		unsigned char *tmp;
		EVP_CIPHER_CTX *ctx;

		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
			goto err;
			}
		BIO_get_cipher_ctx(btmp, &ctx);
		keylen=EVP_CIPHER_key_length(evp_cipher);
		ivlen=EVP_CIPHER_iv_length(evp_cipher);
		if (RAND_bytes(key,keylen) <= 0)
			goto err;
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
		EVP_CipherInit(ctx, evp_cipher, key, iv, 1);

		if (ivlen > 0) {
			if (xalg->parameter == NULL) 
						xalg->parameter=ASN1_TYPE_new();
			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
								       goto err;
		}

		/* Lets do the pub key stuff :-) */
		max=0;
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			if (ri->cert == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
				goto err;
				}
			pkey=X509_get_pubkey(ri->cert);
			jj=EVP_PKEY_size(pkey);
			EVP_PKEY_free(pkey);
			if (max < jj) max=jj;
			}
		if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			pkey=X509_get_pubkey(ri->cert);
			jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
			EVP_PKEY_free(pkey);
			if (jj <= 0)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
				OPENSSL_free(tmp);
				goto err;
				}
			M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
			}
		OPENSSL_free(tmp);
		memset(key, 0, keylen);

		if (out == NULL)
			out=btmp;
		else
			BIO_push(out,btmp);
		btmp=NULL;
		}

	if (bio == NULL) {
		if (p7->detached)
			bio=BIO_new(BIO_s_null());
		else {
			if (PKCS7_type_is_signed(p7) &&
				PKCS7_type_is_data(p7->d.sign->contents)) {
				ASN1_OCTET_STRING *os;
				os=p7->d.sign->contents->d.data;
				if (os->length > 0) bio = 
					BIO_new_mem_buf(os->data, os->length);
			} 
			if(bio == NULL) {
				bio=BIO_new(BIO_s_mem());
				BIO_set_mem_eof_return(bio,0);
			}
		}
	}
	BIO_push(out,bio);
	bio=NULL;
	if (0)
		{
err:
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		out=NULL;
		}
	return(out);
	}
示例#14
0
/*
 * Creates a x509v3 extension containing a hash
 *
 * DigestInfo ::= SEQUENCE {
 *     digestAlgorithm  AlgorithmIdentifier,
 *     digest           OCTET STRING
 * }
 *
 * AlgorithmIdentifier ::=  SEQUENCE  {
 *     algorithm        OBJECT IDENTIFIER,
 *     parameters       ANY DEFINED BY algorithm OPTIONAL
 * }
 *
 * Parameters:
 *   nid: extension identifier
 *   crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
 *   md: hash algorithm
 *   buf: pointer to the buffer that contains the hash
 *   len: size of the hash in bytes
 *
 * Return: Extension address, NULL if error
 */
X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md,
		unsigned char *buf, size_t len)
{
	X509_EXTENSION *ex;
	ASN1_OCTET_STRING *octet;
	HASH *hash;
	ASN1_OBJECT *algorithm;
	X509_ALGOR *x509_algor;
	unsigned char *p = NULL;
	int sz;

	/* OBJECT_IDENTIFIER with hash algorithm */
	algorithm = OBJ_nid2obj(EVP_MD_type(md));
	if (algorithm == NULL) {
		return NULL;
	}

	/* Create X509_ALGOR */
	x509_algor = X509_ALGOR_new();
	if (x509_algor == NULL) {
		return NULL;
	}
	x509_algor->algorithm = algorithm;
	x509_algor->parameter = ASN1_TYPE_new();
	ASN1_TYPE_set(x509_algor->parameter, V_ASN1_NULL, NULL);

	/* OCTET_STRING with the actual hash */
	octet = ASN1_OCTET_STRING_new();
	if (octet == NULL) {
		X509_ALGOR_free(x509_algor);
		return NULL;
	}
	ASN1_OCTET_STRING_set(octet, buf, len);

	/* HASH structure containing algorithm + hash */
	hash = HASH_new();
	if (hash == NULL) {
		ASN1_OCTET_STRING_free(octet);
		X509_ALGOR_free(x509_algor);
		return NULL;
	}
	hash->hashAlgorithm = x509_algor;
	hash->dataHash = octet;

	/* DER encoded HASH */
	sz = i2d_HASH(hash, &p);
	if ((sz <= 0) || (p == NULL)) {
		HASH_free(hash);
		X509_ALGOR_free(x509_algor);
		return NULL;
	}

	/* Create the extension */
	ex = ext_new(nid, crit, p, sz);

	/* Clean up */
	OPENSSL_free(p);
	HASH_free(hash);

	return ex;
}
示例#15
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
				 unsigned char *salt, int saltlen,
				 unsigned char *aiv, int prf_nid)
{
	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
	int alg_nid;
	EVP_CIPHER_CTX ctx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	PBKDF2PARAM *kdf = NULL;
	PBE2PARAM *pbe2 = NULL;
	ASN1_OCTET_STRING *osalt = NULL;
	ASN1_OBJECT *obj;

	alg_nid = EVP_CIPHER_type(cipher);
	if(alg_nid == NID_undef) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
		goto err;
	}
	obj = OBJ_nid2obj(alg_nid);

	if(!(pbe2 = PBE2PARAM_new())) goto merr;

	/* Setup the AlgorithmIdentifier for the encryption scheme */
	scheme = pbe2->encryption;

	scheme->algorithm = obj;
	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;

	/* Create random IV */
	if (EVP_CIPHER_iv_length(cipher))
		{
		if (aiv)
			TINYCLR_SSL_MEMCPY(iv, aiv, EVP_CIPHER_iv_length(cipher));
		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
  			goto err;
		}

	EVP_CIPHER_CTX_init(&ctx);

	/* Dummy cipherinit to just setup the IV, and PRF */
	EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
		EVP_CIPHER_CTX_cleanup(&ctx);
		goto err;
	}
	/* If prf NID unspecified see if cipher has a preference.
	 * An error is OK here: just means use default PRF.
	 */
	if ((prf_nid == -1) && 
	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
		{
		ERR_clear_error();
		prf_nid = NID_hmacWithSHA1;
		}
	EVP_CIPHER_CTX_cleanup(&ctx);

	if(!(kdf = PBKDF2PARAM_new())) goto merr;
	if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;

	if (!saltlen) saltlen = PKCS5_SALT_LEN;
	if (!(osalt->data = (unsigned char*)OPENSSL_malloc (saltlen))) goto merr; //MS: cast to unsigned char*
	osalt->length = saltlen;
	if (salt) TINYCLR_SSL_MEMCPY (osalt->data, salt, saltlen);
	else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;

	if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
	if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;

	/* Now include salt in kdf structure */
	kdf->salt->value.octet_string = osalt;
	kdf->salt->type = V_ASN1_OCTET_STRING;
	osalt = NULL;

	/* If its RC2 then we'd better setup the key length */

	if(alg_nid == NID_rc2_cbc) {
		if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
		if(!ASN1_INTEGER_set (kdf->keylength,
				 EVP_CIPHER_key_length(cipher))) goto merr;
	}

	/* prf can stay NULL if we are using hmacWithSHA1 */
	if (prf_nid != NID_hmacWithSHA1)
		{
		kdf->prf = X509_ALGOR_new();
		if (!kdf->prf)
			goto merr;
		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
					V_ASN1_NULL, NULL);
		}

	/* Now setup the PBE2PARAM keyfunc structure */

	pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

	/* Encode PBKDF2PARAM into parameter of pbe2 */

	if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;

	if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
			 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
	pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;

	PBKDF2PARAM_free(kdf);
	kdf = NULL;

	/* Now set up top level AlgorithmIdentifier */

	if(!(ret = X509_ALGOR_new())) goto merr;
	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;

	ret->algorithm = OBJ_nid2obj(NID_pbes2);

	/* Encode PBE2PARAM into parameter */

	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
				 &ret->parameter->value.sequence)) goto merr;
	ret->parameter->type = V_ASN1_SEQUENCE;

	PBE2PARAM_free(pbe2);
	pbe2 = NULL;

	return ret;

	merr:
	ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);

	err:
	PBE2PARAM_free(pbe2);
	/* Note 'scheme' is freed as part of pbe2 */
	M_ASN1_OCTET_STRING_free(osalt);
	PBKDF2PARAM_free(kdf);
	X509_ALGOR_free(kalg);
	X509_ALGOR_free(ret);

	return NULL;

}
示例#16
0
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
{
	PKCS8_PRIV_KEY_INFO *p8;

	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {	
		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	p8->broken = broken;
	if (!ASN1_INTEGER_set(p8->version, 0)) {
		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
		PKCS8_PRIV_KEY_INFO_free (p8);
		return NULL;
	}
	if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
		PKCS8_PRIV_KEY_INFO_free (p8);
		return NULL;
	}
	p8->pkey->type = V_ASN1_OCTET_STRING;
	switch (EVP_PKEY_type(pkey->type)) {
#ifndef OPENSSL_NO_RSA
		case EVP_PKEY_RSA:

		if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;

		p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
		p8->pkeyalg->parameter->type = V_ASN1_NULL;
		if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey,
					 &p8->pkey->value.octet_string)) {
			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
			PKCS8_PRIV_KEY_INFO_free (p8);
			return NULL;
		}
		break;
#endif
#ifndef OPENSSL_NO_DSA
		case EVP_PKEY_DSA:
		if(!dsa_pkey2pkcs8(p8, pkey)) {
			PKCS8_PRIV_KEY_INFO_free (p8);
			return NULL;
		}

		break;
#endif
#ifndef OPENSSL_NO_EC
		case EVP_PKEY_EC:
		if (!eckey_pkey2pkcs8(p8, pkey))
		{
			PKCS8_PRIV_KEY_INFO_free(p8);
			return(NULL);
		}
		break;
#endif
		default:
		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
		PKCS8_PRIV_KEY_INFO_free (p8);
		return NULL;
	}
	RAND_add(p8->pkey->value.octet_string->data,
		 p8->pkey->value.octet_string->length, 0.0);
	return p8;
}
示例#17
0
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
                          const EVP_MD *dgst)
{
    int nid;
    char is_dsa;

    if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
        is_dsa = 1;
    else
        is_dsa = 0;
    /* We now need to add another PKCS7_SIGNER_INFO entry */
    if (!ASN1_INTEGER_set(p7i->version, 1))
        goto err;
    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
                       X509_get_issuer_name(x509)))
        goto err;

    /*
     * because ASN1_INTEGER_set is used to set a 'long' we will do things the
     * ugly way.
     */
    M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
    if (!(p7i->issuer_and_serial->serial =
          M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
        goto err;

    /* lets keep the pkey around for a while */
    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
    p7i->pkey = pkey;

    /* Set the algorithms */
    if (is_dsa)
        p7i->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
    else
        p7i->digest_alg->algorithm = OBJ_nid2obj(EVP_MD_type(dgst));

    if (p7i->digest_alg->parameter != NULL)
        ASN1_TYPE_free(p7i->digest_alg->parameter);
    if ((p7i->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    p7i->digest_alg->parameter->type = V_ASN1_NULL;

    if (p7i->digest_enc_alg->parameter != NULL)
        ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
    nid = EVP_PKEY_type(pkey->type);
    if (nid == EVP_PKEY_RSA) {
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
        if (!(p7i->digest_enc_alg->parameter = ASN1_TYPE_new()))
            goto err;
        p7i->digest_enc_alg->parameter->type = V_ASN1_NULL;
    } else if (nid == EVP_PKEY_DSA) {
#if 1
        /*
         * use 'dsaEncryption' OID for compatibility with other software
         * (PKCS #7 v1.5 does specify how to handle DSA) ...
         */
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_dsa);
#else
        /*
         * ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for
         * CMS) would make more sense.
         */
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_dsaWithSHA1);
#endif
        p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit
                                                * 'parameter'! */
    } else if (nid == EVP_PKEY_EC) {
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA1);
        if (!(p7i->digest_enc_alg->parameter = ASN1_TYPE_new()))
            goto err;
        p7i->digest_enc_alg->parameter->type = V_ASN1_NULL;
    } else
        return (0);

    return (1);
 err:
    return (0);
}
示例#18
0
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
	ASN1_STRING *params = NULL;
	ASN1_INTEGER *prkey = NULL;
	ASN1_TYPE *ttmp = NULL;
	STACK_OF(ASN1_TYPE) *ndsa = NULL;
	unsigned char *p = NULL, *q;
	int len;

	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
	len = i2d_DSAparams (pkey->pkey.dsa, NULL);
	if (!(p = OPENSSL_malloc(len))) {
		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
		goto err;
	}
	q = p;
	i2d_DSAparams (pkey->pkey.dsa, &q);
	if (!(params = ASN1_STRING_new())) {
		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!ASN1_STRING_set(params, p, len)) {
		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
		goto err;
	}
	OPENSSL_free(p);
	p = NULL;
	/* Get private key into integer */
	if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
		EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
		goto err;
	}

	switch(p8->broken) {

		case PKCS8_OK:
		case PKCS8_NO_OCTET:

		if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
					 &p8->pkey->value.octet_string)) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}

		M_ASN1_INTEGER_free (prkey);
		prkey = NULL;
		p8->pkeyalg->parameter->value.sequence = params;
		params = NULL;
		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;

		break;

		case PKCS8_NS_DB:

		p8->pkeyalg->parameter->value.sequence = params;
		params = NULL;
		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
		if (!(ndsa = sk_ASN1_TYPE_new_null())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		if (!(ttmp = ASN1_TYPE_new())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		if (!(ttmp->value.integer =
			BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
			goto err;
		}
		ttmp->type = V_ASN1_INTEGER;
		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}

		if (!(ttmp = ASN1_TYPE_new())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		ttmp->value.integer = prkey;
		prkey = NULL;
		ttmp->type = V_ASN1_INTEGER;
		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		ttmp = NULL;

		if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}

		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
					 &p8->pkey->value.octet_string->data,
					 &p8->pkey->value.octet_string->length)) {

			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
		break;

		case PKCS8_EMBEDDED_PARAM:

		p8->pkeyalg->parameter->type = V_ASN1_NULL;
		if (!(ndsa = sk_ASN1_TYPE_new_null())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		if (!(ttmp = ASN1_TYPE_new())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		ttmp->value.sequence = params;
		params = NULL;
		ttmp->type = V_ASN1_SEQUENCE;
		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}

		if (!(ttmp = ASN1_TYPE_new())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		ttmp->value.integer = prkey;
		prkey = NULL;
		ttmp->type = V_ASN1_INTEGER;
		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		ttmp = NULL;

		if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}

		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
					 &p8->pkey->value.octet_string->data,
					 &p8->pkey->value.octet_string->length)) {

			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
		break;
	}
	return 1;
err:
	if (p != NULL) OPENSSL_free(p);
	if (params != NULL) ASN1_STRING_free(params);
	if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
	if (ttmp != NULL) ASN1_TYPE_free(ttmp);
	if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
	return 0;
}
示例#19
0
int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it)
{
	ASN1_VALUE **opval = NULL;
	ASN1_STRING *stmp;
	ASN1_TYPE *typ = NULL;
	int ret = 0;
	const ASN1_PRIMITIVE_FUNCS *pf;
	ASN1_INTEGER **tint;
	pf = it->funcs;
	if(pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
	/* If ANY type clear type and set pointer to internal value */
	if(it->utype == V_ASN1_ANY) {
		if(!*pval) {
			typ = ASN1_TYPE_new();
			*pval = (ASN1_VALUE *)typ;
		} else typ = (ASN1_TYPE *)*pval;
		if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL);
		opval = pval;
		pval = (ASN1_VALUE **)&typ->value.ptr;
	}
	switch(utype) {
		case V_ASN1_OBJECT:
		if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err;
		break;

		case V_ASN1_NULL:
		if(len) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH);
			goto err;
		}
		*pval = (ASN1_VALUE *)1;
		break;

		case V_ASN1_BOOLEAN:
		if(len != 1) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
			goto err;
		} else {
			ASN1_BOOLEAN *tbool;
			tbool = (ASN1_BOOLEAN *)pval;
			*tbool = *cont;
		}
		break;

		case V_ASN1_BIT_STRING:
		if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err;
		break;

		case V_ASN1_INTEGER:
		case V_ASN1_NEG_INTEGER:
		case V_ASN1_ENUMERATED:
		case V_ASN1_NEG_ENUMERATED:
		tint = (ASN1_INTEGER **)pval;
		if(!c2i_ASN1_INTEGER(tint, &cont, len)) goto err;
		/* Fixup type to match the expected form */
		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
		break;

		case V_ASN1_OCTET_STRING:
		case V_ASN1_NUMERICSTRING:
		case V_ASN1_PRINTABLESTRING:
		case V_ASN1_T61STRING:
		case V_ASN1_VIDEOTEXSTRING:
		case V_ASN1_IA5STRING:
		case V_ASN1_UTCTIME:
		case V_ASN1_GENERALIZEDTIME:
		case V_ASN1_GRAPHICSTRING:
		case V_ASN1_VISIBLESTRING:
		case V_ASN1_GENERALSTRING:
		case V_ASN1_UNIVERSALSTRING:
		case V_ASN1_BMPSTRING:
		case V_ASN1_UTF8STRING:
		case V_ASN1_OTHER:
		case V_ASN1_SET:
		case V_ASN1_SEQUENCE:
		default:
		/* All based on ASN1_STRING and handled the same */
		if(!*pval) {
			stmp = ASN1_STRING_type_new(utype);
			if(!stmp) {
				ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
				goto err;
			}
			*pval = (ASN1_VALUE *)stmp;
		} else {
			stmp = (ASN1_STRING *)*pval;
			stmp->type = utype;
		}
		/* If we've already allocated a buffer use it */
		if(*free_cont) {
			if(stmp->data) OPENSSL_free(stmp->data);
			stmp->data = cont;
			stmp->length = len;
			*free_cont = 0;
		} else {
			if(!ASN1_STRING_set(stmp, cont, len)) {
				ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
				ASN1_STRING_free(stmp);	
				*pval = NULL;
				goto err;
			}
		}
		break;
	}
	/* If ASN1_ANY and NULL type fix up value */
	if(typ && utype==V_ASN1_NULL) typ->value.ptr = NULL;

	ret = 1;
	err:
	if(!ret)
		{
		ASN1_TYPE_free(typ);
		if (opval)
			*opval = NULL;
		}
	return ret;
}
示例#20
0
static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
	EC_KEY		*ec_key;
	const EC_GROUP  *group;
	unsigned char	*p, *pp;
	int 		nid, i, ret = 0;
	unsigned int    tmp_flags, old_flags;

	ec_key = pkey->pkey.ec;
	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
	{
		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
		return 0;
	}

	/* set the ec parameters OID */
	if (p8->pkeyalg->algorithm)
		ASN1_OBJECT_free(p8->pkeyalg->algorithm);

	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);

	/* set the ec parameters */

	if (p8->pkeyalg->parameter)
	{
		ASN1_TYPE_free(p8->pkeyalg->parameter);
		p8->pkeyalg->parameter = NULL;
	}

	if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
	{
		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	
	if (EC_GROUP_get_asn1_flag(group)
                     && (nid = EC_GROUP_get_curve_name(group)))
	{
		/* we have a 'named curve' => just set the OID */
		p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
		p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
	}
	else	/* explicit parameters */
	{
		if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
		{
			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
			return 0;
		}
		if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
		{
			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
			return 0;
		}	
		pp = p;
		if (!i2d_ECParameters(ec_key, &pp))
		{
			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
			OPENSSL_free(p);
			return 0;
		}
		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
		if ((p8->pkeyalg->parameter->value.sequence 
			= ASN1_STRING_new()) == NULL)
		{
			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
			OPENSSL_free(p);
			return 0;
		}
		ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
		OPENSSL_free(p);
	}

	/* set the private key */

	/* do not include the parameters in the SEC1 private key
	 * see PKCS#11 12.11 */
	old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
	EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
	i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
	if (!i)
	{
		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
		return 0;
	}
	p = (unsigned char *) OPENSSL_malloc(i);
	if (!p)
	{
		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	pp = p;
	if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
	{
		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
		OPENSSL_free(p);
		return 0;
	}
	/* restore old encoding flags */
	EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);

	switch(p8->broken) {

		case PKCS8_OK:
		p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
		if (!p8->pkey->value.octet_string ||
		    !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
		    (const void *)p, i))

		{
			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
		}
		else
			ret = 1;
		break;
		case PKCS8_NO_OCTET:		/* RSA specific */
		case PKCS8_NS_DB:		/* DSA specific */
		case PKCS8_EMBEDDED_PARAM:	/* DSA specific */
		default:
			EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
	}
	OPENSSL_cleanse(p, (size_t)i);
	OPENSSL_free(p);
	return ret;
}
示例#21
0
文件: ec_ameth.c 项目: 0culus/openssl
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
	{
	EVP_PKEY_CTX *pctx;
	EVP_PKEY *pkey;
	EVP_CIPHER_CTX *ctx;
	int keylen;
	X509_ALGOR *talg, *wrap_alg = NULL;
	ASN1_OBJECT *aoid;
	ASN1_BIT_STRING *pubkey;
	ASN1_STRING *wrap_str;
	ASN1_OCTET_STRING *ukm;
	unsigned char *penc = NULL;
	int penclen;
	int rv = 0;
	int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
	const EVP_MD *kdf_md;
	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
	if (!pctx)
		return 0;
	/* Get ephemeral key */
	pkey = EVP_PKEY_CTX_get0_pkey(pctx);
	if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
							NULL, NULL, NULL))
		goto err;
	X509_ALGOR_get0(&aoid, NULL, NULL, talg);
	/* Is everything uninitialised? */
	if (aoid == OBJ_nid2obj(NID_undef))
		{

		EC_KEY *eckey = pkey->pkey.ec;
		/* Set the key */
		unsigned char *p;

		penclen = i2o_ECPublicKey(eckey, NULL);
		if (penclen <= 0)
			goto err;
		penc = OPENSSL_malloc(penclen);
		if (!penc)
			goto err;
		p = penc;
		penclen = i2o_ECPublicKey(eckey, &p);
		if (penclen <= 0)
			goto err;
		ASN1_STRING_set0(pubkey, penc, penclen);
		pubkey->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
		pubkey->flags|=ASN1_STRING_FLAG_BITS_LEFT;

		penc = NULL;
		X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
							V_ASN1_UNDEF, NULL);
		}

	/* See if custom paraneters set */
	kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
	if (kdf_type <= 0)
		goto err;
	if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
		goto err;
	ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
	if (ecdh_nid < 0)
		goto err;
	else if (ecdh_nid == 0)
		ecdh_nid = NID_dh_std_kdf;
	else if (ecdh_nid == 1)
		ecdh_nid = NID_dh_cofactor_kdf;

	if (kdf_type == EVP_PKEY_ECDH_KDF_NONE)
		{
		kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
		if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
			goto err;
		}
	else
		/* Uknown KDF */
		goto err;
	if (kdf_md == NULL)
		{
		/* Fixme later for better MD */
		kdf_md = EVP_sha1();
		if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
			goto err;
		}

	if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
		goto err;

	/* Lookup NID for KDF+cofactor+digest */

	if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
		goto err;
	/* Get wrap NID */
	ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
	wrap_nid = EVP_CIPHER_CTX_type(ctx);
	keylen = EVP_CIPHER_CTX_key_length(ctx);

	/* Package wrap algorithm in an AlgorithmIdentifier */

	wrap_alg = X509_ALGOR_new();
	if (!wrap_alg)
		goto err;
	wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
	wrap_alg->parameter = ASN1_TYPE_new();
	if (!wrap_alg->parameter)
		goto err;
	if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
		goto err;
	if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef)
		{
		ASN1_TYPE_free(wrap_alg->parameter);
		wrap_alg->parameter = NULL;
		}

	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
		goto err;

	penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);

	if (!penclen)
		goto err;

	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
		goto err;
	penc = NULL;

	/* Now need to wrap encoding of wrap AlgorithmIdentifier into
	 * parameter of another AlgorithmIdentifier.
	 */
	penclen = i2d_X509_ALGOR(wrap_alg, &penc);
	if (!penc || !penclen)
		goto err;
	wrap_str = ASN1_STRING_new();
	if (!wrap_str)
		goto err;
	ASN1_STRING_set0(wrap_str, penc, penclen);
	penc = NULL;
	X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);

	rv = 1;

	err:
	if (penc)
		OPENSSL_free(penc);
	if (wrap_alg)
		X509_ALGOR_free(wrap_alg);
	return rv;
	}
示例#22
0
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
    int i;
    BIO *out = NULL, *btmp = NULL;
    X509_ALGOR *xa = NULL;
    const EVP_CIPHER *evp_cipher = NULL;
    STACK_OF(X509_ALGOR) *md_sk = NULL;
    STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
    X509_ALGOR *xalg = NULL;
    PKCS7_RECIP_INFO *ri = NULL;
    ASN1_OCTET_STRING *os = NULL;
    
    if (p7 == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
        return NULL;
    }
    /*
     * The content field in the PKCS7 ContentInfo is optional, but that really
     * only applies to inner content (precisely, detached signatures).
     *
     * When reading content, missing outer content is therefore treated as an
     * error.
     *
     * When creating content, PKCS7_content_new() must be called before
     * calling this method, so a NULL p7->d is always an error.
     */
    if (p7->d.ptr == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
        return NULL;
    }

    i = OBJ_obj2nid(p7->type);
    p7->state = PKCS7_S_HEADER;

    switch (i) {
        case NID_pkcs7_signed:
            md_sk = p7->d.sign->md_algs;
            os = PKCS7_get_octet_string(p7->d.sign->contents);
            break;
        case NID_pkcs7_signedAndEnveloped:
            rsk = p7->d.signed_and_enveloped->recipientinfo;
            md_sk = p7->d.signed_and_enveloped->md_algs;
            xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
            evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
            if (evp_cipher == NULL) {
                PKCS7err(PKCS7_F_PKCS7_DATAINIT,
                         PKCS7_R_CIPHER_NOT_INITIALIZED);
                goto err;
            }
            break;
        case NID_pkcs7_enveloped:
            rsk = p7->d.enveloped->recipientinfo;
            xalg = p7->d.enveloped->enc_data->algorithm;
            evp_cipher = p7->d.enveloped->enc_data->cipher;
            if (evp_cipher == NULL) {
                PKCS7err(PKCS7_F_PKCS7_DATAINIT,
                         PKCS7_R_CIPHER_NOT_INITIALIZED);
                goto err;
            }
            break;
        case NID_pkcs7_digest:
            xa = p7->d.digest->md;
            os = PKCS7_get_octet_string(p7->d.digest->contents);
            break;
        case NID_pkcs7_data:
            break;
        default:
            PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
            goto err;
    }

    for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
        if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
            goto err;

    if (xa && !PKCS7_bio_add_digest(&out, xa))
        goto err;

    if (evp_cipher != NULL) {
        uint8_t key[EVP_MAX_KEY_LENGTH];
        uint8_t iv[EVP_MAX_IV_LENGTH];
        int keylen, ivlen;
        EVP_CIPHER_CTX *ctx;

        if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
            PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
            goto err;
        }
        BIO_get_cipher_ctx(btmp, &ctx);
        keylen = EVP_CIPHER_key_length(evp_cipher);
        ivlen = EVP_CIPHER_iv_length(evp_cipher);
        xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
        if (ivlen > 0)
            if (RAND_bytes(iv, ivlen) <= 0)
                goto err;
        if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
            goto err;
        if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
            goto err;
        if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
            goto err;

        if (ivlen > 0) {
            if (xalg->parameter == NULL) {
                xalg->parameter = ASN1_TYPE_new();
                if (xalg->parameter == NULL)
                    goto err;
            }
            if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
                goto err;
        }

        /* Lets do the pub key stuff :-) */
        for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
            ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
            if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
                goto err;
        }
        vigortls_zeroize(key, keylen);

        if (out == NULL)
            out = btmp;
        else
            BIO_push(out, btmp);
        btmp = NULL;
    }

    if (bio == NULL) {
        if (PKCS7_is_detached(p7))
            bio = BIO_new(BIO_s_null());
        else if (os && os->length > 0)
            bio = BIO_new_mem_buf(os->data, os->length);
        if (bio == NULL) {
            bio = BIO_new(BIO_s_mem());
            if (bio == NULL)
                goto err;
            BIO_set_mem_eof_return(bio, 0);
        }
    }
    if (out)
        BIO_push(out, bio);
    else
        out = bio;
    bio = NULL;
    if (0) {
    err:
        if (out != NULL)
            BIO_free_all(out);
        if (btmp != NULL)
            BIO_free_all(btmp);
        out = NULL;
    }
    return (out);
}
示例#23
0
文件: a_sign.c 项目: 1310701102/sl4a
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
	      ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
	      const EVP_MD *type)
	{
	EVP_MD_CTX ctx;
	unsigned char *p,*buf_in=NULL,*buf_out=NULL;
	int i,inl=0,outl=0,outll=0;
	X509_ALGOR *a;

	EVP_MD_CTX_init(&ctx);
	for (i=0; i<2; i++)
		{
		if (i == 0)
			a=algor1;
		else
			a=algor2;
		if (a == NULL) continue;
                if (type->pkey_type == NID_dsaWithSHA1)
			{
			/* special case: RFC 2459 tells us to omit 'parameters'
			 * with id-dsa-with-sha1 */
			ASN1_TYPE_free(a->parameter);
			a->parameter = NULL;
			}
		else if ((a->parameter == NULL) || 
			(a->parameter->type != V_ASN1_NULL))
			{
			ASN1_TYPE_free(a->parameter);
			if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
			a->parameter->type=V_ASN1_NULL;
			}
		ASN1_OBJECT_free(a->algorithm);
		a->algorithm=OBJ_nid2obj(type->pkey_type);
		if (a->algorithm == NULL)
			{
			ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
			goto err;
			}
		if (a->algorithm->length == 0)
			{
			ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
			goto err;
			}
		}
	inl=i2d(data,NULL);
	buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
	outll=outl=EVP_PKEY_size(pkey);
	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
	if ((buf_in == NULL) || (buf_out == NULL))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=buf_in;

	i2d(data,&p);
	EVP_SignInit_ex(&ctx,type, NULL);
	EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
	if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
			(unsigned int *)&outl,pkey))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
		goto err;
		}
	if (signature->data != NULL) OPENSSL_free(signature->data);
	signature->data=buf_out;
	buf_out=NULL;
	signature->length=outl;
	/* In the interests of compatibility, I'll make sure that
	 * the bit string has a 'not-used bits' value of 0
	 */
	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
	EVP_MD_CTX_cleanup(&ctx);
	if (buf_in != NULL)
		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
	if (buf_out != NULL)
		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
	return(outl);
	}
示例#24
0
文件: p5_scrypt.c 项目: 1234-/openssl
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
                                  const unsigned char *salt, int saltlen,
                                  unsigned char *aiv, uint64_t N, uint64_t r,
                                  uint64_t p)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid;
    size_t keylen = 0;
    EVP_CIPHER_CTX *ctx = NULL;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBE2PARAM *pbe2 = NULL;
    ASN1_OBJECT *obj;

    if (!cipher) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER);
        goto err;
    }

    if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
                ASN1_R_INVALID_SCRYPT_PARAMETERS);
        goto err;
    }

    alg_nid = EVP_CIPHER_type(cipher);
    if (alg_nid == NID_undef) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        goto err;
    }
    obj = OBJ_nid2obj(alg_nid);
    pbe2 = PBE2PARAM_new();
    if (pbe2 == NULL)
        goto merr;

    /* Setup the AlgorithmIdentifier for the encryption scheme */
    scheme = pbe2->encryption;

    scheme->algorithm = obj;
    scheme->parameter = ASN1_TYPE_new();
    if (scheme->parameter == NULL)
        goto merr;

    /* Create random IV */
    if (EVP_CIPHER_iv_length(cipher)) {
        if (aiv)
            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
            goto err;
    }

    ctx = EVP_CIPHER_CTX_new();
    if (ctx == NULL)
        goto merr;

    /* Dummy cipherinit to just setup the IV */
    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
                ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        goto err;
    }
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* If its RC2 then we'd better setup the key length */

    if (alg_nid == NID_rc2_cbc)
        keylen = EVP_CIPHER_key_length(cipher);

    /* Setup keyfunc */

    X509_ALGOR_free(pbe2->keyfunc);

    pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p);

    if (pbe2->keyfunc == NULL)
        goto merr;

    /* Now set up top level AlgorithmIdentifier */

    ret = X509_ALGOR_new();
    if (ret == NULL)
        goto merr;

    ret->algorithm = OBJ_nid2obj(NID_pbes2);

    /* Encode PBE2PARAM into parameter */

    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
                                &ret->parameter) == NULL)
        goto merr;

    PBE2PARAM_free(pbe2);
    pbe2 = NULL;

    return ret;

 merr:
    ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE);

 err:
    PBE2PARAM_free(pbe2);
    X509_ALGOR_free(kalg);
    X509_ALGOR_free(ret);
    EVP_CIPHER_CTX_free(ctx);

    return NULL;

}