Exemplo n.º 1
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;
}
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	ASN1_OCTET_STRING *os=NULL;

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

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		if (!(os=M_ASN1_OCTET_STRING_new()))
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		if (!(os=M_ASN1_OCTET_STRING_new()))
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=PKCS7_get_octet_string(p7->d.sign->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;

	case NID_pkcs7_digest:
		os=PKCS7_get_octet_string(p7->d.digest->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
			{
			M_ASN1_OCTET_STRING_free(os);
			p7->d.digest->contents->d.data = NULL;
			}
		break;

		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;

			btmp = PKCS7_find_digest(&mdc, btmp, j);

			if (btmp == NULL)
				goto err;

			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
			if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
				unsigned int md_len, alen;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time if not already present */
				if (!PKCS7_get_signed_attribute(si,
							NID_pkcs9_signingTime))
					{
					if (!(sign_time=X509_gmtime_adj(NULL,0)))
						{
						PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
							ERR_R_MALLOC_FAILURE);
						goto err;
						}
					PKCS7_add_signed_attribute(si,
						NID_pkcs9_signingTime,
						V_ASN1_UTCTIME,sign_time);
					}

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
				if (!(digest=M_ASN1_OCTET_STRING_new()))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
						ERR_R_MALLOC_FAILURE);
					goto err;
					}
				if (!M_ASN1_OCTET_STRING_set(digest,md_data,
								md_len))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
						ERR_R_MALLOC_FAILURE);
					goto err;
					}
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the attributes */
				EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
				alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
							ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
				if(!abuf) goto err;
				EVP_SignUpdate(&ctx_tmp,abuf,alen);
				OPENSSL_free(abuf);
				}

#ifndef OPENSSL_NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
 			if (si->pkey->type == EVP_PKEY_EC)
 				ctx_tmp.digest=EVP_ecdsa();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}
	else if (i == NID_pkcs7_digest)
		{
		unsigned char md_data[EVP_MAX_MD_SIZE];
		unsigned int md_len;
		if (!PKCS7_find_digest(&mdc, bio,
				OBJ_obj2nid(p7->d.digest->md->algorithm)))
			goto err;
		EVP_DigestFinal_ex(mdc,md_data,&md_len);
		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
		}

	if (!PKCS7_is_detached(p7))
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	ret=1;
err:
	EVP_MD_CTX_cleanup(&ctx_tmp);
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}
Exemplo n.º 3
0
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
{
    return M_ASN1_OCTET_STRING_set(x, d, len);
}
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;
	EVP_PKEY *pkey;
	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;
	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;
		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);
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
		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(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;
				}
			if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,
					ERR_R_MALLOC_FAILURE);
				OPENSSL_free(tmp);
				goto err;
				}
			}
		OPENSSL_free(tmp);
		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());
			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);
	}
Exemplo n.º 5
0
int
PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
{
	int ret = 0;
	int i, j;
	BIO *btmp;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc, ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
	ASN1_OCTET_STRING *os = NULL;

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

	switch (i) {
	case NID_pkcs7_data:
		os = p7->d.data;
		break;
	case NID_pkcs7_signedAndEnveloped:
		/* XXX */
		si_sk = p7->d.signed_and_enveloped->signer_info;
		os = p7->d.signed_and_enveloped->enc_data->enc_data;
		if (!os) {
			os = M_ASN1_OCTET_STRING_new();
			if (!os) {
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
				    ERR_R_MALLOC_FAILURE);
				goto err;
			}
			p7->d.signed_and_enveloped->enc_data->enc_data = os;
		}
		break;
	case NID_pkcs7_enveloped:
		/* XXX */
		os = p7->d.enveloped->enc_data->enc_data;
		if (!os) {
			os = M_ASN1_OCTET_STRING_new();
			if (!os) {
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
				    ERR_R_MALLOC_FAILURE);
				goto err;
			}
			p7->d.enveloped->enc_data->enc_data = os;
		}
		break;
	case NID_pkcs7_signed:
		si_sk = p7->d.sign->signer_info;
		os = PKCS7_get_octet_string(p7->d.sign->contents);
		if (!PKCS7_is_detached(p7) && os == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_DECODE_ERROR);
			goto err;
		}
		/* If detached data then the content is excluded */
		if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;

	case NID_pkcs7_digest:
		os = PKCS7_get_octet_string(p7->d.digest->contents);
		if (os == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_DECODE_ERROR);
			goto err;
		}
		/* If detached data then the content is excluded */
		if (PKCS7_type_is_data(p7->d.digest->contents) &&
		    p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.digest->contents->d.data = NULL;
		}
		break;

	default:
		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
		goto err;
	}

	if (si_sk != NULL) {
		for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
			si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
			if (si->pkey == NULL)
				continue;

			j = OBJ_obj2nid(si->digest_alg->algorithm);

			btmp = bio;

			btmp = PKCS7_find_digest(&mdc, btmp, j);

			if (btmp == NULL)
				goto err;

			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
				goto err;

			sk = si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if (sk_X509_ATTRIBUTE_num(sk) > 0) {
				if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
					goto err;
			} else {
				unsigned char *abuf = NULL;
				unsigned int abuflen;
				abuflen = EVP_PKEY_size(si->pkey);
				abuf = malloc(abuflen);
				if (!abuf)
					goto err;

				if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
				    si->pkey)) {
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
					    ERR_R_EVP_LIB);
					goto err;
				}
				ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
			}
		}
	} else if (i == NID_pkcs7_digest) {
		unsigned char md_data[EVP_MAX_MD_SIZE];
		unsigned int md_len;
		if (!PKCS7_find_digest(&mdc, bio,
		    OBJ_obj2nid(p7->d.digest->md->algorithm)))
			goto err;
		if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
			goto err;
		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
	}

	if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) {
		char *cont;
		long contlen;
		btmp = BIO_find_type(bio, BIO_TYPE_MEM);
		if (btmp == NULL) {
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
			    PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
		}
		contlen = BIO_get_mem_data(btmp, &cont);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
	}
	ret = 1;
