p=buf;
p = buf + 11;
static int get_server_hello(SSL *s)	{	unsigned char *buf;	unsigned char *p;	int i,j;	STACK_OF(SSL_CIPHER) *sk=NULL,*cl, *prio, *allow;	buf=(unsigned char *)s->init_buf->data;	p=buf;	if (s->state == SSL2_ST_GET_SERVER_HELLO_A)		{		i=ssl2_read(s,(char *)&(buf[s->init_num]),11-s->init_num);		if (i < (11-s->init_num)) 			return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));		if (*(p++) != SSL2_MT_SERVER_HELLO)			{			if (p[-1] != SSL2_MT_ERROR)				{				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);				SSLerr(SSL_F_GET_SERVER_HELLO,					SSL_R_READ_WRONG_PACKET_TYPE);				}			else				SSLerr(SSL_F_GET_SERVER_HELLO,					SSL_R_PEER_ERROR);			return(-1);			}#ifdef __APPLE_CC__		/* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug		 * workaround. <appro@fy.chalmers.se> */		s->hit=(i=*(p++))?1:0;#else		s->hit=(*(p++))?1:0;#endif		s->s2->tmp.cert_type= *(p++);		n2s(p,i);		if (i < s->version) s->version=i;		n2s(p,i); s->s2->tmp.cert_length=i;		n2s(p,i); s->s2->tmp.csl=i;		n2s(p,i); s->s2->tmp.conn_id_length=i;		s->state=SSL2_ST_GET_SERVER_HELLO_B;		s->init_num=0;		}	/* SSL2_ST_GET_SERVER_HELLO_B */	j=s->s2->tmp.cert_length+s->s2->tmp.csl+s->s2->tmp.conn_id_length		- s->init_num;	i=ssl2_read(s,(char *)&(buf[s->init_num]),j);	if (i != j) return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));	/* things are looking good */	p=buf;	if (s->hit)		{		if (s->s2->tmp.cert_length != 0) 			{			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);			return(-1);			}		if (s->s2->tmp.cert_type != 0)			{			if (!(s->options &				SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG))				{				SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO);				return(-1);				}			}		if (s->s2->tmp.csl != 0)			{			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);			return(-1);			}		}	else		{#ifdef undef		/* very bad */		memset(s->session->session_id,0,			SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);		s->session->session_id_length=0;		*/#endif		/* we need to do this in case we were trying to reuse a 		 * client session but others are already reusing it.		 * If this was a new 'blank' session ID, the session-id		 * length will still be 0 */		if (s->session->session_id_length > 0)			{			if (!ssl_get_new_session(s,0))				{				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);				return(-1);				}			}		if (ssl2_set_certificate(s,s->s2->tmp.cert_type,			s->s2->tmp.cert_length,p) <= 0)			{			ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);			return(-1);			}		p+=s->s2->tmp.cert_length;		if (s->s2->tmp.csl == 0)			{			ssl2_return_error(s,SSL2_PE_NO_CIPHER);			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_LIST);			return(-1);			}		/* We have just received a list of ciphers back from the		 * server.  We need to get the ones that match, then select		 * the one we want the most :-). */		/* load the ciphers */		sk=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.csl,					    &s->session->ciphers);		p+=s->s2->tmp.csl;		if (sk == NULL)			{			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);			SSLerr(SSL_F_GET_SERVER_HELLO,ERR_R_MALLOC_FAILURE);			return(-1);			}		sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp);		/* get the array of ciphers we will accept */		cl=SSL_get_ciphers(s);		sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp);		/*		 * If server preference flag set, choose the first		 * (highest priority) cipher the server sends, otherwise		 * client preference has priority.		 */		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)		    {		    prio = sk;		    allow = cl;		    }		else		    {		    prio = cl;		    allow = sk;		    }		/* In theory we could have ciphers sent back that we		 * don't want to use but that does not matter since we		 * will check against the list we originally sent and		 * for performance reasons we should not bother to match		 * the two lists up just to check. */		for (i=0; i<sk_SSL_CIPHER_num(prio); i++)			{			if (sk_SSL_CIPHER_find(allow,					     sk_SSL_CIPHER_value(prio,i)) >= 0)				break;			}		if (i >= sk_SSL_CIPHER_num(prio))			{			ssl2_return_error(s,SSL2_PE_NO_CIPHER);			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_MATCH);			return(-1);			}		s->session->cipher=sk_SSL_CIPHER_value(prio,i);		if (s->session->peer != NULL) /* can't happen*/			{			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);			SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);			return(-1);			}		s->session->peer = s->session->sess_cert->peer_key->x509;		/* peer_key->x509 has been set by ssl2_set_certificate. */		CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);		}	if (s->session->peer != s->session->sess_cert->peer_key->x509)		/* can't happen */		{		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);		SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);		return(-1);		}			s->s2->conn_id_length=s->s2->tmp.conn_id_length;	memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);	return(1);	}