kerberos: Fix numerous segfaults when using weak crypto

Weak crypto is provided by the openssl legacy provider which is
not load by default. Load the legacy providers as needed.

When the legacy provider is loaded into the default context the default
provider will no longer be automatically loaded. Without the default
provider the various kerberos applicaions and functions will abort().

PR:			272835
MFC after:		3 days
Differential Revision:	https://reviews.freebsd.org/D43009
Tested by:		netchild, Joerg Pulz <Joerg.Pulz@frm2.tum.de>
This commit is contained in:
Cy Schubert
2023-12-06 07:30:05 -08:00
parent ed1a88a311
commit cb350ba7bf
13 changed files with 81 additions and 8 deletions
+4 -3
View File
@@ -2635,9 +2635,10 @@ ${_bt}-usr.bin/grep: ${_bt}-lib/libbz2
_other_bootstrap_tools+=lib/libz
${_bt}-lib/libdwarf: ${_bt}-lib/libz
# libroken depends on libcrypt
# libroken depends on libcrypt and libcrypto
_other_bootstrap_tools+=lib/libcrypt
${_bt}-lib/libroken: ${_bt}-lib/libcrypt
_other_bootstrap_tools+=secure/lib/libcrypto
${_bt}-lib/libroken: ${_bt}-lib/libcrypt ${_bt}-lib/libcrypto
.else
# All tools in _basic_bootstrap_tools have the same name as the subdirectory
# so we can use :T to get the name of the symlinks that we need to create.
@@ -3283,7 +3284,7 @@ kerberos5/lib/libkrb5__L: kerberos5/lib/libasn1__L lib/libcom_err__L \
lib/libcrypt__L secure/lib/libcrypto__L kerberos5/lib/libhx509__L \
kerberos5/lib/libroken__L kerberos5/lib/libwind__L \
kerberos5/lib/libheimbase__L kerberos5/lib/libheimipcc__L
kerberos5/lib/libroken__L: lib/libcrypt__L
kerberos5/lib/libroken__L: lib/libcrypt__L secure/lib/libcrypto__L
kerberos5/lib/libwind__L: kerberos5/lib/libroken__L lib/libcom_err__L
kerberos5/lib/libheimbase__L: lib/libthr__L
kerberos5/lib/libheimipcc__L: kerberos5/lib/libroken__L kerberos5/lib/libheimbase__L lib/libthr__L
+4
View File
@@ -169,6 +169,10 @@ kadm5_s_create_principal(void *server_handle,
ent.entry.keys.len = 0;
ent.entry.keys.val = NULL;
ret = fbsd_ossl_provider_load();
if (ret)
goto out;
ret = _kadm5_set_keys(context, &ent.entry, password);
if (ret)
goto out;
+1
View File
@@ -79,5 +79,6 @@
#include <der.h>
#include <parse_units.h>
#include "private.h"
#include "fbsd_ossl_provider.h"
#endif /* __KADM5_LOCL_H__ */
+4
View File
@@ -392,6 +392,10 @@ krb5_init_context(krb5_context *context)
}
HEIMDAL_MUTEX_init(p->mutex);
ret = fbsd_ossl_provider_load();
if(ret)
goto out;
p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;
ret = krb5_get_default_config_files(&files);
+3
View File
@@ -2054,6 +2054,9 @@ krb5_crypto_init(krb5_context context,
*crypto = NULL;
return ret;
}
ret = fbsd_ossl_provider_load();
if (ret)
return ret;
(*crypto)->key.schedule = NULL;
(*crypto)->num_key_usage = 0;
(*crypto)->key_usage = NULL;
+5
View File
@@ -43,6 +43,8 @@ krb5_salttype_to_string (krb5_context context,
struct _krb5_encryption_type *e;
struct salt_type *st;
(void) fbsd_ossl_provider_load();
e = _krb5_find_enctype (etype);
if (e == NULL) {
krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
@@ -75,6 +77,8 @@ krb5_string_to_salttype (krb5_context context,
struct _krb5_encryption_type *e;
struct salt_type *st;
(void) fbsd_ossl_provider_load();
e = _krb5_find_enctype (etype);
if (e == NULL) {
krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
@@ -196,6 +200,7 @@ krb5_string_to_key_data_salt_opaque (krb5_context context,
enctype);
return KRB5_PROG_ETYPE_NOSUPP;
}
(void) fbsd_ossl_provider_load();
for(st = et->keytype->string_to_key; st && st->type; st++)
if(st->type == salt.salttype)
return (*st->string_to_key)(context, enctype, password,
@@ -13,6 +13,7 @@ HEIMDAL_ROKEN_1.0 {
ct_memcmp;
err;
errx;
fbsd_ossl_provider_load;
free_getarg_strings;
get_default_username;
get_window_size;
+4
View File
@@ -17,5 +17,9 @@
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/ecdh.h>
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
#include <openssl/provider.h>
#include "fbsd_ossl_provider.h"
#endif
#endif /* __crypto_headers_h__ */
+4
View File
@@ -0,0 +1,4 @@
#ifndef __fbsd_ossl_provider_h
#define __fbsd_ossl_provider_h
int fbsd_ossl_provider_load(void);
#endif
+8 -3
View File
@@ -2,7 +2,7 @@
PACKAGE= kerberos-lib
LIB= roken
LIBADD= crypt
LIBADD= crypt crypto
VERSION_MAP= ${KRB5DIR}/lib/roken/version-script.map
INCS= roken.h \
roken-common.h \
@@ -74,15 +74,20 @@ SRCS= base64.c \
vis.c \
warnerr.c \
write_pid.c \
xfree.c
xfree.c \
fbsd_ossl_provider_load.c
CFLAGS+=-I${KRB5DIR}/lib/roken -I.
CFLAGS+=-I${KRB5DIR}/lib/roken \
-I${SRCTOP}/kerberos5/include \
-I${KRB5DIR}/lib/krb5 \
-I${SRCTOP}/crypto/openssl/include -I.
CLEANFILES= roken.h
roken.h:
${MAKE_ROKEN} > ${.TARGET}
.include <bsd.lib.mk>
.PATH: ${KRB5DIR}/lib/roken
@@ -0,0 +1,41 @@
#include <errno.h>
#include <krb5_locl.h>
static void fbsd_ossl_provider_unload(void);
static OSSL_PROVIDER *legacy;
static OSSL_PROVIDER *deflt;
static int providers_loaded = 0;
int
fbsd_ossl_provider_load(void)
{
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
if (providers_loaded == 0) {
if ((legacy = OSSL_PROVIDER_load(NULL, "legacy")) == NULL)
return (EINVAL);
if ((deflt = OSSL_PROVIDER_load(NULL, "default")) == NULL) {
OSSL_PROVIDER_unload(legacy);
return (EINVAL);
}
if (atexit(fbsd_ossl_provider_unload)) {
fbsd_ossl_provider_unload();
return (errno);
}
providers_loaded = 1;
}
#endif
return (0);
}
static void
fbsd_ossl_provider_unload(void)
{
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
if (providers_loaded == 1) {
OSSL_PROVIDER_unload(legacy);
OSSL_PROVIDER_unload(deflt);
providers_loaded = 0;
}
#endif
}
+1 -1
View File
@@ -11,7 +11,7 @@ SRCS= config.c \
CFLAGS+=-I${KRB5DIR}/lib/krb5 -I${KRB5DIR}/lib/asn1 -I${KRB5DIR}/lib/roken \
-I${KRB5DIR}/kdc -I${SRCTOP}/contrib/com_err ${LDAPCFLAGS}
LIBADD= kdc hdb krb5 roken crypt vers
LIBADD= kdc hdb krb5 roken crypt vers crypto
LDFLAGS=${LDAPLDFLAGS}
.include <bsd.prog.mk>
+1 -1
View File
@@ -367,7 +367,7 @@ _DP_pam+= ssh
.if ${MK_NIS} != "no"
_DP_pam+= ypclnt
.endif
_DP_roken= crypt
_DP_roken= crypt crypto
_DP_kadm5clnt= com_err krb5 roken
_DP_kadm5srv= com_err hdb krb5 roken
_DP_heimntlm= crypto com_err krb5 roken