From 882e891284c81c7a49b2bce28f44df3e8d6f7ffc Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 31 Jul 2001 07:21:06 +0000 Subject: [PATCH] More Kerberos SSL changes from Jeffrey Altman 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 | 16 ++++++++++------ ssl/s3_clnt.c | 2 ++ ssl/s3_srvr.c | 16 +++++++++++++++- ssl/ssl.h | 6 ++++++ ssl/ssl_asn1.c | 27 +++++++++++++++++++++++++++ ssl/ssl_sess.c | 11 +++++++++++ ssl/ssl_txt.c | 12 ++++++++++++ 7 files changed, 83 insertions(+), 7 deletions(-) diff --git a/ssl/kssl.c b/ssl/kssl.c index d9e1160550..cd9144f2be 100644 --- a/ssl/kssl.c +++ b/ssl/kssl.c @@ -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 */ diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 3d6e5f9f96..f93f2772d6 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -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); diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 112c823a0f..53091d3577 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -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); diff --git a/ssl/ssl.h b/ssl/ssl.h index 61424ebab5..8d9c988fae 100644 --- 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 */ diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index fa6456e4f5..d0487e5af5 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -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) diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 5bfc8ccf6a..7430d84d75 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -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) diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c index 8b37a37e40..77e881d061 100644 --- a/ssl/ssl_txt.c +++ b/ssl/ssl_txt.c @@ -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; ikrb5_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; -- 2.25.1