CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509);
s->session->peer->references++;
static int get_server_hello(SSL *s)	{	unsigned char *buf;	unsigned char *p;	int i,j;	STACK_OF(SSL_CIPHER) *sk=NULL,*cl;	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);			}		s->hit=(*(p++))?1:0;		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 incase 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_by_id(s);		/* 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 origionally 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(cl); i++)			{			if (sk_SSL_CIPHER_find(sk,					       sk_SSL_CIPHER_value(cl,i)) >= 0)				break;			}		if (i >= sk_SSL_CIPHER_num(cl))			{			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(cl,i);		}	if ((s->session != NULL) && (s->session->peer != NULL))		X509_free(s->session->peer);	/* hmmm, can we have the problem of the other session with this	 * cert, Free's it before we increment the reference count. */	CRYPTO_w_lock(CRYPTO_LOCK_X509);	s->session->peer=s->session->cert->key->x509;	CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509);	CRYPTO_w_unlock(CRYPTO_LOCK_X509);	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);	}