err:
	EVP_MD_CTX_cleanup(&ctx_tmp);
	return (ret);
}
Exemplo n.º 6
0
static LUA_FUNCTION(openssl_pkcs7_sign_digest)
{
  PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7");
  size_t l;
  const char* data = luaL_checklstring(L, 2, &l);
  long flags = luaL_optint(L, 3, 0);
  int hash = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4);

  int ret = 0;
  int i, j;

  const EVP_MD* md;
  PKCS7_SIGNER_INFO *si;
  EVP_MD_CTX mdc;
  STACK_OF(X509_ATTRIBUTE) *sk;
  STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
  ASN1_OCTET_STRING *os = NULL;

  if (p7->d.ptr == NULL)
  {
    luaL_error(L, "pkcs7 without content");
    return 0;
  }

  flags |= PKCS7_DETACHED;
  PKCS7_set_detached(p7, 1);

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

  switch (i)
  {
  case NID_pkcs7_data:
    os = p7->d.data;
    break;
  case NID_pkcs7_signedAndEnveloped:
    /* XXXXXXXXXXXXXXXX */
    si_sk = p7->d.signed_and_enveloped->signer_info;
    os = p7->d.signed_and_enveloped->enc_data->enc_data;
    if (!os)
    {
      os = M_ASN1_OCTET_STRING_new();
      if (!os)
      {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      p7->d.signed_and_enveloped->enc_data->enc_data = os;
    }
    break;
  case NID_pkcs7_enveloped:
    /* XXXXXXXXXXXXXXXX */
    os = p7->d.enveloped->enc_data->enc_data;
    if (!os)
    {
      os = M_ASN1_OCTET_STRING_new();
      if (!os)
      {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      p7->d.enveloped->enc_data->enc_data = os;
    }
    break;
  case NID_pkcs7_signed:
    si_sk = p7->d.sign->signer_info;
    os = PKCS7_get_octet_string(p7->d.sign->contents);
    /* If detached data then the content is excluded */
    if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached)
    {
      M_ASN1_OCTET_STRING_free(os);
      os = NULL;
      p7->d.sign->contents->d.data = NULL;
    }
    break;

  case NID_pkcs7_digest:
    os = PKCS7_get_octet_string(p7->d.digest->contents);
    /* If detached data then the content is excluded */
    if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
    {
      M_ASN1_OCTET_STRING_free(os);
      os = NULL;
      p7->d.digest->contents->d.data = NULL;
    }
    break;

  default:
    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
    goto err;
  }

  if (si_sk != NULL)
  {
    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
    {
      si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
      if (si->pkey == NULL)
        continue;
      j = OBJ_obj2nid(si->digest_alg->algorithm);
      md = EVP_get_digestbynid(j);
      EVP_DigestInit_ex(&mdc, md, NULL);

      if (hash)
      {
        if (l == (size_t) mdc.digest->ctx_size)
        {
          memcpy(mdc.md_data, data, l);
        }
        else
        {
          EVP_MD_CTX_cleanup(&mdc);
          luaL_argerror(L, 2, "data with wrong length");
        }
      }
      else
        EVP_DigestUpdate(&mdc, data, l);

      sk = si->auth_attr;

      /*
      * If there are attributes, we add the digest attribute and only
      * sign the attributes
      */
      if (sk_X509_ATTRIBUTE_num(sk) > 0)
      {
        if (!do_pkcs7_signed_attrib(si, &mdc))
          goto err;
      }
      else
      {
        unsigned char *abuf = NULL;
        unsigned int abuflen;
        abuflen = EVP_PKEY_size(si->pkey);
        abuf = OPENSSL_malloc(abuflen);
        if (!abuf)
          goto err;

        if (!EVP_SignFinal(&mdc, abuf, &abuflen, si->pkey))
        {
          PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
          goto err;
        }
        ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
      }
    }
  }
  else if (i == NID_pkcs7_digest)
  {
    unsigned char md_data[EVP_MAX_MD_SIZE];
    unsigned int md_len;
    md = EVP_get_digestbynid(OBJ_obj2nid(p7->d.digest->md->algorithm));
    EVP_DigestInit_ex(&mdc, md, NULL);
    if (l == (size_t) mdc.digest->ctx_size)
    {
      memcpy(mdc.md_data, data, l);
    }
    else
    {
      EVP_MD_CTX_cleanup(&mdc);
      luaL_error(L, "data with wrong data");
    }
    if (!EVP_DigestFinal_ex(&mdc, md_data, &md_len))
      goto err;
    M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
  }

  if (!PKCS7_is_detached(p7))
  {
    /*
    * NOTE(emilia): I think we only reach os == NULL here because detached
    * digested data support is broken.
    */
    if (os == NULL)
      goto err;
    if (!(os->flags & ASN1_STRING_FLAG_NDEF))
    {
      char *cont = memdup(data, l);
      long contlen = l;
      ASN1_STRING_set0(os, (unsigned char *) cont, contlen);
    }
  }

  ret = 1;
err:
  EVP_MD_CTX_cleanup(&mdc);
  return openssl_pushresult(L, ret);
}
Exemplo n.º 7
0
static BIGN_ECPARAMS* bign_asn1_params2ecp(BIGN_ECPARAMS* ecp, 
	const bign_params* params)
{
	int	ok = 0;
	BIGN_ECPARAMS* ret = ecp;
	BIGNUM* order = NULL;
	octet rev[64];
	// ������� ��������
	if (!params)
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}
	// ����������� �������
	if (!ret && !(ret = BIGN_ECPARAMS_new()))
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	// ���������� ������ (������ 1)
	ret->version = (long)1;
	// ���������� fieldID
	if (!bign_asn1_params2fieldid(ret->fieldID, params))
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_EC_LIB);
		goto err;
	}
	// ���������� ������
	if (!bign_asn1_params2curve(ret->curve, params))
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_EC_LIB);
		goto err;
	}
	
	// ���������� ������� �����
	if (!M_ASN1_OCTET_STRING_set(ret->base, params->yG, params->l / 4))
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_ASN1_LIB);
		goto err;
	}
	// ���������� �������
	memCopy(rev, params->q, params->l / 4);
	memRev(rev, params->l / 4);
	if (!(order = BN_new()) || !BN_bin2bn(rev, params->l / 4, order))
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	ret->order = BN_to_ASN1_INTEGER(order, NULL);
	if (!ret->order)
	{
		BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_ASN1_LIB);
		goto err;
	}
	// ���������� �������� (optional, ������ 1)
	//if (!ASN1_INTEGER_set(ret->cofactor, (long)1))
	//{
	//	BEE2EVPerr(BEE2EVP_F_BIGN_ASN1_PARAMS2ECP, ERR_R_ASN1_LIB);
	//	goto err;
	//}
	ok = 1;

