More Kerberos SSL changes from Jeffrey Altman <jaltman@columbia.edu>
authorRichard Levitte <levitte@openssl.org>
Tue, 31 Jul 2001 07:21:06 +0000 (07:21 +0000)
committerRichard Levitte <levitte@openssl.org>
Tue, 31 Jul 2001 07:21:06 +0000 (07:21 +0000)
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.

ssl/kssl.c
ssl/s3_clnt.c
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl_asn1.c
ssl/ssl_sess.c
ssl/ssl_txt.c

index d9e1160..cd9144f 100644 (file)
@@ -760,19 +760,14 @@ kssl_map_enc(krb5_enctype enctype)
         {
        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 @@ krb5_error_code  kssl_check_authent(
                }
 
        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 */
 
index 3d6e5f9..f93f277 100644 (file)
@@ -1461,6 +1461,8 @@ static int ssl3_send_client_key_exchange(SSL *s)
                         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);
index 112c823..53091d3 100644 (file)
@@ -1493,7 +1493,7 @@ static int ssl3_get_client_key_exchange(SSL *s)
                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 @@ static int ssl3_get_client_key_exchange(SSL *s)
 #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 @@ static int ssl3_get_client_key_exchange(SSL *s)
                         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);
index 61424eb..8d9c988 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -106,6 +106,7 @@ extern "C" {
 #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 @@ typedef struct ssl_session_st
        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 */
index fa6456e..d0487e5 100644 (file)
@@ -72,6 +72,9 @@ typedef struct ssl_session_asn1_st
        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 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
        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 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
                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 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
        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 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, unsigned char **pp,
        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)
index 5bfc8cc..7430d84 100644 (file)
@@ -558,6 +558,17 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
                                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)
index 8b37a37..77e881d 100644 (file)
@@ -139,6 +139,18 @@ int SSL_SESSION_print(BIO *bp, SSL_SESSION *x)
                        {
                        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;