X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_enc.c;h=c5c9a3be429941e3a3a2fc0cbe5c24cd150c3b8c;hp=f1cd25e3d35bab4498c2d989736fd66e2227a2b2;hb=436d318c806003352b916f637ceb68f3bfde72de;hpb=eda1f21f1af8b6f77327e7b37573af9c1ba73726 diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index f1cd25e3d3..c5c9a3be42 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -1,5 +1,5 @@ /* ssl/s3_enc.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -76,6 +76,56 @@ static unsigned char ssl3_pad_2[48]={ 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c }; +#ifndef NO_PROTO +static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, + unsigned char *sender, int len, unsigned char *p); +#else +static int ssl3_handshake_mac(); +#endif + +static void ssl3_generate_key_block(s,km,num) +SSL *s; +unsigned char *km; +int num; + { + MD5_CTX m5; + SHA_CTX s1; + unsigned char buf[8],smd[SHA_DIGEST_LENGTH]; + unsigned char c='A'; + int i,j,k; + + k=0; + for (i=0; isession->master_key, + s->session->master_key_length); + SHA1_Update(&s1,s->s3->server_random,SSL3_RANDOM_SIZE); + SHA1_Update(&s1,s->s3->client_random,SSL3_RANDOM_SIZE); + SHA1_Final( smd,&s1); + + MD5_Init( &m5); + MD5_Update(&m5,s->session->master_key, + s->session->master_key_length); + MD5_Update(&m5,smd,SHA_DIGEST_LENGTH); + if ((i+MD5_DIGEST_LENGTH) > num) + { + MD5_Final(smd,&m5); + memcpy(km,smd,(num-i)); + } + else + MD5_Final(km,&m5); + + km+=MD5_DIGEST_LENGTH; + } + memset(smd,0,SHA_DIGEST_LENGTH); + } + int ssl3_change_cipher_state(s,which) SSL *s; int which; @@ -86,10 +136,10 @@ int which; unsigned char *ms,*key,*iv,*er1,*er2; EVP_CIPHER_CTX *dd; EVP_CIPHER *c; - SSL_COMPRESSION *comp; + COMP_METHOD *comp; EVP_MD *m; MD5_CTX md; - int exp,n,i,j,k; + int exp,n,i,j,k,cl; exp=(s->s3->tmp.new_cipher->algorithms & SSL_EXPORT)?1:0; c=s->s3->tmp.new_sym_enc; @@ -105,7 +155,25 @@ int which; goto err; dd= s->enc_read_ctx; s->read_hash=m; - s->read_compression=comp; + /* COMPRESS */ + if (s->expand != NULL) + { + COMP_CTX_free(s->expand); + s->expand=NULL; + } + if (comp != NULL) + { + s->expand=COMP_CTX_new(comp); + if (s->expand == NULL) + { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + s->s3->rrec.comp=(unsigned char *) + Malloc(SSL3_RT_MAX_PLAIN_LENGTH); + if (s->s3->rrec.comp == NULL) + goto err; + } memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); } @@ -117,14 +185,32 @@ int which; goto err; dd= s->enc_write_ctx; s->write_hash=m; - s->write_compression=comp; + /* COMPRESS */ + if (s->compress != NULL) + { + COMP_CTX_free(s->compress); + s->compress=NULL; + } + if (comp != NULL) + { + s->compress=COMP_CTX_new(comp); + if (s->compress == NULL) + { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + } memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); } + EVP_CIPHER_CTX_init(dd); + p=s->s3->tmp.key_block; i=EVP_MD_size(m); - j=(exp)?5:EVP_CIPHER_key_length(c); + cl=EVP_CIPHER_key_length(c); + j=exp ? (cl < 5 ? cl : 5) : cl; + /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) @@ -164,18 +250,20 @@ int which; MD5_Final(&(exp_key[0]),&md); key= &(exp_key[0]); - MD5_Init(&md); - MD5_Update(&md,er1,SSL3_RANDOM_SIZE); - MD5_Update(&md,er2,SSL3_RANDOM_SIZE); - MD5_Final(&(exp_iv[0]),&md); - iv= &(exp_iv[0]); + if (k > 0) + { + MD5_Init(&md); + MD5_Update(&md,er1,SSL3_RANDOM_SIZE); + MD5_Update(&md,er2,SSL3_RANDOM_SIZE); + MD5_Final(&(exp_iv[0]),&md); + iv= &(exp_iv[0]); + } } - s->session->key_arg_length=k; - if (k > 0) - memcpy(&(s->session->key_arg[0]),iv,k); + s->session->key_arg_length=0; EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE)); + memset(&(exp_key[0]),0,sizeof(exp_key)); memset(&(exp_iv[0]),0,sizeof(exp_iv)); return(1); @@ -204,6 +292,11 @@ SSL *s; s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; +#ifdef ZLIB + s->s3->tmp.new_compression=COMP_zlib(); +#endif +/* s->s3->tmp.new_compression=COMP_rle(); */ +/* s->session->compress_meth= xxxxx */ exp=(s->session->cipher->algorithms & SSL_EXPORT)?1:0; @@ -248,35 +341,28 @@ int send; unsigned long l; int bs,i; EVP_CIPHER *enc; - SSL_COMPRESSION *comp; if (send) { ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) - { enc=NULL; comp=NULL; } + enc=NULL; else - { enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); - comp=s->write_compression; - } } else { ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) - { enc=NULL; comp=NULL; } + enc=NULL; else - { enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); - comp=s->read_compression; - } } if ((s->session == NULL) || (ds == NULL) || - ((enc == NULL) && (comp == NULL))) + (enc == NULL)) { memcpy(rec->data,rec->input,rec->length); rec->input=rec->data; @@ -286,6 +372,8 @@ int send; l=rec->length; bs=EVP_CIPHER_block_size(ds->cipher); + /* COMPRESS */ + /* This should be using (bs-1) and bs instead of 7 and 8 */ if ((bs != 1) && send) { @@ -305,7 +393,7 @@ int send; if (i > bs) { SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_BAD_RECORD_MAC); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPT_ERROR); return(0); } rec->length-=i; @@ -317,8 +405,8 @@ int send; void ssl3_init_finished_mac(s) SSL *s; { - EVP_DigestInit(&(s->s3->finish_dgst1),EVP_md5()); - EVP_DigestInit(&(s->s3->finish_dgst2),EVP_sha1()); + EVP_DigestInit(&(s->s3->finish_dgst1),s->ctx->md5); + EVP_DigestInit(&(s->s3->finish_dgst2),s->ctx->sha1); } void ssl3_finish_mac(s,buf,len) @@ -330,10 +418,34 @@ int len; EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len); } -int ssl3_final_finish_mac(s,in_ctx,sender,p) +int ssl3_cert_verify_mac(s,ctx,p) +SSL *s; +EVP_MD_CTX *ctx; +unsigned char *p; + { + return(ssl3_handshake_mac(s,ctx,NULL,0,p)); + } + +int ssl3_final_finish_mac(s,ctx1,ctx2,sender,len,p) +SSL *s; +EVP_MD_CTX *ctx1,*ctx2; +unsigned char *sender; +int len; +unsigned char *p; + { + int ret; + + ret=ssl3_handshake_mac(s,ctx1,sender,len,p); + p+=ret; + ret+=ssl3_handshake_mac(s,ctx2,sender,len,p); + return(ret); + } + +static int ssl3_handshake_mac(s,in_ctx,sender,len,p) SSL *s; EVP_MD_CTX *in_ctx; unsigned char *sender; +int len; unsigned char *p; { unsigned int ret; @@ -348,7 +460,7 @@ unsigned char *p; npad=(48/n)*n; if (sender != NULL) - EVP_DigestUpdate(&ctx,sender,4); + EVP_DigestUpdate(&ctx,sender,len); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_1,npad); @@ -397,19 +509,6 @@ int send; md_size=EVP_MD_size(hash); npad=(48/md_size)*md_size; -#ifdef MAC_DEBUG -printf("npad=%d md_size=%d",npad,md_size); -printf("\nmsec="); -for (i=0; itype,rec->length); -for (i=0; ilength; i++) printf("%02X",rec->input[i]); -printf("\n"); -#endif - /* Chop the digest off the end :-) */ EVP_DigestInit( &md_ctx,hash); @@ -433,12 +532,6 @@ printf("\n"); for (i=7; i>=0; i--) if (++seq[i]) break; -#ifdef MAC_DEBUG -printf("md="); -for (i=0; ictx->sha1); EVP_DigestUpdate(&ctx,salt[i],strlen((char *)salt[i])); EVP_DigestUpdate(&ctx,p,len); EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]), @@ -469,7 +562,7 @@ int len; SSL3_RANDOM_SIZE); EVP_DigestFinal(&ctx,buf,&n); - EVP_DigestInit(&ctx,EVP_md5()); + EVP_DigestInit(&ctx,s->ctx->md5); EVP_DigestUpdate(&ctx,p,len); EVP_DigestUpdate(&ctx,buf,n); EVP_DigestFinal(&ctx,out,&n); @@ -479,3 +572,36 @@ int len; return(ret); } +int ssl3_alert_code(code) +int code; + { + switch (code) + { + case SSL_AD_CLOSE_NOTIFY: return(SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: return(SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_RECORD_OVERFLOW: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: return(SSL3_AD_NO_CERTIFICATE); + case SSL_AD_BAD_CERTIFICATE: return(SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: return(SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: return(SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_ACCESS_DENIED: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECODE_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECRYPT_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_EXPORT_RESTRICION: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_PROTOCOL_VERSION: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INTERNAL_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_USER_CANCLED: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_RENEGOTIATION: return(-1); /* Don't send it :-) */ + default: return(-1); + } + } +