Add support for MS "fast SGC".

This commit is contained in:
Dr. Stephen Henson 2000-01-02 18:52:58 +00:00
parent 20432eae41
commit 3d14b9d04a
6 changed files with 65 additions and 10 deletions

15
CHANGES
View File

@ -4,6 +4,21 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 1999]
*) Add support for MS "fast SGC". This is arguably a violation of the
SSL3/TLS protocol. Netscape SGC does two handshakes: the first with
weak crypto and after checking the certificate is SGC a second one
with strong crypto. MS SGC stops the first handshake after receiving
the server certificate message and sends a second client hello. Since
a server will typically do all the time consuming operations before
expecting any further messages from the client (server key exchange
is the most expensive) there is little difference between the two.
To get OpenSSL to support MS SGC we have to permit a second client
hello message after we have sent server done. In addition we have to
reset the MAC if we do get this second client hello and include the
data just received.
[Steve Henson]
*) Add a function 'd2i_AutoPrivateKey()' this will automatically decide
if a DER encoded private key is RSA or DSA traditional format. Changed
d2i_PrivateKey_bio() to use it. This is only needed for the "traditional"

View File

@ -200,11 +200,12 @@ typedef struct crypto_ex_data_func_st
#define CRYPTO_EX_INDEX_X509_STORE_CTX 5
#if 0 /* unnecessary, it's the default and cannot be changed back later anyway */
/* This is the default callbacks, but we can have others as well */
/* This is the default callbacks, but we can have others as well:
* this is needed in Win32 where the application malloc and the
* library malloc may not be the same.
*/
#define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\
malloc, realloc, free)
#endif
#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */

View File

@ -293,6 +293,18 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
if((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
(st1 == SSL3_ST_SR_CERT_A) &&
(stn == SSL3_ST_SR_CERT_B))
{
/* At this point we have got an MS SGC second client
* hello. We need to restart the mac and mac the data
* currently received.
*/
ssl3_init_finished_mac(s);
ssl3_finish_mac(s, p + s->init_num, i);
}
s->s3->tmp.message_type= *(p++);
n2l3(p,l);

View File

@ -70,6 +70,7 @@
static SSL_METHOD *ssl3_get_server_method(int ver);
static int ssl3_get_client_hello(SSL *s);
static int ssl3_check_client_hello(SSL *s);
static int ssl3_send_server_hello(SSL *s);
static int ssl3_send_server_key_exchange(SSL *s);
static int ssl3_send_certificate_request(SSL *s);
@ -141,6 +142,7 @@ int ssl3_accept(SSL *s)
s->new_session=1;
/* s->state=SSL_ST_ACCEPT; */
case SSL3_ST_SR_MS_SGC:
case SSL_ST_BEFORE:
case SSL_ST_ACCEPT:
case SSL_ST_BEFORE|SSL_ST_ACCEPT:
@ -184,8 +186,8 @@ int ssl3_accept(SSL *s)
if (s->state != SSL_ST_RENEGOTIATE)
{
if(s->state != SSL3_ST_SR_MS_SGC) ssl3_init_finished_mac(s);
s->state=SSL3_ST_SR_CLNT_HELLO_A;
ssl3_init_finished_mac(s);
s->ctx->stats.sess_accept++;
}
else
@ -341,12 +343,18 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CERT_A:
case SSL3_ST_SR_CERT_B:
/* could be sent for a DH cert, even if we
* have not asked for it :-) */
ret=ssl3_get_client_certificate(s);
if (ret <= 0) goto end;
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
/* Check for second client hello if MS SGC */
ret = ssl3_check_client_hello(s);
if(ret <= 0) goto end;
if(ret == 2) s->state = SSL3_ST_SR_MS_SGC;
else {
/* could be sent for a DH cert, even if we
* have not asked for it :-) */
ret=ssl3_get_client_certificate(s);
if (ret <= 0) goto end;
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
}
break;
case SSL3_ST_SR_KEY_EXCH_A:
@ -510,6 +518,23 @@ static int ssl3_send_hello_request(SSL *s)
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
static int ssl3_check_client_hello(SSL *s)
{
int ok;
long n;
n=ssl3_get_message(s,
SSL3_ST_SR_CERT_A,
SSL3_ST_SR_CERT_B,
-1,
SSL3_RT_MAX_PLAIN_LENGTH,
&ok);
if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1;
if(s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) return 2;
return 1;
}
static int ssl3_get_client_hello(SSL *s)
{
int i,j,ok,al,ret= -1;

View File

@ -398,6 +398,7 @@ typedef struct ssl3_ctx_st
#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
#define SSL3_ST_SR_MS_SGC (0x113|SSL_ST_ACCEPT)
/* write to client */
#define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT)
#define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT)

View File

@ -161,6 +161,7 @@ case SSL3_ST_SW_FLUSH: str="SSLv3 flush data"; break;
case SSL3_ST_SR_CLNT_HELLO_A: str="SSLv3 read client hello A"; break;
case SSL3_ST_SR_CLNT_HELLO_B: str="SSLv3 read client hello B"; break;
case SSL3_ST_SR_CLNT_HELLO_C: str="SSLv3 read client hello C"; break;
case SSL3_ST_SR_MS_SGC: str="SSLv3 read second client hello (MS SGC)"; break;
case SSL3_ST_SW_HELLO_REQ_A: str="SSLv3 write hello request A"; break;
case SSL3_ST_SW_HELLO_REQ_B: str="SSLv3 write hello request B"; break;
case SSL3_ST_SW_HELLO_REQ_C: str="SSLv3 write hello request C"; break;