Remove Kerberos support from libssl

Remove RFC2712 Kerberos support from libssl. This code and the associated
standard is no longer considered fit-for-purpose.

Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
Matt Caswell
2015-05-12 10:27:53 +01:00
parent 5561419a60
commit 55a9a16f1c
31 changed files with 839 additions and 4406 deletions

View File

@@ -151,7 +151,6 @@
#include <stdio.h>
#include "ssl_locl.h"
#include "kssl_lcl.h"
#include "../crypto/constant_time_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
@@ -163,9 +162,6 @@
# include <openssl/dh.h>
#endif
#include <openssl/bn.h>
#ifndef OPENSSL_NO_KRB5
# include <openssl/krb5_asn.h>
#endif
#include <openssl/md5.h>
#ifndef OPENSSL_NO_SSL3_METHOD
@@ -421,11 +417,10 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SW_CERT_A:
case SSL3_ST_SW_CERT_B:
/* Check if it is anon DH or anon ECDH, */
/* normal PSK or KRB5 or SRP */
/* normal PSK or SRP */
if (!
(s->s3->tmp.
new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 |
SSL_aSRP))
new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
ret = ssl3_send_server_certificate(s);
if (ret <= 0)
@@ -516,16 +511,12 @@ int ssl3_accept(SSL *s)
* RFC 2246):
*/
((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
/*
* ... except when the application insists on
* verification (against the specs, but s3_clnt.c accepts
* this for SSL 3)
*/
!(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
/*
* never request cert in Kerberos ciphersuites
* ... except when the application insists on
* verification (against the specs, but s3_clnt.c accepts
* this for SSL 3)
*/
(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
!(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
/* don't request certificate for SRP auth */
(s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
/*
@@ -2123,9 +2114,6 @@ int ssl3_get_client_key_exchange(SSL *s)
BIGNUM *pub = NULL;
DH *dh_srvr, *dh_clnt = NULL;
#endif
#ifndef OPENSSL_NO_KRB5
KSSL_ERR kssl_err;
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_EC
EC_KEY *srvr_ecdh = NULL;
@@ -2391,189 +2379,6 @@ int ssl3_get_client_key_exchange(SSL *s)
return 2;
} else
#endif
#ifndef OPENSSL_NO_KRB5
if (alg_k & SSL_kKRB5) {
krb5_error_code krb5rc;
krb5_data enc_ticket;
krb5_data authenticator;
krb5_data enc_pms;
KSSL_CTX *kssl_ctx = s->kssl_ctx;
EVP_CIPHER_CTX ciph_ctx;
const EVP_CIPHER *enc = NULL;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH];
int padl, outl;
krb5_timestamp authtime = 0;
krb5_ticket_times ttimes;
EVP_CIPHER_CTX_init(&ciph_ctx);
if (!kssl_ctx)
kssl_ctx = kssl_ctx_new();
n2s(p, i);
enc_ticket.length = i;
if (n < (long)(enc_ticket.length + 6)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
enc_ticket.data = (char *)p;
p += enc_ticket.length;
n2s(p, i);
authenticator.length = i;
if (n < (long)(enc_ticket.length + authenticator.length + 6)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
authenticator.data = (char *)p;
p += authenticator.length;
n2s(p, i);
enc_pms.length = i;
enc_pms.data = (char *)p;
p += enc_pms.length;
/*
* Note that the length is checked again below, ** after decryption
*/
if (enc_pms.length > sizeof pms) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
if (n != (long)(enc_ticket.length + authenticator.length +
enc_pms.length + 6)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
&kssl_err)) != 0) {
# ifdef KSSL_DEBUG
fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n",
krb5rc, kssl_err.reason);
if (kssl_err.text)
fprintf(stderr, "kssl_err text= %s\n", kssl_err.text);
# endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason);
goto err;
}
/*
* Note: no authenticator is not considered an error, ** but will
* return authtime == 0.
*/
if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
&authtime, &kssl_err)) != 0) {
# ifdef KSSL_DEBUG
fprintf(stderr, "kssl_check_authent rtn %d [%d]\n",
krb5rc, kssl_err.reason);
if (kssl_err.text)
fprintf(stderr, "kssl_err text= %s\n", kssl_err.text);
# endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason);
goto err;
}
if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
goto err;
}
# ifdef KSSL_DEBUG
kssl_ctx_show(kssl_ctx);
# endif /* KSSL_DEBUG */
enc = kssl_map_enc(kssl_ctx->enctype);
if (enc == NULL)
goto err;
memset(iv, 0, sizeof(iv)); /* per RFC 1510 */
if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto err;
}
if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl,
(unsigned char *)enc_pms.data, enc_pms.length))
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto err;
}
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto err;
}
outl += padl;
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
if (!((pms[0] == (s->client_version >> 8))
&& (pms[1] == (s->client_version & 0xff)))) {
/*
* The premaster secret must contain the same version number as
* the ClientHello to detect version rollback attacks (strangely,
* the protocol does not offer such protection for DH
* ciphersuites). However, buggy clients exist that send random
* bytes instead of the protocol version. If
* SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients.
* (Perhaps we should have a separate BUG value for the Kerberos
* cipher)
*/
if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_AD_DECODE_ERROR);
goto err;
}
}
EVP_CIPHER_CTX_cleanup(&ciph_ctx);
s->session->master_key_length =
s->method->ssl3_enc->generate_master_secret(s,
s->
session->master_key,
pms, outl);
if (s->session->master_key_length < 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto f_err;
}
if (kssl_ctx->client_princ) {
size_t 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);
* if (s->kssl_ctx) s->kssl_ctx = NULL;
*/
} else
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_EC
if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe)) {
@@ -3303,14 +3108,9 @@ int ssl3_send_server_certificate(SSL *s)
if (s->state == SSL3_ST_SW_CERT_A) {
cpk = ssl_get_server_send_pkey(s);
if (cpk == NULL) {
/* VRS: allow null cert if auth == KRB5 */
if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
ERR_R_INTERNAL_ERROR);
s->state = SSL_ST_ERR;
return (0);
}
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
s->state = SSL_ST_ERR;
return (0);
}
if (!ssl3_output_cert_chain(s, cpk)) {