CERT *c;
SESS_CERT *sc;
static int ssl3_get_server_certificate(SSL *s)	{	int al,i,ok,ret= -1;	unsigned long n,nc,llen,l;	X509 *x=NULL;	unsigned char *p,*d,*q;	STACK_OF(X509) *sk=NULL;	CERT *c;	EVP_PKEY *pkey=NULL;	n=ssl3_get_message(s,		SSL3_ST_CR_CERT_A,		SSL3_ST_CR_CERT_B,		-1,#if defined(MSDOS) && !defined(WIN32)		1024*30, /* 30k max cert list :-) */#else		1024*100, /* 100k max cert list :-) */#endif		&ok);	if (!ok) return((int)n);	if (s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE)		{		s->s3->tmp.reuse_message=1;		return(1);		}	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE)		{		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE);		goto f_err;		}	d=p=(unsigned char *)s->init_buf->data;	if ((sk=sk_X509_new_null()) == NULL)		{		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);		goto err;		}	n2l3(p,llen);	if (llen+3 != n)		{		al=SSL_AD_DECODE_ERROR;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_LENGTH_MISMATCH);		goto f_err;		}	for (nc=0; nc<llen; )		{		n2l3(p,l);		if ((l+nc+3) > llen)			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);			goto f_err;			}		q=p;		x=d2i_X509(NULL,&q,l);		if (x == NULL)			{			al=SSL_AD_BAD_CERTIFICATE;			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_ASN1_LIB);			goto f_err;			}		if (q != (p+l))			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH);			goto f_err;			}		if (!sk_X509_push(sk,x))			{			SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_MALLOC_FAILURE);			goto err;			}		x=NULL;		nc+=l+3;		p=q;		}	i=ssl_verify_cert_chain(s,sk);        if ((s->verify_mode != SSL_VERIFY_NONE) && (!i))		{		al=ssl_verify_alarm_type(s->verify_result);		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);		goto f_err; 		}	c=ssl_cert_new();	if (c == NULL) goto err;	if (s->session->sess_cert) ssl_cert_free(s->session->sess_cert);	s->session->sess_cert=c;	c->cert_chain=sk;	x=sk_X509_value(sk,0);	sk=NULL;	pkey=X509_get_pubkey(x);	if ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))		{		x=NULL;		al=SSL3_AL_FATAL;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);		goto f_err;		}	i=ssl_cert_type(x,pkey);	if (i < 0)		{		x=NULL;		al=SSL3_AL_FATAL;		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNKNOWN_CERTIFICATE_TYPE);		goto f_err;		}	c->cert_type=i;	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);	if (c->pkeys[i].x509 != NULL)		X509_free(c->pkeys[i].x509);	c->pkeys[i].x509=x;	c->key= &(c->pkeys[i]);	if ((s->session != NULL) && (s->session->peer != NULL)) 		X509_free(s->session->peer);	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);	s->session->peer=x;	x=NULL;	ret=1;	if (0)		{f_err:		ssl3_send_alert(s,SSL3_AL_FATAL,al);		}err:	EVP_PKEY_free(pkey);	X509_free(x);	sk_X509_pop_free(sk,X509_free);	return(ret);	}