err:	
	if (!ok)
	{
		if (ret && !ecp)
			BIGN_ECPARAMS_free(ret);
		ret = NULL;
	}
	order ? BN_free(order) : 0;
	memSetZero(rev, sizeof(rev));
	return ret;
}
Exemplo n.º 8
0
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	unsigned char *p,*pp=NULL;
	int x;
	ASN1_OCTET_STRING *os=NULL;

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

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		os=M_ASN1_OCTET_STRING_new();
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		os=M_ASN1_OCTET_STRING_new();
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=p7->d.sign->contents->d.data;
		/* If detached data then the content is excluded */
		if(p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;
		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;
			for (;;)
				{
				if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) 
					== NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
					goto err;
					}
				BIO_get_md_ctx(btmp,&mdc);
				if (mdc == NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR);
					goto err;
					}
				if (EVP_MD_CTX_type(mdc) == j)
					break;
				else
					btmp=BIO_next(btmp);
				}
			
			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp));
			if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE];
				unsigned int md_len;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time */
				sign_time=X509_gmtime_adj(NULL,0);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_signingTime,
					V_ASN1_UTCTIME,sign_time);

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal(&ctx_tmp,md_data,&md_len);
				digest=M_ASN1_OCTET_STRING_new();
				M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the mess */
				EVP_SignInit(&ctx_tmp,md_tmp);
				x=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,
					   i2d_X509_ATTRIBUTE,
					   V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
				pp=(unsigned char *)OPENSSL_malloc(x);
				p=pp;
				i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,
				           i2d_X509_ATTRIBUTE,
					   V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
				EVP_SignUpdate(&ctx_tmp,pp,x);
				OPENSSL_free(pp);
				pp=NULL;
				}

#ifndef NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}

	if (!p7->detached)
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	if (pp != NULL) OPENSSL_free(pp);
	pp=NULL;

	ret=1;
err:
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}