Hello all,

    I am trying to reconstruct the key block from a given ssl connection,
and I seem to have found a way to do it (borrowing heavily from the files
t1_enc.c, and ssl_ciph.c) but I run into a problem.  During a call to
ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,const EVP_MD
**md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp, SSL* ssl)  I
get an error state, and I've tracked it down to something within the
SSL_CIPHER structure.  First, I'll paste the code here for reference, and
highlight my changes with a diff style changes

-- original code
++ my changes

int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
--     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP
**comp)
++      const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP
**comp, SSL* ssl)
 {
int i;
const SSL_CIPHER *c;
-- c=s->cipher;
++    c = SSL_get_current_cipher(ssl);  //This was changed because s->cipher
was returning 0, and causing the function to return.
 if (c == NULL) return(0);
if (comp != NULL)
{
 SSL_COMP ctmp;
#ifndef OPENSSL_NO_COMP
load_builtin_compressions();
#endif

*comp=NULL;
ctmp.id=s->compress_meth;
 if (ssl_comp_methods != NULL)
{
i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
 if (i >= 0)
*comp=sk_SSL_COMP_value(ssl_comp_methods,i);
else
 *comp=NULL;
}
}

if ((enc == NULL) || (md == NULL)) return(0);

switch (c->algorithm_enc)
 {
case SSL_DES:
i=SSL_ENC_DES_IDX;
 break;
case SSL_3DES:
i=SSL_ENC_3DES_IDX;
 break;
case SSL_RC4:
i=SSL_ENC_RC4_IDX;
 break;
case SSL_RC2:
i=SSL_ENC_RC2_IDX;
 break;
case SSL_IDEA:
i=SSL_ENC_IDEA_IDX;
 break;
case SSL_eNULL:
i=SSL_ENC_NULL_IDX;
 break;
case SSL_AES128:
i=SSL_ENC_AES128_IDX;
 break;
case SSL_AES256:
i=SSL_ENC_AES256_IDX;
 break;
case SSL_CAMELLIA128:
i=SSL_ENC_CAMELLIA128_IDX;
 break;
case SSL_CAMELLIA256:
i=SSL_ENC_CAMELLIA256_IDX;
 break;
case SSL_eGOST2814789CNT:
i=SSL_ENC_GOST89_IDX;
 break;
case SSL_SEED:
i=SSL_ENC_SEED_IDX;
 break;
default:
i= -1;
 break;
}

if ((i < 0) || (i > SSL_ENC_NUM_IDX))
 *enc=NULL;
else
{
 if (i == SSL_ENC_NULL_IDX)
*enc=EVP_enc_null();
else
 *enc=ssl_cipher_methods[i];
}

switch (c->algorithm_mac)
 {
case SSL_MD5:
i=SSL_MD_MD5_IDX;
 break;
case SSL_SHA1:
i=SSL_MD_SHA1_IDX;
 break;
case SSL_GOST94:
i = SSL_MD_GOST94_IDX;
 break;
case SSL_GOST89MAC:
i = SSL_MD_GOST89MAC_IDX;
 break;
default:
i= -1;
 break;
}
if ((i < 0) || (i > SSL_MD_NUM_IDX))
 {
*md=NULL;
if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
 if (mac_secret_size!=NULL) *mac_secret_size = 0;

}
else
 {
*md=ssl_digest_methods[i];
if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
 if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
}

if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type !=
NID_undef))
return(1);
 else
return(0);
}

Like I said, this is heavily borrowed.  I've only made 1 change so far, and
changed the signature of the function.  Any way the error comes when I'm
switching on c->algorithm_enc.  c->algorithm_enc is always zero no matter
what the cipher spec.  I don't understand why.  c->algorithm_mac has a
legitimate value, but not c->algorithm_enc.  Why is this?  Is there anyway
to work around it like I did with with the SSL_get_current_cipher()?  Please
let me know if you know of any possible solution.  I am really at a loss for
why this field never gets populated.

     Thanks again,

          Sam


-- 
Sam Jantz
Software Engineer

Reply via email to