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 d9e1160550c7919dd778b7060465106a6b689841..cd9144f2be041aeecdde61edb68dfe60894ec553 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 3d6e5f9f9603d9752299e795ccee135e2aa169ac..f93f2772d63c93896c39ec10d985280f0b71ca4a 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 112c823a0fe8eef3fb9b6bc649e8f845d468e341..53091d35770ec3cb5edab8f8eea08575e26db864 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 61424ebab5f6e32e7b1e8ffd9cd3c5a820d3b558..8d9c988fae9eefda86884b5883c9c9c25eec9fdd 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 fa6456e4f5e8915f4f4d616845e38adac2ba4052..d0487e5af5c5942e80062ab7fe06b4f9e8f0a698 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 5bfc8ccf6a94d4dd00e8ee470b8576d1b8d9584b..7430d84d751d94aa8302d90a6e5e6a4501a404af 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 8b37a37e404ac8c63a7e9bd5ab1d694b4f4fd804..77e881d06120c07f964e7360f43c564000cfab2c 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;