/* seed1 through seed5 are virtually concatenated */
static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
int sec_len,
const void *seed1, int seed1_len,
const void *seed2, int seed2_len,
const void *seed3, int seed3_len,
const void *seed4, int seed4_len,
const void *seed5, int seed5_len,
unsigned char *out, int olen)
{
int chunk;
size_t j;
EVP_MD_CTX ctx, ctx_tmp, ctx_init;
EVP_PKEY *mac_key;
unsigned char A1[EVP_MAX_MD_SIZE];
size_t A1_len;
int ret = 0;
chunk=EVP_MD_size(md);
OPENSSL_assert(chunk >= 0);
EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_init(&ctx_tmp);
EVP_MD_CTX_init(&ctx_init);
EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
if (!mac_key)
goto err;
if (!EVP_DigestSignInit(&ctx_init,NULL,md, NULL, mac_key))
goto err;
if (!EVP_MD_CTX_copy_ex(&ctx,&ctx_init))
goto err;
if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
goto err;
if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
goto err;
if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
goto err;
if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
goto err;
if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
goto err;
if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
goto err;
for (;;)
{
/* Reinit mac contexts */
if (!EVP_MD_CTX_copy_ex(&ctx,&ctx_init))
goto err;
if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
goto err;
if (olen>chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp,&ctx))
goto err;
if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
goto err;
if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
goto err;
if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
goto err;
if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
goto err;
if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
goto err;
if (olen > chunk)
{
if (!EVP_DigestSignFinal(&ctx,out,&j))
goto err;
out+=j;
olen-=j;
/* calc the next A1 value */
if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len))
goto err;
}
else /* last one */
{
if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
goto err;
memcpy(out,A1,olen);
break;
}
}
ret = 1;
err:
EVP_PKEY_free(mac_key);
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_cleanup(&ctx_tmp);
EVP_MD_CTX_cleanup(&ctx_init);
OPENSSL_cleanse(A1,sizeof(A1));
return ret;
}
开发者ID:0culus,项目名称:openssl,代码行数:92,代码来源:t1_enc.c
示例7: PKCS7_dataFinal
//.........这里部分代码省略.........
}
/* 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);
}
//.........这里部分代码省略.........
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
goto err;
}
BIO_get_md_ctx(btmp,&mdc);
if (mdc == NULL)
{
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
ERR_R_INTERNAL_ERROR);
goto err;
}
if (EVP_MD_CTX_type(mdc) == md_type)
break;
/* Workaround for some broken clients that put the signature
* OID instead of the digest OID in digest_alg->algorithm
*/
if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
break;
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 */
if (!EVP_MD_CTX_copy_ex(&mdc_tmp,mdc))
goto err;
sk=si->auth_attr;
if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
{
unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
unsigned int md_len;
int alen;
ASN1_OCTET_STRING *message_digest;
if (!EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len))
goto err;
message_digest=PKCS7_digest_from_attributes(sk);
if (!message_digest)
{
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
goto err;
}
if ((message_digest->length != (int)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_SIGNATUREVERIFY,
PKCS7_R_DIGEST_FAILURE);
ret= -1;
goto err;
}
if (!EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL))
goto err;
alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
if (alen <= 0)
{
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
ret = -1;
goto err;
}
if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
goto err;
free(abuf);
}
os=si->enc_digest;
pkey = X509_get_pubkey(x509);
if (!pkey)
{
ret = -1;
goto err;
}
i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
EVP_PKEY_free(pkey);
if (i <= 0)
{
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
PKCS7_R_SIGNATURE_FAILURE);
ret= -1;
goto err;
}
else
ret=1;
err:
EVP_MD_CTX_cleanup(&mdc_tmp);
return(ret);
}
//.........这里部分代码省略.........
/* If we get an error we need to
* ssl->rwstate=SSL_X509_LOOKUP;
* return(error);
* We should then be retried when things are ok and we
* can get a cert or not */
i=0;
if (s->ctx->client_cert_cb != NULL)
{
i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
}
if (i < 0)
{
s->rwstate=SSL_X509_LOOKUP;
return(-1);
}
s->rwstate=SSL_NOTHING;
if ((i == 1) && (pkey != NULL) && (x509 != NULL))
{
s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
if ( !SSL_use_certificate(s,x509) ||
!SSL_use_PrivateKey(s,pkey))
{
i=0;
}
X509_free(x509);
EVP_PKEY_free(pkey);
}
else if (i == 1)
{
if (x509 != NULL) X509_free(x509);
if (pkey != NULL) EVP_PKEY_free(pkey);
SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
i=0;
}
if (i == 0)
{
/* We have no client certificate to respond with
* so send the correct error message back */
s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
p=buf;
*(p++)=SSL2_MT_ERROR;
s2n(SSL2_PE_NO_CERTIFICATE,p);
s->init_off=0;
s->init_num=3;
/* Write is done at the end */
}
}
if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
{
return(ssl2_do_write(s));
}
if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
{
EVP_MD_CTX ctx;
/* ok, now we calculate the checksum
* do it first so we can reuse buf :-) */
p=buf;
EVP_MD_CTX_init(&ctx);
EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
EVP_SignUpdate(&ctx,s->s2->key_material,
s->s2->key_material_length);
EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
i=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
/* Don't update the signature if it fails - FIXME: probably should handle this better */
if(i > 0)
EVP_SignUpdate(&ctx,buf,(unsigned int)i);
p=buf;
d=p+6;
*(p++)=SSL2_MT_CLIENT_CERTIFICATE;
*(p++)=SSL2_CT_X509_CERTIFICATE;
n=i2d_X509(s->cert->key->x509,&d);
s2n(n,p);
if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
{
/* this is not good. If things have failed it
* means there so something wrong with the key.
* We will continue with a 0 length signature
*/
}
EVP_MD_CTX_cleanup(&ctx);
s2n(n,p);
d+=n;
s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
s->init_num=d-buf;
s->init_off=0;
}
/* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
return(ssl2_do_write(s));
}
请发表评论