Commit 3d14b9d0 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add support for MS "fast SGC".

parent 20432eae
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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"
+4 −3
Original line number Diff line number Diff line
@@ -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 */
+12 −0
Original line number Diff line number Diff line
@@ -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);
+32 −7
Original line number Diff line number Diff line
@@ -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:
			/* 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;
+1 −0
Original line number Diff line number Diff line
@@ -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)
Loading