From dfeab0689f69c0b4bd3480ffd37a9cacc2f17d9c Mon Sep 17 00:00:00 2001 From: "Ralf S. Engelschall" Date: Mon, 21 Dec 1998 11:00:56 +0000 Subject: Import of old SSLeay release: SSLeay 0.9.1b (unreleased) --- crypto/pkcs7/pk7_doit.c | 615 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 574 insertions(+), 41 deletions(-) (limited to 'crypto/pkcs7/pk7_doit.c') diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index b5689b3fe4..d761c3ee02 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -62,12 +62,16 @@ #include "objects.h" #include "x509.h" +static int add_attribute(STACK **sk, int nid, int atrtype, char *value); +static ASN1_TYPE *get_attribute(STACK *sk, int nid); + +#if 1 BIO *PKCS7_dataInit(p7,bio) PKCS7 *p7; BIO *bio; { int i,j; - BIO *out=NULL,*btmp; + BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa; EVP_MD *evp_md; EVP_CIPHER *evp_cipher=NULL; @@ -95,6 +99,16 @@ BIO *bio; } xalg=p7->d.signed_and_enveloped->enc_data->algorithm; break; + case NID_pkcs7_enveloped: + rsk=p7->d.enveloped->recipientinfo; + evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.enveloped->enc_data->algorithm->algorithm))); + if (evp_cipher == NULL) + { + PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + xalg=p7->d.enveloped->enc_data->algorithm; + break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; @@ -105,7 +119,11 @@ BIO *bio; for (i=0; ialgorithm); evp_md=EVP_get_digestbyname(OBJ_nid2sn(j)); @@ -120,6 +138,7 @@ BIO *bio; out=btmp; else BIO_push(out,btmp); + btmp=NULL; } } @@ -131,7 +150,11 @@ BIO *bio; int jj,max; unsigned char *tmp; - if ((btmp=BIO_new(BIO_f_cipher())) == NULL) goto err; + if ((btmp=BIO_new(BIO_f_cipher())) == NULL) + { + PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); + goto err; + } keylen=EVP_CIPHER_key_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher); @@ -142,9 +165,12 @@ BIO *bio; RAND_bytes(iv,ivlen); os=ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(os,iv,ivlen); - /* ASN1_TYPE_set(xalg->parameter,V_ASN1_OCTET_STRING, +/* 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); - */ } + } RAND_bytes(key,keylen); /* Lets do the pub key stuff :-) */ @@ -152,20 +178,34 @@ BIO *bio; for (i=0; icert == NULL) abort(); + 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); if (max < jj) max=jj; } - if ((tmp=(unsigned char *)Malloc(max)) == NULL) abort(); + if ((tmp=(unsigned char *)Malloc(max)) == NULL) + { + PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); + goto err; + } for (i=0; icert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); - if (jj <= 0) abort(); + if (jj <= 0) + { + PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); + Free(tmp); + goto err; + } ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } + Free(tmp); BIO_set_cipher(btmp,evp_cipher,key,iv,1); @@ -173,6 +213,7 @@ BIO *bio; out=btmp; else BIO_push(out,btmp); + btmp=NULL; } if (bio == NULL) /* ??????????? */ @@ -182,6 +223,11 @@ BIO *bio; else { bio=BIO_new(BIO_s_mem()); + /* We need to set this so that when we have read all + * the data, the encrypt BIO, if present, will read + * EOF and encode the last few bytes */ + BIO_set_mem_eof_return(bio,0); + if (PKCS7_type_is_signed(p7) && PKCS7_type_is_data(p7->d.sign->contents)) { @@ -195,12 +241,234 @@ BIO *bio; } } 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); + } + +/* int */ +BIO *PKCS7_dataDecode(p7,pkey,in_bio,xs) +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; + EVP_CIPHER_CTX *evp_ctx=NULL; + X509_ALGOR *enc_alg=NULL; + STACK *md_sk=NULL,*rsk=NULL; + X509_ALGOR *xalg=NULL; + PKCS7_RECIP_INFO *ri=NULL; +/* EVP_PKEY *pkey; */ +#if 0 + X509_STORE_CTX s_ctx; +#endif + + i=OBJ_obj2nid(p7->type); + p7->state=PKCS7_S_HEADER; + + switch (i) + { + case NID_pkcs7_signed: + data_body=p7->d.sign->contents->d.data; + 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; + data_body=p7->d.signed_and_enveloped->enc_data->enc_data; + enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm))); + if (evp_cipher == NULL) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + xalg=p7->d.signed_and_enveloped->enc_data->algorithm; + break; + case NID_pkcs7_enveloped: + rsk=p7->d.enveloped->recipientinfo; + enc_alg=p7->d.enveloped->enc_data->algorithm; + data_body=p7->d.enveloped->enc_data->enc_data; + evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm))); + if (evp_cipher == NULL) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + xalg=p7->d.enveloped->enc_data->algorithm; + break; + default: + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + /* We will be checking the signature */ + if (md_sk != NULL) + { + for (i=0; ialgorithm); + evp_md=EVP_get_digestbyname(OBJ_nid2sn(j)); + if (evp_md == NULL) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,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) + { +#if 0 + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char *p; + int keylen,ivlen; + int max; + X509_OBJECT ret; +#endif + int jj; + + if ((etmp=BIO_new(BIO_f_cipher())) == NULL) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB); + goto err; + } + + /* It was encrypted, we need to decrypt the secret key + * with the private key */ + + /* We need to find a private key for one of the people in the + * recipentinfo list */ + if (rsk == NULL) + return(NULL); + + ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0); +#if 0 + X509_STORE_CTX_init(&s_ctx,xs,NULL,NULL); + for (i=0; iissuer_and_serial->issuer, + ri->issuer_and_serial->serial, + &ret)) + break; + ri=NULL; + } + if (ri == NULL) return(NULL); + pkey=ret.data.pkey; +#endif + if (pkey == NULL) + { + return(NULL); + } + + jj=EVP_PKEY_size(pkey); + tmp=Malloc(jj+10); + if (tmp == NULL) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + jj=EVP_PKEY_decrypt((unsigned char *)tmp, + ASN1_STRING_data(ri->enc_key), + ASN1_STRING_length(ri->enc_key), + pkey); + if (jj <= 0) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_EVP_LIB); + goto err; + } + + evp_ctx=NULL; + BIO_get_cipher_ctx(etmp,&evp_ctx); + EVP_CipherInit(evp_ctx,evp_cipher,NULL,NULL,0); + if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) + return(NULL); + + if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) + { + PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); + goto err; + } + EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0); + + memset(tmp,0,jj); + + if (out == NULL) + out=etmp; + else + BIO_push(out,etmp); + etmp=NULL; + } + +#if 1 + if (p7->detached || (in_bio != NULL)) + { + bio=in_bio; + } + else + { + bio=BIO_new(BIO_s_mem()); + /* We need to set this so that when we have read all + * the data, the encrypt BIO, if present, will read + * EOF and encode the last few bytes */ + BIO_set_mem_eof_return(bio,0); + + if (data_body->length > 0) + BIO_write(bio,(char *)data_body->data,data_body->length); + } + BIO_push(out,bio); + bio=NULL; +#endif + if (0) + { err: - return(NULL); + if (out != NULL) BIO_free_all(out); + if (btmp != NULL) BIO_free_all(btmp); + if (etmp != NULL) BIO_free_all(etmp); + if (bio != NULL) BIO_free_all(bio); + out=NULL; + } + if (tmp != NULL) + Free(tmp); + return(out); } +#endif -int PKCS7_dataSign(p7,bio) +int PKCS7_dataFinal(p7,bio) PKCS7 *p7; BIO *bio; { @@ -227,6 +495,11 @@ BIO *bio; os=ASN1_OCTET_STRING_new(); p7->d.signed_and_enveloped->enc_data->enc_data=os; break; + case NID_pkcs7_enveloped: + /* XXXXXXXXXXXXXXXX */ + os=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; @@ -235,14 +508,18 @@ BIO *bio; if (si_sk != NULL) { - if ((buf=BUF_MEM_new()) == NULL) goto err; + if ((buf=BUF_MEM_new()) == NULL) + { + PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); + goto err; + } for (i=0; ipkey == NULL) - continue; - j=OBJ_obj2nid(si->digest_enc_alg->algorithm); + if (si->pkey == NULL) continue; + + j=OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; for (;;) @@ -259,7 +536,7 @@ BIO *bio; PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR); goto err; } - if (EVP_MD_pkey_type(EVP_MD_CTX_type(mdc)) == j) + if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == j) break; else btmp=btmp->next_bio; @@ -269,46 +546,85 @@ BIO *bio; * 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_num(sk) != 0)) { + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + ASN1_OCTET_STRING *digest; + ASN1_UTCTIME *sign_time; + 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); + + /* 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); + + /* 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); - pp=(unsigned char *)Malloc(i); + pp=(unsigned char *)Malloc(x); p=pp; i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL); EVP_SignUpdate(&ctx_tmp,pp,x); Free(pp); + pp=NULL; } + if (si->pkey->type == EVP_PKEY_DSA) + ctx_tmp.digest=EVP_dss1(); + 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)) - goto err; - } - if (p7->detached) - ASN1_OCTET_STRING_set(os,(unsigned char *)"",0); - else - { - btmp=BIO_find_type(bio,BIO_TYPE_MEM); - if (btmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); + PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB); goto err; } - BIO_get_mem_ptr(btmp,&buf_mem); - ASN1_OCTET_STRING_set(os, - (unsigned char *)buf_mem->data,buf_mem->length); } - if (pp != NULL) Free(pp); - pp=NULL; } + if (p7->detached) + ASN1_OCTET_STRING_set(os,(unsigned char *)"",0); + else + { + 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); + ASN1_OCTET_STRING_set(os, + (unsigned char *)buf_mem->data,buf_mem->length); + } + if (pp != NULL) Free(pp); + pp=NULL; + ret=1; err: if (buf != NULL) BUF_MEM_free(buf); @@ -322,22 +638,34 @@ BIO *bio; PKCS7 *p7; PKCS7_SIGNER_INFO *si; { - PKCS7_SIGNED *s; +/* PKCS7_SIGNED *s; */ ASN1_OCTET_STRING *os; EVP_MD_CTX mdc_tmp,*mdc; unsigned char *pp,*p; PKCS7_ISSUER_AND_SERIAL *ias; - int ret=0,md_type,i; - STACK *sk; + int ret=0,i; + int md_type; + STACK *sk,*cert; BIO *btmp; X509 *x509; - if (!PKCS7_type_is_signed(p7)) abort(); + if (PKCS7_type_is_signed(p7)) + { + cert=p7->d.sign->cert; + } + else if (PKCS7_type_is_signedAndEnveloped(p7)) + { + cert=p7->d.signed_and_enveloped->cert; + } + else + { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } /* XXXXXXXXXXXXXXXXXXXXXXX */ ias=si->issuer_and_serial; - s=p7->d.sign; - x509=X509_find_by_issuer_and_serial(s->cert,ias->issuer,ias->serial); + x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial); /* were we able to find the cert in passed to us */ if (x509 == NULL) @@ -347,9 +675,13 @@ PKCS7_SIGNER_INFO *si; } /* Lets verify */ - X509_STORE_CTX_init(ctx,cert_store,x509,s->cert); + X509_STORE_CTX_init(ctx,cert_store,x509,cert); i=X509_verify_cert(ctx); - if (i <= 0) goto err; + if (i <= 0) + { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); + goto err; + } X509_STORE_CTX_cleanup(ctx); /* So we like 'x509', lets check the signature. */ @@ -375,23 +707,55 @@ PKCS7_SIGNER_INFO *si; btmp=btmp->next_bio; } - /* mdc is the digest ctx that we want */ + /* 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)); sk=si->auth_attr; if ((sk != NULL) && (sk_num(sk) != 0)) { + unsigned char md_dat[EVP_MAX_MD_SIZE]; + int md_len; + ASN1_OCTET_STRING *message_digest; + + EVP_DigestFinal(&mdc_tmp,md_dat,&md_len); + message_digest=PKCS7_digest_from_attributes(sk); + if (!message_digest) + { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + if ((message_digest->length != md_len) || + (memcmp(message_digest->data,md_dat,md_len))) + { +#if 0 +{ +int ii; +for (ii=0; iilength; ii++) + printf("%02X",message_digest->data[ii]); printf(" sent\n"); +for (ii=0; iienc_digest; + if (X509_get_pubkey(x509)->type == EVP_PKEY_DSA) + mdc_tmp.digest=EVP_dss1(); + i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, X509_get_pubkey(x509)); if (i <= 0) @@ -406,3 +770,172 @@ err: return(ret); } +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(p7,idx) +PKCS7 *p7; +int idx; + { + STACK *rsk; + PKCS7_RECIP_INFO *ri; + int i; + + i=OBJ_obj2nid(p7->type); + if (i != NID_pkcs7_signedAndEnveloped) return(NULL); + rsk=p7->d.signed_and_enveloped->recipientinfo; + ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0); + if (sk_num(rsk) <= idx) return(NULL); + ri=(PKCS7_RECIP_INFO *)sk_value(rsk,idx); + return(ri->issuer_and_serial); + } + +ASN1_TYPE *PKCS7_get_signed_attribute(si,nid) +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; + { + return(get_attribute(si->unauth_attr,nid)); + } + +static ASN1_TYPE *get_attribute(sk,nid) +STACK *sk; +int nid; + { + int i; + X509_ATTRIBUTE *xa; + ASN1_OBJECT *o; + + o=OBJ_nid2obj(nid); + if (o == NULL) return(NULL); + for (i=0; iobject,o) == 0) + { + if (xa->set && sk_num(xa->value.set)) + return((ASN1_TYPE *)sk_value(xa->value.set,0)); + else + return(NULL); + } + } + return(NULL); + } + +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(sk) +STACK *sk; + { + X509_ATTRIBUTE *attr; + 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; + } + +int PKCS7_set_signed_attributes(p7si,sk) +PKCS7_SIGNER_INFO *p7si; +STACK *sk; + { + int i; + + if (p7si->auth_attr != NULL) + sk_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); + p7si->auth_attr=sk_dup(sk); + for (i=0; iauth_attr,i)=(char *)X509_ATTRIBUTE_dup( + (X509_ATTRIBUTE *)sk_value(sk,i))) == NULL) + return(0); + } + return(1); + } + +int PKCS7_set_attributes(p7si,sk) +PKCS7_SIGNER_INFO *p7si; +STACK *sk; + { + int i; + + if (p7si->unauth_attr != NULL) + sk_pop_free(p7si->unauth_attr,X509_ATTRIBUTE_free); + p7si->unauth_attr=sk_dup(sk); + for (i=0; iunauth_attr,i)=(char *)X509_ATTRIBUTE_dup( + (X509_ATTRIBUTE *)sk_value(sk,i))) == NULL) + return(0); + } + return(1); + } + +int PKCS7_add_signed_attribute(p7si,nid,atrtype,value) +PKCS7_SIGNER_INFO *p7si; +int nid; +int atrtype; +char *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; + { + 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; + { + X509_ATTRIBUTE *attr=NULL; + ASN1_TYPE *val=NULL; + + if (*sk == NULL) + { + *sk = sk_new(NULL); +new_attrib: + attr=X509_ATTRIBUTE_create(nid,atrtype,value); + sk_push(*sk,(char *)attr); + } + else + { + int i; + + for (i=0; iobject) == nid) + { + X509_ATTRIBUTE_free(attr); + attr=X509_ATTRIBUTE_create(nid,atrtype,value); + sk_value(*sk,i)=(char *)attr; + goto end; + } + } + goto new_attrib; + } +end: + return(1); + } + -- cgit v1.2.3