pk7_doit.c
来自「openssl是ssl的开源项目」· C语言 代码 · 共 941 行 · 第 1/2 页
C
941 行
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 *sk,*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=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; 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_num(si_sk); i++) { si=(PKCS7_SIGNER_INFO *) sk_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_type(EVP_MD_CTX_type(mdc)) == j) break; else btmp=btmp->next_bio; } /* 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_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(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)) { PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB); 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); 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); 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; {/* 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,i; int md_type; STACK *sk,*cert; BIO *btmp; X509 *x509; 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; 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) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); goto err; } /* Lets verify */ X509_STORE_CTX_init(ctx,cert_store,x509,cert); i=X509_verify_cert(ctx); 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. */ md_type=OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; for (;;) { if ((btmp == NULL) || ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } BIO_get_md_ctx(btmp,&mdc); if (mdc == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_INTERNAL_ERROR); goto err; } if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type) break; btmp=btmp->next_bio; } /* 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; ii<message_digest->length; ii++) printf("%02X",message_digest->data[ii]); printf(" sent\n");for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");}#endif PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_DIGEST_FAILURE); ret= -1; goto err; } EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type)); i=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL); pp=(unsigned char *)Malloc(i); p=pp; i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE, V_ASN1_SET,V_ASN1_UNIVERSAL); 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(); i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, X509_get_pubkey(x509)); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE); ret= -1; goto err; } else ret=1;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; 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)); 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; i<sk_num(sk); i++) { if ((sk_value(p7si->auth_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; i<sk_num(sk); i++) { if ((sk_value(p7si->unauth_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; 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; i<sk_num(*sk); i++) { attr=(X509_ATTRIBUTE *)sk_value(*sk,i); if (OBJ_obj2nid(attr->object) == 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); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?