#include <stdio.h>
#include "cryptlib.h"
-#include "rand.h"
-#include "objects.h"
-#include "x509.h"
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
-static int add_attribute(STACK **sk, int nid, int atrtype, char *value);
+static int add_attribute(STACK **sk, int nid, int atrtype, void *value);
static ASN1_TYPE *get_attribute(STACK *sk, int nid);
-#if 1
-BIO *PKCS7_dataInit(p7,bio)
-PKCS7 *p7;
-BIO *bio;
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
int i,j;
BIO *out=NULL,*btmp=NULL;
X509_ALGOR *xa;
- EVP_MD *evp_md;
- EVP_CIPHER *evp_cipher=NULL;
+ const EVP_MD *evp_md;
+ const EVP_CIPHER *evp_cipher=NULL;
STACK *md_sk=NULL,*rsk=NULL;
X509_ALGOR *xalg=NULL;
PKCS7_RECIP_INFO *ri=NULL;
keylen=EVP_CIPHER_key_length(evp_cipher);
ivlen=EVP_CIPHER_iv_length(evp_cipher);
- if (ivlen > 0)
- {
- ASN1_OCTET_STRING *os;
-
- RAND_bytes(iv,ivlen);
- os=ASN1_OCTET_STRING_new();
- ASN1_OCTET_STRING_set(os,iv,ivlen);
-/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX this needs to change */
- if (xalg->parameter == NULL)
- xalg->parameter=ASN1_TYPE_new();
- ASN1_TYPE_set(xalg->parameter,V_ASN1_OCTET_STRING,
- (char *)os);
- }
+ if (ivlen > 0) {
+ EVP_CIPHER_CTX *ctx;
+ BIO_get_cipher_ctx(btmp, &ctx);
+ if (xalg->parameter == NULL)
+ xalg->parameter=ASN1_TYPE_new();
+ if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
+ goto err;
+ }
RAND_bytes(key,keylen);
/* Lets do the pub key stuff :-) */
}
pkey=X509_get_pubkey(ri->cert);
jj=EVP_PKEY_size(pkey);
+ EVP_PKEY_free(pkey);
if (max < jj) max=jj;
}
if ((tmp=(unsigned char *)Malloc(max)) == NULL)
ri=(PKCS7_RECIP_INFO *)sk_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);
}
/* int */
-BIO *PKCS7_dataDecode(p7,pkey,in_bio,xs)
-PKCS7 *p7;
-EVP_PKEY *pkey;
-BIO *in_bio;
-X509_STORE *xs;
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
+ X509_STORE *xs)
{
int i,j;
BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
char *tmp=NULL;
X509_ALGOR *xa;
ASN1_OCTET_STRING *data_body=NULL;
- EVP_MD *evp_md;
- EVP_CIPHER *evp_cipher=NULL;
+ const EVP_MD *evp_md;
+ const EVP_CIPHER *evp_cipher=NULL;
EVP_CIPHER_CTX *evp_ctx=NULL;
X509_ALGOR *enc_alg=NULL;
STACK *md_sk=NULL,*rsk=NULL;
if (rsk == NULL)
return(NULL);
+ /* FIXME: this assumes that the passed private key
+ * corresponds to the first RecipientInfo. This in
+ * general is not true
+ */
+
ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0);
#if 0
X509_STORE_CTX_init(&s_ctx,xs,NULL,NULL);
Free(tmp);
return(out);
}
-#endif
-int PKCS7_dataFinal(p7,bio)
-PKCS7 *p7;
-BIO *bio;
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
{
int ret=0;
int i,j;
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) {
+ ASN1_OCTET_STRING_free(os);
+ p7->d.sign->contents->d.data = NULL;
+ }
break;
}
unsigned int md_len;
ASN1_OCTET_STRING *digest;
ASN1_UTCTIME *sign_time;
- EVP_MD *md_tmp;
+ 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,(char *)sign_time);
+ V_ASN1_UTCTIME,sign_time);
/* Add digest */
md_tmp=EVP_MD_CTX_type(&ctx_tmp);
EVP_DigestFinal(&ctx_tmp,md_data,&md_len);
digest=ASN1_OCTET_STRING_new();
ASN1_OCTET_STRING_set(digest,md_data,md_len);
- PKCS7_add_signed_attribute(si,NID_pkcs9_messageDigest,
- V_ASN1_OCTET_STRING,(char *)digest);
+ 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(sk,NULL,i2d_X509_ATTRIBUTE,
- V_ASN1_SET,V_ASN1_UNIVERSAL);
+ V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);
pp=(unsigned char *)Malloc(x);
p=pp;
i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,
- V_ASN1_SET,V_ASN1_UNIVERSAL);
+ V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET);
EVP_SignUpdate(&ctx_tmp,pp,x);
Free(pp);
pp=NULL;
}
}
- if (p7->detached)
- ASN1_OCTET_STRING_set(os,(unsigned char *)"",0);
- else
+ if (!p7->detached)
{
btmp=BIO_find_type(bio,BIO_TYPE_MEM);
if (btmp == NULL)
return(ret);
}
-int PKCS7_dataVerify(cert_store,ctx,bio,p7,si)
-X509_STORE *cert_store;
-X509_STORE_CTX *ctx;
-BIO *bio;
-PKCS7 *p7;
-PKCS7_SIGNER_INFO *si;
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
+ PKCS7 *p7, PKCS7_SIGNER_INFO *si)
{
/* PKCS7_SIGNED *s; */
ASN1_OCTET_STRING *os;
PKCS7_ISSUER_AND_SERIAL *ias;
int ret=0,i;
int md_type;
- STACK *sk,*cert;
+ STACK *sk;
+ STACK_OF(X509) *cert;
BIO *btmp;
X509 *x509;
+ EVP_PKEY *pkey;
if (PKCS7_type_is_signed(p7))
{
if ((sk != NULL) && (sk_num(sk) != 0))
{
unsigned char md_dat[EVP_MAX_MD_SIZE];
- int md_len;
+ unsigned int md_len;
ASN1_OCTET_STRING *message_digest;
EVP_DigestFinal(&mdc_tmp,md_dat,&md_len);
PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
goto err;
}
- if ((message_digest->length != md_len) ||
+ if ((message_digest->length != (int)md_len) ||
(memcmp(message_digest->data,md_dat,md_len)))
{
#if 0
}
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(sk,NULL,i2d_X509_ATTRIBUTE,
- V_ASN1_SET,V_ASN1_UNIVERSAL);
+ V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
pp=(unsigned char *)Malloc(i);
p=pp;
i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,
- V_ASN1_SET,V_ASN1_UNIVERSAL);
+ V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
EVP_VerifyUpdate(&mdc_tmp,pp,i);
+
Free(pp);
}
os=si->enc_digest;
- if (X509_get_pubkey(x509)->type == EVP_PKEY_DSA)
- mdc_tmp.digest=EVP_dss1();
+ pkey = X509_get_pubkey(x509);
+ if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
- i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length,
- X509_get_pubkey(x509));
+ i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
+ EVP_PKEY_free(pkey);
if (i <= 0)
{
PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE);
return(ret);
}
-PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(p7,idx)
-PKCS7 *p7;
-int idx;
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
{
STACK *rsk;
PKCS7_RECIP_INFO *ri;
return(ri->issuer_and_serial);
}
-ASN1_TYPE *PKCS7_get_signed_attribute(si,nid)
-PKCS7_SIGNER_INFO *si;
-int nid;
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
{
return(get_attribute(si->auth_attr,nid));
}
-ASN1_TYPE *PKCS7_get_attribute(si,nid)
-PKCS7_SIGNER_INFO *si;
-int nid;
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
{
return(get_attribute(si->unauth_attr,nid));
}
-static ASN1_TYPE *get_attribute(sk,nid)
-STACK *sk;
-int nid;
+static ASN1_TYPE *get_attribute(STACK *sk, int nid)
{
int i;
X509_ATTRIBUTE *xa;
ASN1_OBJECT *o;
o=OBJ_nid2obj(nid);
- if (o == NULL) return(NULL);
+ if (!o || !sk) return(NULL);
for (i=0; i<sk_num(sk); i++)
{
xa=(X509_ATTRIBUTE *)sk_value(sk,i);
if (OBJ_cmp(xa->object,o) == 0)
{
- if (xa->set && sk_num(xa->value.set))
- return((ASN1_TYPE *)sk_value(xa->value.set,0));
+ if (xa->set && sk_ASN1_TYPE_num(xa->value.set))
+ return(sk_ASN1_TYPE_value(xa->value.set,0));
else
return(NULL);
}
return(NULL);
}
-ASN1_OCTET_STRING *PKCS7_digest_from_attributes(sk)
-STACK *sk;
- {
- X509_ATTRIBUTE *attr;
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK *sk)
+{
ASN1_TYPE *astype;
- int i;
- if (!sk || !sk_num(sk)) return NULL;
- /* Search the attributes for a digest */
- for (i = 0; i < sk_num(sk); i++)
- {
- attr = (X509_ATTRIBUTE *) sk_value(sk, i);
- if (OBJ_obj2nid(attr->object) == NID_pkcs9_messageDigest)
- {
- if (!attr->set) return NULL;
- if (!attr->value.set ||
- !sk_num (attr->value.set) ) return NULL;
- astype = (ASN1_TYPE *) sk_value(attr->value.set, 0);
- return astype->value.octet_string;
- }
- }
- return NULL;
- }
+ if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
+ return astype->value.octet_string;
+}
-int PKCS7_set_signed_attributes(p7si,sk)
-PKCS7_SIGNER_INFO *p7si;
-STACK *sk;
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, STACK *sk)
{
int i;
return(1);
}
-int PKCS7_set_attributes(p7si,sk)
-PKCS7_SIGNER_INFO *p7si;
-STACK *sk;
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK *sk)
{
int i;
return(1);
}
-int PKCS7_add_signed_attribute(p7si,nid,atrtype,value)
-PKCS7_SIGNER_INFO *p7si;
-int nid;
-int atrtype;
-char *value;
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+ void *value)
{
return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
}
-int PKCS7_add_attribute(p7si,nid,atrtype,value)
-PKCS7_SIGNER_INFO *p7si;
-int nid;
-int atrtype;
-char *value;
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+ void *value)
{
return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
}
-static int add_attribute(sk, nid, atrtype, value)
-STACK **sk;
-int nid;
-int atrtype;
-char *value;
+static int add_attribute(STACK **sk, int nid, int atrtype, void *value)
{
X509_ATTRIBUTE *attr=NULL;