#include <openssl/x509.h>
#include "ssl_locl.h"
+#ifndef OPENSSL_NO_KRB5
+#include "kssl.h"
+#endif /* OPENSSL_NO_KRB5 */
+
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);
/* clear this, it may get reset by
* send_server_key_exchange */
- if (s->options & SSL_OP_EPHEMERAL_RSA)
+ if ((s->options & SSL_OP_EPHEMERAL_RSA)
+#ifndef OPENSSL_NO_KRB5
+ && !(l & SSL_KRB5)
+#endif /* OPENSSL_NO_KRB5 */
+ )
s->s3->tmp.use_rsa_tmp=1;
else
s->s3->tmp.use_rsa_tmp=0;
* which will now be aborted. (A full SSL_clear would be too much.)
* I hope that tmp.dh is the only thing that may need to be cleared
* when a handshake is not completed ... */
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
if (s->s3->tmp.dh != NULL)
{
DH_free(s->s3->tmp.dh);
}
}
- /* Given s->session->ciphers and ssl_get_ciphers_by_id(s), we must
+ /* Given s->session->ciphers and SSL_get_ciphers, we must
* pick a cipher */
if (!s->hit)
}
ciphers=NULL;
c=ssl3_choose_cipher(s,s->session->ciphers,
- ssl_get_ciphers_by_id(s));
+ SSL_get_ciphers(s));
if (c == NULL)
{
static int ssl3_send_server_key_exchange(SSL *s)
{
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
unsigned char *q;
int j,num;
RSA *rsa;
unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
unsigned int u;
#endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
DH *dh=NULL,*dhp;
#endif
EVP_PKEY *pkey;
r[0]=r[1]=r[2]=r[3]=NULL;
n=0;
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
if (type & SSL_kRSA)
{
rsa=cert->rsa_tmp;
}
else
#endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
if (type & SSL_kEDH)
{
dhp=cert->dh_tmp;
{
/* n is the length of the params, they start at &(d[4])
* and p points to the space at the end. */
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
{
q=md_buf;
}
else
#endif
-#if !defined(NO_DSA)
+#if !defined(OPENSSL_NO_DSA)
if (pkey->type == EVP_PKEY_DSA)
{
/* lets do DSS */
long n;
unsigned long l;
unsigned char *p;
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
EVP_PKEY *pkey=NULL;
#endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
BIGNUM *pub=NULL;
DH *dh_srvr;
#endif
+#ifndef OPENSSL_NO_KRB5
+ KSSL_ERR kssl_err;
+#endif /* OPENSSL_NO_KRB5 */
n=ssl3_get_message(s,
SSL3_ST_SR_KEY_EXCH_A,
l=s->s3->tmp.new_cipher->algorithms;
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
if (l & SSL_kRSA)
{
/* FIX THIS UP EAY EAY EAY EAY */
}
else
#endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
{
n2s(p,i);
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,p,i);
+ memset(p,0,i);
}
else
#endif
+#ifndef OPENSSL_NO_KRB5
+ if (l & SSL_kKRB5)
+ {
+ krb5_error_code krb5rc;
+ KSSL_CTX *kssl_ctx = s->kssl_ctx;
+
+ if (!kssl_ctx) kssl_ctx = kssl_ctx_new();
+ if ((krb5rc = kssl_sget_tkt(kssl_ctx,
+ s->init_buf->data, s->init_buf->length,
+ &kssl_err)) != 0)
+ {
+#ifdef KSSL_DEBUG
+ printf("kssl_sget_tkt rtn %d [%d]\n",
+ krb5rc, kssl_err.reason);
+ if (kssl_err.text)
+ printf("kssl_err text= %s\n", kssl_err.text);
+#endif /* KSSL_DEBUG */
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ kssl_err.reason);
+ goto err;
+ }
+
+#ifdef KSSL_DEBUG
+ kssl_ctx_show(kssl_ctx);
+#endif /* KSSL_DEBUG */
+
+ /* 19991013 VRS - 3DES is kind of bogus here,
+ ** at least until Kerberos supports 3DES. The only
+ ** real secret is the 8-byte Kerberos session key;
+ ** the other key material (client_random, server_random)
+ ** could be sniffed. Nonces may help against replays though.
+ **
+ ** Alternate code for Kerberos Purists:
+ **
+ ** memcpy(s->session->master_key, kssl_ctx->key, kssl_ctx->length);
+ ** s->session->master_key_length = kssl_ctx->length;
+ */
+ s->session->master_key_length=
+ s->method->ssl3_enc->generate_master_secret(s,
+ s->session->master_key, kssl_ctx->key, kssl_ctx->length);
+ /* Was doing kssl_ctx_free() here, but it caused problems for apache.
+ ** kssl_ctx = kssl_ctx_free(kssl_ctx);
+ ** if (s->kssl_ctx) s->kssl_ctx = NULL;
+ */
+ }
+ else
+#endif /* OPENSSL_NO_KRB5 */
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNKNOWN_CIPHER_TYPE);
return(1);
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
-#if !defined(NO_DH) || !defined(NO_RSA)
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA)
err:
#endif
return(-1);
goto f_err;
}
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
{
i=RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
}
else
#endif
-#ifndef NO_DSA
+#ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA)
{
j=DSA_verify(pkey->save_type,
SSL3_ST_SR_CERT_A,
SSL3_ST_SR_CERT_B,
-1,
-#if defined(MSDOS) && !defined(WIN32)
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
1024*30, /* 30k max cert list :-) */
#else
1024*100, /* 100k max cert list :-) */
if (s->state == SSL3_ST_SW_CERT_A)
{
x=ssl_get_server_send_cert(s);
- if (x == NULL)
+ if (x == NULL &&
+ /* VRS: allow null cert if auth == KRB5 */
+ (s->s3->tmp.new_cipher->algorithms
+ & (SSL_MKEY_MASK|SSL_AUTH_MASK))
+ != (SSL_aKRB5|SSL_kKRB5))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,SSL_R_INTERNAL_ERROR);
return(0);