s2_clnt.c 30.1 KB
Newer Older
		/* new session-id */
		/* Make sure we were not trying to re-use an old SSL_SESSION
		 * or bad things can happen */
		/* ZZZZZZZZZZZZZ */
		s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
		memcpy(s->session->session_id,p+1,SSL2_SSL_SESSION_ID_LENGTH);
		}
	else
		{
		if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG))
			{
			if ((s->session->session_id_length > sizeof s->session->session_id)
			    || (0 != memcmp(buf + 1, s->session->session_id,
			                    (unsigned int)s->session->session_id_length)))
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_SSL_SESSION_ID_IS_DIFFERENT);
				return(-1);
				}
			}
		}
	s->state = SSL_ST_OK;
	return(1);
	}

/* loads in the certificate from the server */
int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
	{
	STACK_OF(X509) *sk=NULL;
	EVP_PKEY *pkey=NULL;
	SESS_CERT *sc=NULL;
	int i;
	X509 *x509=NULL;
	int ret=0;
	
	x509=d2i_X509(NULL,&data,(long)len);
	if (x509 == NULL)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB);
		goto err;
		}

	if ((sk=sk_X509_new_null()) == NULL || !sk_X509_push(sk,x509))
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	i=ssl_verify_cert_chain(s,sk);
		
	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
		goto err;
		}
	ERR_clear_error(); /* but we keep s->verify_result */
	s->session->verify_result = s->verify_result;

	/* server's cert for this session */
	sc=ssl_sess_cert_new();
	if (sc == NULL)
		{
		ret= -1;
		goto err;
		}
	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
	s->session->sess_cert=sc;

	sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
	sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);

	pkey=X509_get_pubkey(x509);
	x509=NULL;
	if (pkey == NULL)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
		goto err;
		}
	if (pkey->type != EVP_PKEY_RSA)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA);
		goto err;
		}

	if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
		goto err;
	ret=1;
err:
	sk_X509_free(sk);
	X509_free(x509);
	EVP_PKEY_free(pkey);
	return(ret);
	}

static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
	     unsigned char *to, int padding)
	{
	EVP_PKEY *pkey=NULL;
	int i= -1;

	if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
		((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
		{
		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
		return(-1);
		}
	if (pkey->type != EVP_PKEY_RSA)
		{
		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
		goto end;
		}

	/* we have the public key */
	i=RSA_public_encrypt(len,from,to,pkey->pkey.rsa,padding);
	if (i < 0)
		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,ERR_R_RSA_LIB);
end:
	EVP_PKEY_free(pkey);
	return(i);
	}
#else /* !OPENSSL_NO_SSL2 */

# if PEDANTIC
static void *dummy=&dummy;
# endif

#endif