More Kerberos SSL changes from Jeffrey Altman <jaltman@columbia.edu>
His comments are:
First, it corrects a problem introduced in the last patch where the
kssl_map_enc() would intentionally return NULL for valid ENCTYPE
values. This was done to prevent verification of the kerberos 5
authenticator from being performed when Derived Key ciphers were
in use. Unfortunately, the authenticator verification routine was
not the only place that function was used. And it caused core dumps.
Second, it attempt to add to SSL_SESSION the Kerberos 5 Client
Principal Name.
diff --git a/ssl/kssl.c b/ssl/kssl.c
index d9e1160..cd9144f 100644
--- a/ssl/kssl.c
+++ b/ssl/kssl.c
@@ -760,19 +760,14 @@
{
switch (enctype)
{
-#if ! defined(KRB5_MIT_OLD11)
- /* cannot handle derived keys */
- case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */
case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */
- return (EVP_CIPHER *) NULL;
- break;
-#endif
case ENCTYPE_DES_CBC_CRC:
case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_MD5:
case ENCTYPE_DES_CBC_RAW:
return (EVP_CIPHER *) EVP_des_cbc();
break;
+ case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */
case ENCTYPE_DES3_CBC_SHA:
case ENCTYPE_DES3_CBC_RAW:
return (EVP_CIPHER *) EVP_des_ede3_cbc();
@@ -1979,6 +1974,15 @@
}
enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */
+#if !defined(KRB5_MIT_OLD11)
+ switch ( enctype ) {
+ case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */
+ case ENCTYPE_DES3_CBC_SHA:
+ case ENCTYPE_DES3_CBC_RAW:
+ krb5rc = 0; /* Skip, can't handle derived keys */
+ goto err;
+ }
+#endif
enc = kssl_map_enc(enctype);
memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 3d6e5f9..f93f277 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1461,6 +1461,8 @@
krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
&kssl_err);
enc = kssl_map_enc(kssl_ctx->enctype);
+ if (enc == NULL)
+ goto err;
#ifdef KSSL_DEBUG
{
printf("kssl_cget_tkt rtn %d\n", krb5rc);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 112c823..53091d3 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1493,7 +1493,7 @@
enc_pms.data = p;
p+=enc_pms.length;
- if (n != enc_ticket.length + authenticator.length +
+ if ((unsigned long)n != enc_ticket.length + authenticator.length +
enc_pms.length + 6)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
@@ -1543,6 +1543,9 @@
#endif /* KSSL_DEBUG */
enc = kssl_map_enc(kssl_ctx->enctype);
+ if (enc == NULL)
+ goto err;
+
memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */
if (!EVP_DecryptInit(&ciph_ctx,enc,kssl_ctx->key,iv))
@@ -1583,6 +1586,17 @@
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key, pms, outl);
+ if (kssl_ctx->client_princ)
+ {
+ int len = strlen(kssl_ctx->client_princ);
+ if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH )
+ {
+ s->session->krb5_client_princ_len = len;
+ memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
+ }
+ }
+
+
/* Was doing kssl_ctx_free() here,
** but it caused problems for apache.
** kssl_ctx = kssl_ctx_free(kssl_ctx);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 61424eb..8d9c988 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -106,6 +106,7 @@
#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5
#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+#define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256
#define SSL_MAX_SSL_SESSION_ID_LENGTH 32
#define SSL_MAX_SID_CTX_LENGTH 32
@@ -283,6 +284,11 @@
unsigned int sid_ctx_length;
unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+#ifndef OPENSSL_NO_KRB5
+ unsigned int krb5_client_princ_len;
+ unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
+#endif /* OPENSSL_NO_KRB5 */
+
int not_resumable;
/* The cert is the certificate used to establish this connection */
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index fa6456e..d0487e5 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -72,6 +72,9 @@
ASN1_OCTET_STRING session_id;
ASN1_OCTET_STRING session_id_context;
ASN1_OCTET_STRING key_arg;
+#ifndef OPENSSL_NO_KRB5
+ ASN1_OCTET_STRING krb5_princ;
+#endif /* OPENSSL_NO_KRB5 */
ASN1_INTEGER time;
ASN1_INTEGER timeout;
ASN1_INTEGER verify_result;
@@ -142,6 +145,12 @@
a.key_arg.type=V_ASN1_OCTET_STRING;
a.key_arg.data=in->key_arg;
+#ifndef OPENSSL_NO_KRB5
+ a.krb5_princ.length=in->krb5_client_princ_len;
+ a.krb5_princ.type=V_ASN1_OCTET_STRING;
+ a.krb5_princ.data=in->krb5_client_princ;
+#endif /* OPENSSL_NO_KRB5 */
+
if (in->time != 0L)
{
a.time.length=LSIZE2;
@@ -166,11 +175,15 @@
ASN1_INTEGER_set(&a.verify_result,in->verify_result);
}
+
M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING);
M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING);
M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING);
+#ifndef OPENSSL_NO_KRB5
+ M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
+#endif /* OPENSSL_NO_KRB5 */
if (in->key_arg_length > 0)
M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING);
if (in->time != 0L)
@@ -190,6 +203,9 @@
M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING);
M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING);
M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING);
+#ifndef OPENSSL_NO_KRB5
+ M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
+#endif /* OPENSSL_NO_KRB5 */
if (in->key_arg_length > 0)
M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0);
if (in->time != 0L)
@@ -293,6 +309,17 @@
memcpy(ret->key_arg,os.data,ret->key_arg_length);
if (os.data != NULL) OPENSSL_free(os.data);
+#ifndef OPENSSL_NO_KRB5
+ os.length=0;
+ M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING);
+ if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
+ ret->krb5_client_princ_len=0;
+ else
+ ret->krb5_client_princ_len=os.length;
+ memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len);
+ if (os.data != NULL) OPENSSL_free(os.data);
+#endif /* OPENSSL_NO_KRB5 */
+
ai.length=0;
M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1);
if (ai.data != NULL)
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 5bfc8cc..7430d84 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -558,6 +558,17 @@
session->timeout=s->ctx->session_timeout;
}
+#ifndef OPENSSL_NO_KRB5
+ if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
+ session->krb5_client_princ_len > 0)
+ {
+ s->kssl_ctx->client_princ = (char *)malloc(session->krb5_client_princ_len + 1);
+ memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
+ session->krb5_client_princ_len);
+ s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '/0';
+ }
+#endif /* OPENSSL_NO_KRB5 */
+
/* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
if (s->session != NULL)
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index 8b37a37..77e881d 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -139,6 +139,18 @@
{
if (BIO_printf(bp,"%02X",x->key_arg[i]) <= 0) goto err;
}
+#ifndef OPENSSL_NO_KRB5
+ if (BIO_puts(bp,"/n Krb5 Principal: ") <= 0) goto err;
+ if (x->krb5_client_princ_len == 0)
+ {
+ if (BIO_puts(bp,"None") <= 0) goto err;
+ }
+ else
+ for (i=0; i<x->krb5_client_princ_len; i++)
+ {
+ if (BIO_printf(bp,"%02X",x->key_arg[i]) <= 0) goto err;
+ }
+#endif /* OPENSSL_NO_KRB5 */
if (x->compress_meth != 0)
{
SSL_COMP *comp;