void *value);
static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
+static int PKCS7_type_is_other(PKCS7* p7)
+ {
+ int isOther=1;
+
+ int nid=OBJ_obj2nid(p7->type);
+
+ switch( nid )
+ {
+ case NID_pkcs7_data:
+ case NID_pkcs7_signed:
+ case NID_pkcs7_enveloped:
+ case NID_pkcs7_signedAndEnveloped:
+ case NID_pkcs7_digest:
+ case NID_pkcs7_encrypted:
+ isOther=0;
+ break;
+ default:
+ isOther=1;
+ }
+
+ return isOther;
+
+ }
+
+static int PKCS7_type_is_octet_string(PKCS7* p7)
+ {
+ if ( 0==PKCS7_type_is_other(p7) )
+ return 0;
+
+ return (V_ASN1_OCTET_STRING==p7->d.other->type) ? 1 : 0;
+ }
+
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
int i,j;
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);
+ EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1);
if (ivlen > 0) {
if (xalg->parameter == NULL)
EVP_PKEY_free(pkey);
if (max < jj) max=jj;
}
- if ((tmp=(unsigned char *)Malloc(max)) == NULL)
+ if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
goto err;
if (jj <= 0)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
- Free(tmp);
+ OPENSSL_free(tmp);
goto err;
}
M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
}
- Free(tmp);
+ OPENSSL_free(tmp);
memset(key, 0, keylen);
if (out == NULL)
}
if (bio == NULL) {
- if (p7->detached)
+ if (PKCS7_is_detached(p7))
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 (PKCS7_type_is_signed(p7) ) {
+ if ( 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);
+ }
+ else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) {
+ ASN1_OCTET_STRING *os;
+ os=p7->d.sign->contents->d.other->value.octet_string;
+ 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);
if (ri == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
- return(NULL);
+ goto err;
}
jj=EVP_PKEY_size(pkey);
- tmp=(unsigned char *)Malloc(jj+10);
+ tmp=(unsigned char *)OPENSSL_malloc(jj+10);
if (tmp == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
evp_ctx=NULL;
BIO_get_cipher_ctx(etmp,&evp_ctx);
- EVP_CipherInit(evp_ctx,evp_cipher,NULL,NULL,0);
+ EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0);
if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
- return(NULL);
+ goto err;
if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
/* Some S/MIME clients don't use the same key
goto err;
}
}
- EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);
+ EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0);
memset(tmp,0,jj);
}
#if 1
- if (p7->detached || (in_bio != NULL))
+ if (PKCS7_is_detached(p7) || (in_bio != NULL))
{
bio=in_bio;
}
out=NULL;
}
if (tmp != NULL)
- Free(tmp);
+ OPENSSL_free(tmp);
return(out);
}
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);
BIO_get_md_ctx(btmp,&mdc);
if (mdc == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR);
+ PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
goto err;
}
if (EVP_MD_CTX_type(mdc) == j)
break;
else
- btmp=btmp->next_bio;
+ btmp=BIO_next(btmp);
}
/* We now have the EVP_MD_CTX, lets do the
* signing. */
- memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp));
+ EVP_MD_CTX_init(&ctx_tmp);
+ EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey)))
{
PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
* 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;
+ 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 */
- sign_time=X509_gmtime_adj(NULL,0);
- PKCS7_add_signed_attribute(si,
- NID_pkcs9_signingTime,
- V_ASN1_UTCTIME,sign_time);
+ /* Add signing time if not already present */
+ if (!PKCS7_get_signed_attribute(si,
+ NID_pkcs9_signingTime))
+ {
+ 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);
+ EVP_DigestFinal_ex(&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 *)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);
- Free(pp);
- pp=NULL;
+ /* 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
if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
(unsigned int *)&buf->length,si->pkey))
}
}
- if (!p7->detached)
+ if (!PKCS7_is_detached(p7))
{
btmp=BIO_find_type(bio,BIO_TYPE_MEM);
if (btmp == NULL)
(unsigned char *)buf_mem->data,buf_mem->length);
#endif
}
- if (pp != NULL) Free(pp);
- pp=NULL;
-
ret=1;
err:
+ EVP_MD_CTX_cleanup(&ctx_tmp);
if (buf != NULL) BUF_MEM_free(buf);
return(ret);
}
}
/* Lets verify */
- X509_STORE_CTX_init(ctx,cert_store,x509,cert);
+ if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
+ goto err;
+ }
X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
i=X509_verify_cert(ctx);
if (i <= 0)
{
ASN1_OCTET_STRING *os;
EVP_MD_CTX mdc_tmp,*mdc;
- unsigned char *pp,*p;
int ret=0,i;
int md_type;
STACK_OF(X509_ATTRIBUTE) *sk;
BIO *btmp;
EVP_PKEY *pkey;
+ EVP_MD_CTX_init(&mdc_tmp);
+
if (!PKCS7_type_is_signed(p7) &&
!PKCS7_type_is_signedAndEnveloped(p7)) {
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
if (mdc == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
- PKCS7_R_INTERNAL_ERROR);
+ ERR_R_INTERNAL_ERROR);
goto err;
}
if (EVP_MD_CTX_type(mdc) == md_type)
break;
- btmp=btmp->next_bio;
+ btmp=BIO_next(btmp);
}
/* mdc is the digest ctx that we want, unless there are attributes,
* in which case the digest is the signed attributes */
- memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp));
+ EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
sk=si->auth_attr;
if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
{
- unsigned char md_dat[EVP_MAX_MD_SIZE];
- unsigned int md_len;
+ unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
+ unsigned int md_len, alen;
ASN1_OCTET_STRING *message_digest;
- EVP_DigestFinal(&mdc_tmp,md_dat,&md_len);
+ EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
message_digest=PKCS7_digest_from_attributes(sk);
if (!message_digest)
{
goto err;
}
- EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type));
- /* Note: when forming the encoding of the attributes we
- * shouldn't reorder them or this will break the signature.
- * This is done by using the IS_SEQUENCE flag.
- */
- i=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,i2d_X509_ATTRIBUTE,
- V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
- pp=Malloc(i);
- p=pp;
- i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,i2d_X509_ATTRIBUTE,
- V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
- EVP_VerifyUpdate(&mdc_tmp,pp,i);
+ EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
+
+ alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
+ ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
+ EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
- Free(pp);
+ OPENSSL_free(abuf);
}
os=si->enc_digest;
pkey = X509_get_pubkey(x509);
+ if (!pkey)
+ {
+ ret = -1;
+ goto err;
+ }
+#ifndef OPENSSL_NO_DSA
if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
+#endif
i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
EVP_PKEY_free(pkey);
else
ret=1;
err:
+ EVP_MD_CTX_cleanup(&mdc_tmp);
return(ret);
}
xa=sk_X509_ATTRIBUTE_value(sk,i);
if (OBJ_cmp(xa->object,o) == 0)
{
- if (xa->set && sk_ASN1_TYPE_num(xa->value.set))
+ if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
return(sk_ASN1_TYPE_value(xa->value.set,0));
else
return(NULL);
if (*sk == NULL)
{
- *sk = sk_X509_ATTRIBUTE_new(NULL);
+ *sk = sk_X509_ATTRIBUTE_new_null();
new_attrib:
attr=X509_ATTRIBUTE_create(nid,atrtype,value);
sk_X509_ATTRIBUTE_push(*sk,attr);